Merge "Remove ro.url.legal* props from proto"
diff --git a/Android.bp b/Android.bp
index 0d2caff..5d125f9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -273,7 +273,7 @@
"core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl",
"core/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl",
"core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl",
- "core/java/android/service/gatekeeper/IGateKeeperService.aidl",
+ ":gatekeeper_aidl",
"core/java/android/service/notification/INotificationListener.aidl",
"core/java/android/service/notification/IStatusBarNotificationHolder.aidl",
"core/java/android/service/notification/IConditionListener.aidl",
@@ -663,6 +663,7 @@
"frameworks/av/camera/aidl",
"frameworks/av/media/libaudioclient/aidl",
"frameworks/native/aidl/gui",
+ "system/core/gatekeeperd/binder",
"system/core/storaged/binder",
"system/vold/binder",
"system/gsid/aidl",
@@ -687,6 +688,7 @@
static_libs: [
"apex_aidl_interface-java",
+ "suspend_control_aidl_interface-java",
"framework-protos",
"game-driver-protos",
"android.hidl.base-V1.0-java",
diff --git a/api/test-current.txt b/api/test-current.txt
index 075963e..144e5f5 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1532,6 +1532,15 @@
method public void setVoiceRoamingType(int);
}
+ public final class SmsManager {
+ method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int checkSmsShortCodeDestination(String, String);
+ field public static final int SMS_CATEGORY_FREE_SHORT_CODE = 1; // 0x1
+ field public static final int SMS_CATEGORY_NOT_SHORT_CODE = 0; // 0x0
+ field public static final int SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3; // 0x3
+ field public static final int SMS_CATEGORY_PREMIUM_SHORT_CODE = 4; // 0x4
+ field public static final int SMS_CATEGORY_STANDARD_SHORT_CODE = 2; // 0x2
+ }
+
public class TelephonyManager {
method public int getCarrierIdListVersion();
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getLine1AlphaTag();
diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl
index e5f3d26..9994f9f 100644
--- a/core/java/android/net/INetworkStatsService.aidl
+++ b/core/java/android/net/INetworkStatsService.aidl
@@ -67,7 +67,8 @@
void forceUpdateIfaces(
in Network[] defaultNetworks,
in NetworkState[] networkStates,
- in String activeIface);
+ in String activeIface,
+ in VpnInfo[] vpnInfos);
/** Force update of statistics. */
@UnsupportedAppUsage
void forceUpdate();
diff --git a/core/java/android/net/util/SocketUtils.java b/core/java/android/net/util/SocketUtils.java
index d9bcb3c..489a292 100644
--- a/core/java/android/net/util/SocketUtils.java
+++ b/core/java/android/net/util/SocketUtils.java
@@ -70,7 +70,7 @@
@NonNull
public static SocketAddress makePacketSocketAddress(int protocol, int ifIndex) {
return new PacketSocketAddress(
- (short) protocol /* sll_protocol */,
+ protocol /* sll_protocol */,
ifIndex /* sll_ifindex */,
null /* sll_addr */);
}
@@ -81,7 +81,7 @@
@NonNull
public static SocketAddress makePacketSocketAddress(int ifIndex, @NonNull byte[] hwAddr) {
return new PacketSocketAddress(
- (short) 0 /* sll_protocol */,
+ 0 /* sll_protocol */,
ifIndex /* sll_ifindex */,
hwAddr /* sll_addr */);
}
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 7f60b9c..1351380 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -246,27 +246,6 @@
**/
/**
- * Return global network statistics summarized at an interface level,
- * without any UID-level granularity.
- */
- NetworkStats getNetworkStatsSummaryDev();
- NetworkStats getNetworkStatsSummaryXt();
-
- /**
- * Return detailed network statistics with UID-level granularity,
- * including interface and tag details.
- */
- NetworkStats getNetworkStatsDetail();
-
- /**
- * Return detailed network statistics for the requested UID and interfaces,
- * including interface and tag details.
- * @param uid UID to obtain statistics for, or {@link NetworkStats#UID_ALL}.
- * @param ifaces Interfaces to obtain statistics for, or {@link NetworkStats#INTERFACES_ALL}.
- */
- NetworkStats getNetworkStatsUidDetail(int uid, in String[] ifaces);
-
- /**
* Return summary of network statistics all tethering interfaces.
*/
NetworkStats getNetworkStatsTethering(int how);
diff --git a/core/java/android/service/gatekeeper/GateKeeperResponse.aidl b/core/java/android/service/gatekeeper/GateKeeperResponse.aidl
deleted file mode 100644
index 966606e..0000000
--- a/core/java/android/service/gatekeeper/GateKeeperResponse.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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.
- */
-
-package android.service.gatekeeper;
-
-/**
- * Response object for a GateKeeper verification request.
- * @hide
- */
-parcelable GateKeeperResponse;
-
diff --git a/core/java/android/service/gatekeeper/IGateKeeperService.aidl b/core/java/android/service/gatekeeper/IGateKeeperService.aidl
deleted file mode 100644
index abc6466..0000000
--- a/core/java/android/service/gatekeeper/IGateKeeperService.aidl
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.
- */
-
-package android.service.gatekeeper;
-
-import android.service.gatekeeper.GateKeeperResponse;
-
-/**
- * Interface for communication with GateKeeper, the
- * secure password storage daemon.
- *
- * This must be kept manually in sync with system/core/gatekeeperd
- * until AIDL can generate both C++ and Java bindings.
- *
- * @hide
- */
-interface IGateKeeperService {
- /**
- * Enrolls a password, returning the handle to the enrollment to be stored locally.
- * @param uid The Android user ID associated to this enrollment
- * @param currentPasswordHandle The previously enrolled handle, or null if none
- * @param currentPassword The previously enrolled plaintext password, or null if none.
- * If provided, must verify against the currentPasswordHandle.
- * @param desiredPassword The new desired password, for which a handle will be returned
- * upon success.
- * @return an EnrollResponse or null on failure
- */
- GateKeeperResponse enroll(int uid, in byte[] currentPasswordHandle, in byte[] currentPassword,
- in byte[] desiredPassword);
-
- /**
- * Verifies an enrolled handle against a provided, plaintext blob.
- * @param uid The Android user ID associated to this enrollment
- * @param enrolledPasswordHandle The handle against which the provided password will be
- * verified.
- * @param The plaintext blob to verify against enrolledPassword.
- * @return a VerifyResponse, or null on failure.
- */
- GateKeeperResponse verify(int uid, in byte[] enrolledPasswordHandle, in byte[] providedPassword);
-
- /**
- * Verifies an enrolled handle against a provided, plaintext blob.
- * @param uid The Android user ID associated to this enrollment
- * @param challenge a challenge to authenticate agaisnt the device credential. If successful
- * authentication occurs, this value will be written to the returned
- * authentication attestation.
- * @param enrolledPasswordHandle The handle against which the provided password will be
- * verified.
- * @param The plaintext blob to verify against enrolledPassword.
- * @return a VerifyResponse with an attestation, or null on failure.
- */
- GateKeeperResponse verifyChallenge(int uid, long challenge, in byte[] enrolledPasswordHandle,
- in byte[] providedPassword);
-
- /**
- * Retrieves the secure identifier for the user with the provided Android ID,
- * or 0 if none is found.
- * @param uid the Android user id
- */
- long getSecureUserId(int uid);
-
- /**
- * Clears secure user id associated with the provided Android ID.
- * Must be called when password is set to NONE.
- * @param uid the Android user id.
- */
- void clearSecureUserId(int uid);
-
- /**
- * Notifies gatekeeper that device setup has been completed and any potentially still existing
- * state from before a factory reset can be cleaned up (if it has not been already).
- */
- void reportDeviceSetupComplete();
-}
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 78331a1..b33b4a0 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -1893,12 +1893,13 @@
public static final boolean isWakeKey(int keyCode) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
+ case KeyEvent.KEYCODE_CAMERA:
case KeyEvent.KEYCODE_MENU:
- case KeyEvent.KEYCODE_WAKEUP:
case KeyEvent.KEYCODE_PAIRING:
case KeyEvent.KEYCODE_STEM_1:
case KeyEvent.KEYCODE_STEM_2:
case KeyEvent.KEYCODE_STEM_3:
+ case KeyEvent.KEYCODE_WAKEUP:
return true;
}
return false;
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index a85c585..b4a3661 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -88,6 +88,7 @@
private float mTouchDownX;
@UnsupportedAppUsage
private boolean mIsDragging;
+ private float mTouchThumbOffset = 0.0f;
public AbsSeekBar(Context context) {
super(context);
@@ -775,6 +776,14 @@
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
+ if (mThumb != null) {
+ final int availableWidth = getWidth() - mPaddingLeft - mPaddingRight;
+ mTouchThumbOffset = (getProgress() - getMin()) / (float) (getMax()
+ - getMin()) - (event.getX() - mPaddingLeft) / availableWidth;
+ if (Math.abs(mTouchThumbOffset * availableWidth) > getThumbOffset()) {
+ mTouchThumbOffset = 0;
+ }
+ }
if (isInScrollingContainer()) {
mTouchDownX = event.getX();
} else {
@@ -857,7 +866,8 @@
} else if (x < mPaddingLeft) {
scale = 1.0f;
} else {
- scale = (availableWidth - x + mPaddingLeft) / (float) availableWidth;
+ scale = (availableWidth - x + mPaddingLeft) / (float) availableWidth
+ + mTouchThumbOffset;
progress = mTouchProgressOffset;
}
} else {
@@ -866,7 +876,7 @@
} else if (x > width - mPaddingRight) {
scale = 1.0f;
} else {
- scale = (x - mPaddingLeft) / (float) availableWidth;
+ scale = (x - mPaddingLeft) / (float) availableWidth + mTouchThumbOffset;
progress = mTouchProgressOffset;
}
}
diff --git a/core/java/com/android/internal/os/KernelWakelockReader.java b/core/java/com/android/internal/os/KernelWakelockReader.java
index 86b2a90..df8c6d0 100644
--- a/core/java/com/android/internal/os/KernelWakelockReader.java
+++ b/core/java/com/android/internal/os/KernelWakelockReader.java
@@ -16,8 +16,13 @@
package com.android.internal.os;
import android.os.Process;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.ServiceManager.ServiceNotFoundException;
import android.os.StrictMode;
import android.os.SystemClock;
+import android.system.suspend.ISuspendControlService;
+import android.system.suspend.WakeLockInfo;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
@@ -58,6 +63,7 @@
private final String[] mProcWakelocksName = new String[3];
private final long[] mProcWakelocksData = new long[3];
+ private ISuspendControlService mSuspendControlService = null;
/**
* Reads kernel wakelock stats and updates the staleStats with the new information.
@@ -117,7 +123,52 @@
}
}
}
- return parseProcWakelocks(buffer, len, wakeup_sources, staleStats);
+
+ updateVersion(staleStats);
+
+ parseProcWakelocks(buffer, len, wakeup_sources, staleStats);
+
+ if (mSuspendControlService == null) {
+ try {
+ mSuspendControlService = ISuspendControlService.Stub.asInterface(
+ ServiceManager.getServiceOrThrow("suspend_control"));
+ } catch (ServiceNotFoundException e) {
+ Slog.wtf(TAG, "Required service suspend_control not available", e);
+ }
+ }
+
+ try {
+ WakeLockInfo[] wlStats = mSuspendControlService.getWakeLockStats();
+ getNativeWakelockStats(wlStats, staleStats);
+ } catch (RemoteException e) {
+ Slog.wtf(TAG, "Failed to obtain wakelock stats from ISuspendControlService", e);
+ }
+
+ return removeOldStats(staleStats);
+ }
+
+ /**
+ * Reads native wakelock stats from SystemSuspend and updates staleStats with the new
+ * information.
+ * @param staleStats Existing object to update.
+ * @return the updated stats.
+ */
+ @VisibleForTesting
+ public KernelWakelockStats getNativeWakelockStats(WakeLockInfo[] wlStats,
+ final KernelWakelockStats staleStats) {
+ for (WakeLockInfo info : wlStats) {
+ if (!staleStats.containsKey(info.name)) {
+ staleStats.put(info.name, new KernelWakelockStats.Entry((int) info.activeCount,
+ info.totalTime, sKernelWakelockUpdateVersion));
+ } else {
+ KernelWakelockStats.Entry kwlStats = staleStats.get(info.name);
+ kwlStats.mCount = (int) info.activeCount;
+ kwlStats.mTotalTime = info.totalTime;
+ kwlStats.mVersion = sKernelWakelockUpdateVersion;
+ }
+ }
+
+ return staleStats;
}
/**
@@ -138,7 +189,6 @@
startIndex = endIndex = i + 1;
synchronized(this) {
- sKernelWakelockUpdateVersion++;
while (endIndex < len) {
for (endIndex=startIndex;
endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0';
@@ -199,16 +249,35 @@
startIndex = endIndex + 1;
}
- // Don't report old data.
- Iterator<KernelWakelockStats.Entry> itr = staleStats.values().iterator();
- while (itr.hasNext()) {
- if (itr.next().mVersion != sKernelWakelockUpdateVersion) {
- itr.remove();
- }
- }
-
- staleStats.kernelWakelockVersion = sKernelWakelockUpdateVersion;
return staleStats;
}
}
+
+ /**
+ * Increments sKernelWakelockUpdateVersion and updates the version in staleStats.
+ * @param staleStats Existing object to update.
+ * @return the updated stats.
+ */
+ @VisibleForTesting
+ public KernelWakelockStats updateVersion(KernelWakelockStats staleStats) {
+ sKernelWakelockUpdateVersion++;
+ staleStats.kernelWakelockVersion = sKernelWakelockUpdateVersion;
+ return staleStats;
+ }
+
+ /**
+ * Removes old stats from staleStats.
+ * @param staleStats Existing object to update.
+ * @return the updated stats.
+ */
+ @VisibleForTesting
+ public KernelWakelockStats removeOldStats(final KernelWakelockStats staleStats) {
+ Iterator<KernelWakelockStats.Entry> itr = staleStats.values().iterator();
+ while (itr.hasNext()) {
+ if (itr.next().mVersion != sKernelWakelockUpdateVersion) {
+ itr.remove();
+ }
+ }
+ return staleStats;
+ }
}
diff --git a/core/proto/android/stats/dnsresolver/dns_resolver.proto b/core/proto/android/stats/dnsresolver/dns_resolver.proto
index b7bf384..9eaabfb 100644
--- a/core/proto/android/stats/dnsresolver/dns_resolver.proto
+++ b/core/proto/android/stats/dnsresolver/dns_resolver.proto
@@ -67,6 +67,7 @@
// NS_R_BADSIG = 16,
NS_R_BADKEY = 17;
NS_R_BADTIME = 18;
+ NS_R_INTERNAL_ERROR = 254;
NS_R_TIMEOUT = 255;
}
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelWakelockReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelWakelockReaderTest.java
index 4e4bb3507..008085e 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelWakelockReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelWakelockReaderTest.java
@@ -13,14 +13,17 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
+
package com.android.internal.os;
-import android.support.test.filters.SmallTest;
+import androidx.test.filters.SmallTest;
import junit.framework.TestCase;
import java.nio.charset.Charset;
+import android.system.suspend.WakeLockInfo;
+
public class KernelWakelockReaderTest extends TestCase {
/**
* Helper class that builds the mock Kernel module file /d/wakeup_sources.
@@ -57,6 +60,39 @@
}
}
+ /**
+ * Helper method to create WakeLockInfo object.
+ * @param totalTime is time in microseconds.
+ * @return the created WakeLockInfo object.
+ */
+ private WakeLockInfo createWakeLockInfo(String name, int activeCount, long totalTime) {
+ WakeLockInfo info = new WakeLockInfo();
+ info.name = name;
+ info.pid = 1;
+ info.activeCount = activeCount;
+ info.isActive = true;
+ info.activeSince = 0;
+ info.lastChange = 0;
+ info.maxTime = 0;
+ info.totalTime = totalTime;
+ return info;
+ }
+
+ /**
+ * Helper method for KernelWakeLockReader::readKernelWakelockStats(...)
+ * @param staleStats existing stats to update.
+ * @param buffer representation of mock kernel module file /d/wakeup_sources.
+ * @param wlStats mock WakeLockInfo list returned from ISuspendControlService.
+ * @return the updated stats.
+ */
+ private KernelWakelockStats readKernelWakelockStats(KernelWakelockStats staleStats,
+ byte[] buffer, WakeLockInfo[] wlStats) {
+ mReader.updateVersion(staleStats);
+ mReader.parseProcWakelocks(buffer, buffer.length, true, staleStats);
+ mReader.getNativeWakelockStats(wlStats, staleStats);
+ return mReader.removeOldStats(staleStats);
+ }
+
private KernelWakelockReader mReader;
@Override
@@ -65,18 +101,22 @@
mReader = new KernelWakelockReader();
}
+// ------------------------- Kernel Wakelock Stats Test ------------------------
@SmallTest
public void testParseEmptyFile() throws Exception {
KernelWakelockStats staleStats = mReader.parseProcWakelocks(new byte[0], 0, true,
new KernelWakelockStats());
+
assertTrue(staleStats.isEmpty());
}
@SmallTest
public void testOnlyHeader() throws Exception {
byte[] buffer = new ProcFileBuilder().getBytes();
+
KernelWakelockStats staleStats = mReader.parseProcWakelocks(buffer, buffer.length, true,
new KernelWakelockStats());
+
assertTrue(staleStats.isEmpty());
}
@@ -85,9 +125,12 @@
byte[] buffer = new ProcFileBuilder()
.addLine("Wakelock", 34, 123) // Milliseconds
.getBytes();
+
KernelWakelockStats staleStats = mReader.parseProcWakelocks(buffer, buffer.length, true,
new KernelWakelockStats());
+
assertEquals(1, staleStats.size());
+
assertTrue(staleStats.containsKey("Wakelock"));
KernelWakelockStats.Entry entry = staleStats.get("Wakelock");
@@ -101,9 +144,12 @@
.addLine("Wakelock", 1, 10)
.addLine("Fakelock", 2, 20)
.getBytes();
+
KernelWakelockStats staleStats = mReader.parseProcWakelocks(buffer, buffer.length, true,
new KernelWakelockStats());
+
assertEquals(2, staleStats.size());
+
assertTrue(staleStats.containsKey("Wakelock"));
assertTrue(staleStats.containsKey("Fakelock"));
}
@@ -114,8 +160,10 @@
.addLine("Wakelock", 1, 10) // Milliseconds
.addLine("Wakelock", 1, 10) // Milliseconds
.getBytes();
+
KernelWakelockStats staleStats = mReader.parseProcWakelocks(buffer, buffer.length, true,
new KernelWakelockStats());
+
assertEquals(1, staleStats.size());
assertTrue(staleStats.containsKey("Wakelock"));
@@ -126,12 +174,14 @@
@SmallTest
public void testWakelocksBecomeStale() throws Exception {
+ KernelWakelockStats staleStats = new KernelWakelockStats();
+
byte[] buffer = new ProcFileBuilder()
.addLine("Fakelock", 3, 30)
.getBytes();
- KernelWakelockStats staleStats = new KernelWakelockStats();
- staleStats = mReader.parseProcWakelocks(buffer, buffer.length, true, staleStats);
+ readKernelWakelockStats(staleStats, buffer, new WakeLockInfo[0]);
+
assertEquals(1, staleStats.size());
assertTrue(staleStats.containsKey("Fakelock"));
@@ -139,9 +189,228 @@
.addLine("Wakelock", 1, 10)
.getBytes();
- staleStats = mReader.parseProcWakelocks(buffer, buffer.length, true, staleStats);
+ readKernelWakelockStats(staleStats, buffer, new WakeLockInfo[0]);
+
assertEquals(1, staleStats.size());
assertTrue(staleStats.containsKey("Wakelock"));
assertFalse(staleStats.containsKey("Fakelock"));
}
+
+// -------------------- Native (SystemSuspend) Wakelock Stats Test -------------------
+ @SmallTest
+ public void testEmptyWakeLockInfoList() {
+ KernelWakelockStats staleStats = mReader.getNativeWakelockStats(new WakeLockInfo[0],
+ new KernelWakelockStats());
+
+ assertTrue(staleStats.isEmpty());
+ }
+
+ @SmallTest
+ public void testOneWakeLockInfo() {
+ WakeLockInfo[] wlStats = new WakeLockInfo[1];
+ wlStats[0] = createWakeLockInfo("WakeLock", 20, 10000);
+
+ KernelWakelockStats staleStats = mReader.getNativeWakelockStats(wlStats,
+ new KernelWakelockStats());
+
+ assertEquals(1, staleStats.size());
+
+ assertTrue(staleStats.containsKey("WakeLock"));
+
+ KernelWakelockStats.Entry entry = staleStats.get("WakeLock");
+ assertEquals(20, entry.mCount);
+ assertEquals(10000, entry.mTotalTime);
+ }
+
+ @SmallTest
+ public void testTwoWakeLockInfos() {
+ WakeLockInfo[] wlStats = new WakeLockInfo[2];
+ wlStats[0] = createWakeLockInfo("WakeLock1", 10, 1000);
+ wlStats[1] = createWakeLockInfo("WakeLock2", 20, 2000);
+
+ KernelWakelockStats staleStats = mReader.getNativeWakelockStats(wlStats,
+ new KernelWakelockStats());
+
+ assertEquals(2, staleStats.size());
+
+ assertTrue(staleStats.containsKey("WakeLock1"));
+ assertTrue(staleStats.containsKey("WakeLock2"));
+
+ KernelWakelockStats.Entry entry1 = staleStats.get("WakeLock1");
+ assertEquals(10, entry1.mCount);
+ assertEquals(1000, entry1.mTotalTime);
+
+ KernelWakelockStats.Entry entry2 = staleStats.get("WakeLock2");
+ assertEquals(20, entry2.mCount);
+ assertEquals(2000, entry2.mTotalTime);
+ }
+
+ @SmallTest
+ public void testWakeLockInfosBecomeStale() {
+ WakeLockInfo[] wlStats = new WakeLockInfo[1];
+ wlStats[0] = createWakeLockInfo("WakeLock1", 10, 1000);
+
+ KernelWakelockStats staleStats = new KernelWakelockStats();
+
+ readKernelWakelockStats(staleStats, new byte[0], wlStats);
+
+ assertEquals(1, staleStats.size());
+
+ assertTrue(staleStats.containsKey("WakeLock1"));
+ KernelWakelockStats.Entry entry = staleStats.get("WakeLock1");
+ assertEquals(10, entry.mCount);
+ assertEquals(1000, entry.mTotalTime);
+
+ wlStats[0] = createWakeLockInfo("WakeLock2", 20, 2000);
+
+ readKernelWakelockStats(staleStats, new byte[0], wlStats);
+
+ assertEquals(1, staleStats.size());
+
+ assertFalse(staleStats.containsKey("WakeLock1"));
+ assertTrue(staleStats.containsKey("WakeLock2"));
+ entry = staleStats.get("WakeLock2");
+ assertEquals(20, entry.mCount);
+ assertEquals(2000, entry.mTotalTime);
+ }
+
+// -------------------- Aggregate Wakelock Stats Tests --------------------
+ @SmallTest
+ public void testAggregateStatsEmpty() throws Exception {
+ KernelWakelockStats staleStats = new KernelWakelockStats();
+
+ byte[] buffer = new byte[0];
+ WakeLockInfo[] wlStats = new WakeLockInfo[0];
+
+ readKernelWakelockStats(staleStats, buffer, wlStats);
+
+ assertTrue(staleStats.isEmpty());
+ }
+
+ @SmallTest
+ public void testAggregateStatsNoNativeWakelocks() throws Exception {
+ KernelWakelockStats staleStats = new KernelWakelockStats();
+
+ byte[] buffer = new ProcFileBuilder()
+ .addLine("Wakelock", 34, 123) // Milliseconds
+ .getBytes();
+ WakeLockInfo[] wlStats = new WakeLockInfo[0];
+
+ readKernelWakelockStats(staleStats, buffer, wlStats);
+
+ assertEquals(1, staleStats.size());
+
+ assertTrue(staleStats.containsKey("Wakelock"));
+
+ KernelWakelockStats.Entry entry = staleStats.get("Wakelock");
+ assertEquals(34, entry.mCount);
+ assertEquals(1000 * 123, entry.mTotalTime); // Microseconds
+ }
+
+ @SmallTest
+ public void testAggregateStatsNoKernelWakelocks() throws Exception {
+ KernelWakelockStats staleStats = new KernelWakelockStats();
+
+ byte[] buffer = new byte[0];
+ WakeLockInfo[] wlStats = new WakeLockInfo[1];
+ wlStats[0] = createWakeLockInfo("WakeLock", 10, 1000);
+
+ readKernelWakelockStats(staleStats, buffer, wlStats);
+
+ assertEquals(1, staleStats.size());
+
+ assertTrue(staleStats.containsKey("WakeLock"));
+
+ KernelWakelockStats.Entry entry = staleStats.get("WakeLock");
+ assertEquals(10, entry.mCount);
+ assertEquals(1000, entry.mTotalTime);
+ }
+
+ @SmallTest
+ public void testAggregateStatsBothKernelAndNativeWakelocks() throws Exception {
+ KernelWakelockStats staleStats = new KernelWakelockStats();
+
+ byte[] buffer = new ProcFileBuilder()
+ .addLine("WakeLock1", 34, 123) // Milliseconds
+ .getBytes();
+ WakeLockInfo[] wlStats = new WakeLockInfo[1];
+ wlStats[0] = createWakeLockInfo("WakeLock2", 10, 1000);
+
+ readKernelWakelockStats(staleStats, buffer, wlStats);
+
+ assertEquals(2, staleStats.size());
+
+ assertTrue(staleStats.containsKey("WakeLock1"));
+ KernelWakelockStats.Entry entry1 = staleStats.get("WakeLock1");
+ assertEquals(34, entry1.mCount);
+ assertEquals(123 * 1000, entry1.mTotalTime); // Microseconds
+
+ assertTrue(staleStats.containsKey("WakeLock2"));
+ KernelWakelockStats.Entry entry2 = staleStats.get("WakeLock2");
+ assertEquals(10, entry2.mCount);
+ assertEquals(1000, entry2.mTotalTime);
+ }
+
+ @SmallTest
+ public void testAggregateStatsUpdate() throws Exception {
+ KernelWakelockStats staleStats = new KernelWakelockStats();
+
+ byte[] buffer = new ProcFileBuilder()
+ .addLine("WakeLock1", 34, 123) // Milliseconds
+ .addLine("WakeLock2", 46, 345) // Milliseconds
+ .getBytes();
+ WakeLockInfo[] wlStats = new WakeLockInfo[2];
+ wlStats[0] = createWakeLockInfo("WakeLock3", 10, 1000);
+ wlStats[1] = createWakeLockInfo("WakeLock4", 20, 2000);
+
+ readKernelWakelockStats(staleStats, buffer, wlStats);
+
+ assertEquals(4, staleStats.size());
+
+ assertTrue(staleStats.containsKey("WakeLock1"));
+ assertTrue(staleStats.containsKey("WakeLock2"));
+ assertTrue(staleStats.containsKey("WakeLock3"));
+ assertTrue(staleStats.containsKey("WakeLock4"));
+
+ KernelWakelockStats.Entry entry1 = staleStats.get("WakeLock1");
+ assertEquals(34, entry1.mCount);
+ assertEquals(123 * 1000, entry1.mTotalTime); // Microseconds
+
+ KernelWakelockStats.Entry entry2 = staleStats.get("WakeLock2");
+ assertEquals(46, entry2.mCount);
+ assertEquals(345 * 1000, entry2.mTotalTime); // Microseconds
+
+ KernelWakelockStats.Entry entry3 = staleStats.get("WakeLock3");
+ assertEquals(10, entry3.mCount);
+ assertEquals(1000, entry3.mTotalTime);
+
+ KernelWakelockStats.Entry entry4 = staleStats.get("WakeLock4");
+ assertEquals(20, entry4.mCount);
+ assertEquals(2000, entry4.mTotalTime);
+
+ buffer = new ProcFileBuilder()
+ .addLine("WakeLock1", 45, 789) // Milliseconds
+ .addLine("WakeLock1", 56, 123) // Milliseconds
+ .getBytes();
+ wlStats = new WakeLockInfo[1];
+ wlStats[0] = createWakeLockInfo("WakeLock4", 40, 4000);
+
+ readKernelWakelockStats(staleStats, buffer, wlStats);
+
+ assertEquals(2, staleStats.size());
+
+ assertTrue(staleStats.containsKey("WakeLock1"));
+ assertTrue(staleStats.containsKey("WakeLock4"));
+
+ assertFalse(staleStats.containsKey("WakeLock2"));
+ assertFalse(staleStats.containsKey("WakeLock3"));
+
+ entry1 = staleStats.get("WakeLock1");
+ assertEquals(45 + 56, entry1.mCount);
+ assertEquals((789 + 123) * 1000, entry1.mTotalTime); // Microseconds
+
+ entry2 = staleStats.get("WakeLock4");
+ assertEquals(40, entry2.mCount);
+ assertEquals(4000, entry4.mTotalTime);
+ }
}
diff --git a/media/java/android/media/tv/TvTrackInfo.java b/media/java/android/media/tv/TvTrackInfo.java
index 2bc9a2b..10cbad9 100644
--- a/media/java/android/media/tv/TvTrackInfo.java
+++ b/media/java/android/media/tv/TvTrackInfo.java
@@ -277,28 +277,36 @@
@Override
public boolean equals(Object o) {
if (this == o) {
- return true;
+ return true;
}
if (!(o instanceof TvTrackInfo)) {
- return false;
+ return false;
}
TvTrackInfo obj = (TvTrackInfo) o;
- return TextUtils.equals(mId, obj.mId)
- && mType == obj.mType
- && TextUtils.equals(mLanguage, obj.mLanguage)
- && TextUtils.equals(mDescription, obj.mDescription)
- && mEncrypted == obj.mEncrypted
- && Objects.equals(mExtra, obj.mExtra)
- && (mType == TYPE_AUDIO
- ? mAudioChannelCount == obj.mAudioChannelCount
- && mAudioSampleRate == obj.mAudioSampleRate
- : (mType == TYPE_VIDEO
- ? mVideoWidth == obj.mVideoWidth
- && mVideoHeight == obj.mVideoHeight
- && mVideoFrameRate == obj.mVideoFrameRate
- && mVideoPixelAspectRatio == obj.mVideoPixelAspectRatio : true));
+
+ if (!TextUtils.equals(mId, obj.mId) || mType != obj.mType
+ || !TextUtils.equals(mLanguage, obj.mLanguage)
+ || !TextUtils.equals(mDescription, obj.mDescription)
+ || !Objects.equals(mExtra, obj.mExtra)) {
+ return false;
+ }
+
+ switch (mType) {
+ case TYPE_AUDIO:
+ return mAudioChannelCount == obj.mAudioChannelCount
+ && mAudioSampleRate == obj.mAudioSampleRate;
+
+ case TYPE_VIDEO:
+ return mVideoWidth == obj.mVideoWidth
+ && mVideoHeight == obj.mVideoHeight
+ && mVideoFrameRate == obj.mVideoFrameRate
+ && mVideoPixelAspectRatio == obj.mVideoPixelAspectRatio
+ && mVideoActiveFormatDescription == obj.mVideoActiveFormatDescription;
+ }
+
+ return true;
}
@Override
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 7d0291f..1a5d6e3 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -68,8 +68,8 @@
],
aaptflags: [
- "--extra-packages",
- "com.android.keyguard",
+ "--extra-packages com.android.keyguard",
+ "--legacy",
],
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index b7c20aa..b67a9f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -548,7 +548,7 @@
}
private boolean isDataDisabled() {
- return !mPhone.getDataEnabled(mSubscriptionInfo.getSubscriptionId());
+ return !mPhone.isDataCapable();
}
@VisibleForTesting
@@ -568,6 +568,7 @@
pw.println(" mSignalStrength=" + mSignalStrength + ",");
pw.println(" mDataState=" + mDataState + ",");
pw.println(" mDataNetType=" + mDataNetType + ",");
+ pw.println(" isDataDisabled=" + isDataDisabled() + ",");
}
class MobilePhoneStateListener extends PhoneStateListener {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index c1f8885..02f99a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -155,7 +155,7 @@
protected void setupNetworkController() {
// For now just pretend to be the data sim, so we can test that too.
mSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
- when(mMockTm.getDataEnabled(mSubId)).thenReturn(true);
+ when(mMockTm.isDataCapable()).thenReturn(true);
setDefaultSubId(mSubId);
setSubscriptions(mSubId);
mMobileSignalController = mNetworkController.mMobileSignalControllers.get(mSubId);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index 96fad21..2aa933e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -119,7 +119,7 @@
@Test
public void testNoInternetIcon() {
setupNetworkController();
- when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
+ when(mMockTm.isDataCapable()).thenReturn(false);
setupDefaultSignal();
updateDataConnectionState(TelephonyManager.DATA_CONNECTED, 0);
setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
@@ -133,7 +133,7 @@
@Test
public void testDataDisabledIcon() {
setupNetworkController();
- when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
+ when(mMockTm.isDataCapable()).thenReturn(false);
setupDefaultSignal();
updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
@@ -188,7 +188,7 @@
@Test
public void testDataDisabledIcon_UserNotSetup() {
setupNetworkController();
- when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
+ when(mMockTm.isDataCapable()).thenReturn(false);
setupDefaultSignal();
updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
@@ -203,7 +203,7 @@
@Test
public void testAlwaysShowDataRatIcon() {
setupDefaultSignal();
- when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
+ when(mMockTm.isDataCapable()).thenReturn(false);
updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED,
TelephonyManager.NETWORK_TYPE_GSM);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index ae80d7e..f8c1b24 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -192,7 +192,6 @@
import com.android.server.net.BaseNetworkObserver;
import com.android.server.net.LockdownVpnTracker;
import com.android.server.net.NetworkPolicyManagerInternal;
-import com.android.server.net.NetworkStatsFactory;
import com.android.server.utils.PriorityDump;
import com.google.android.collect.Lists;
@@ -2614,9 +2613,11 @@
final boolean valid = ((msg.arg1 & NETWORK_VALIDATION_RESULT_VALID) != 0);
final boolean wasValidated = nai.lastValidated;
final boolean wasDefault = isDefaultNetwork(nai);
- if (nai.everCaptivePortalDetected && !nai.captivePortalLoginNotified
- && valid) {
- nai.captivePortalLoginNotified = true;
+ // Only show a connected notification if the network is pending validation
+ // after the captive portal app was open, and it has now validated.
+ if (nai.captivePortalValidationPending && valid) {
+ // User is now logged in, network validated.
+ nai.captivePortalValidationPending = false;
showNetworkNotification(nai, NotificationType.LOGGED_IN);
}
@@ -2687,9 +2688,6 @@
final int oldScore = nai.getCurrentScore();
nai.lastCaptivePortalDetected = visible;
nai.everCaptivePortalDetected |= visible;
- if (visible) {
- nai.captivePortalLoginNotified = false;
- }
if (nai.lastCaptivePortalDetected &&
Settings.Global.CAPTIVE_PORTAL_MODE_AVOID == getCaptivePortalMode()) {
if (DBG) log("Avoiding captive portal network: " + nai.name());
@@ -3498,6 +3496,12 @@
new CaptivePortal(new CaptivePortalImpl(network).asBinder()));
appIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
+ // This runs on a random binder thread, but getNetworkAgentInfoForNetwork is thread-safe,
+ // and captivePortalValidationPending is volatile.
+ final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
+ if (nai != null) {
+ nai.captivePortalValidationPending = true;
+ }
Binder.withCleanCallingIdentity(() ->
mContext.startActivityAsUser(appIntent, UserHandle.CURRENT));
}
@@ -6795,8 +6799,8 @@
}
/**
- * Notify NetworkStatsService and NetworkStatsFactory that the set of active ifaces has changed,
- * or that one of the active iface's trackedproperties has changed.
+ * Notify NetworkStatsService that the set of active ifaces has changed, or that one of the
+ * active iface's tracked properties has changed.
*/
private void notifyIfacesChangedForNetworkStats() {
ensureRunningOnConnectivityServiceThread();
@@ -6806,16 +6810,12 @@
activeIface = activeLinkProperties.getInterfaceName();
}
- // CAUTION: Ordering matters between updateVpnInfos() and forceUpdateIfaces(), which
- // triggers a new poll. Trigger the poll first to ensure a snapshot is taken before
- // switching to the new state. This ensures that traffic does not get mis-attributed to
- // incorrect apps (including VPN app).
+ final VpnInfo[] vpnInfos = getAllVpnInfo();
try {
mStatsService.forceUpdateIfaces(
- getDefaultNetworks(), getAllNetworkState(), activeIface);
+ getDefaultNetworks(), getAllNetworkState(), activeIface, vpnInfos);
} catch (Exception ignored) {
}
- NetworkStatsFactory.updateVpnInfos(getAllVpnInfo());
}
@Override
diff --git a/services/core/java/com/android/server/ExtconStateObserver.java b/services/core/java/com/android/server/ExtconStateObserver.java
new file mode 100644
index 0000000..6b561c7
--- /dev/null
+++ b/services/core/java/com/android/server/ExtconStateObserver.java
@@ -0,0 +1,96 @@
+/*
+ * 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.android.server;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.FileUtils;
+import android.util.Slog;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+/**
+ * A specialized ExtconUEventObserver that on receiving a {@link UEvent} calls {@link
+ * #updateState(ExtconInfo, String, S)} with the value of{@link #parseState(ExtconInfo, String)}.
+ *
+ * @param <S> the type of state to parse and update
+ * @hide
+ */
+public abstract class ExtconStateObserver<S> extends ExtconUEventObserver {
+ private static final String TAG = "ExtconStateObserver";
+ private static final boolean LOG = false;
+
+ /**
+ * Parses the current state from the state file for {@code extconInfo} and calls {@link
+ * #updateState(ExtconInfo, String, Object)}
+ *
+ * @param extconInfo the extconInfo to update state for
+ * @see #parseState(ExtconInfo, String)
+ * @see ExtconInfo#getStatePath()
+ */
+ public void updateStateFromFile(ExtconInfo extconInfo) {
+ String statePath = extconInfo.getStatePath();
+ try {
+ S state =
+ parseState(
+ extconInfo,
+ FileUtils.readTextFile(new File(statePath), 0, null).trim());
+ if (state != null) {
+ updateState(extconInfo, extconInfo.getName(), state);
+ }
+ } catch (FileNotFoundException e) {
+ Slog.w(TAG, statePath + " not found while attempting to determine initial state", e);
+ } catch (IOException e) {
+ Slog.e(
+ TAG,
+ "Error reading " + statePath + " while attempting to determine initial state ",
+ e);
+ }
+ }
+
+ @Override
+ public void onUEvent(ExtconInfo extconInfo, UEvent event) {
+ if (LOG) Slog.d(TAG, extconInfo.getName() + " UEVENT: " + event);
+ String name = event.get("NAME");
+ S state = parseState(extconInfo, event.get("STATE"));
+ if (state != null) {
+ updateState(extconInfo, name, state);
+ }
+ }
+
+ /**
+ * Subclasses of ExtconStateObserver should override this method update state for {@code
+ * exconInfo} from an {@code UEvent}.
+ *
+ * @param extconInfo the external connection
+ * @param eventName the {@code NAME} of the {@code UEvent}
+ * @param state the{@code STATE} as parsed by {@link #parseState(ExtconInfo, String)}.
+ */
+ public abstract void updateState(ExtconInfo extconInfo, String eventName, @NonNull S state);
+
+ /**
+ * Subclasses of ExtconStateObserver should override this method to parse the {@code STATE} from
+ * an UEvent.
+ *
+ * @param extconInfo that matches the {@code DEVPATH} of {@code event}
+ * @param state the {@code STATE} from a {@code UEvent}.
+ * @return the parsed state. Return null if the state can not be parsed.
+ */
+ @Nullable
+ public abstract S parseState(ExtconInfo extconInfo, String state);
+}
diff --git a/services/core/java/com/android/server/ExtconUEventObserver.java b/services/core/java/com/android/server/ExtconUEventObserver.java
new file mode 100644
index 0000000..b3084f5
--- /dev/null
+++ b/services/core/java/com/android/server/ExtconUEventObserver.java
@@ -0,0 +1,128 @@
+/*
+ * 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.android.server;
+
+import android.annotation.Nullable;
+import android.os.UEventObserver;
+import android.util.ArrayMap;
+import android.util.Slog;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * A specialized UEventObserver that receives UEvents from the kernel for devices in the {@code
+ * /sys/class/extcon}. directory
+ *
+ * <p>Subclass ExtconUEventObserver, implementing {@link #onUEvent(ExtconInfo, UEvent)}, then call
+ * startObserving() with a ExtconInfo to observe. The UEvent thread will then call your onUEvent()
+ * method when a UEvent occurs that matches the path of your ExtconInfos.
+ *
+ * <p>Call stopObserving() to stop receiving UEvents.
+ *
+ * <p>There is only one UEvent thread per process, even if that process has multiple UEventObserver
+ * subclass instances. The UEvent thread starts when the startObserving() is called for the first
+ * time in that process. Once started the UEvent thread will not stop (although it can stop
+ * notifying UEventObserver's via stopObserving()).
+ *
+ * <p>
+ *
+ * @hide
+ */
+public abstract class ExtconUEventObserver extends UEventObserver {
+ private static final String TAG = "ExtconUEventObserver";
+ private static final boolean LOG = false;
+ private final Map<String, ExtconInfo> mExtconInfos = new ArrayMap<>();
+
+ @Override
+ public final void onUEvent(UEvent event) {
+ String devPath = event.get("DEVPATH");
+ ExtconInfo info = mExtconInfos.get(devPath);
+ if (info != null) {
+ onUEvent(info, event);
+ } else {
+ Slog.w(TAG, "No match found for DEVPATH of " + event + " in " + mExtconInfos);
+ }
+ }
+
+ /**
+ * Subclasses of ExtconUEventObserver should override this method to handle UEvents.
+ *
+ * @param extconInfo that matches the {@code DEVPATH} of {@code event}
+ * @param event the event
+ */
+ protected abstract void onUEvent(ExtconInfo extconInfo, UEvent event);
+
+ /** Starts observing {@link ExtconInfo#getDevicePath()}. */
+ public void startObserving(ExtconInfo extconInfo) {
+ mExtconInfos.put(extconInfo.getDevicePath(), extconInfo);
+ if (LOG) Slog.v(TAG, "Observing " + extconInfo.getDevicePath());
+ startObserving("DEVPATH=" + extconInfo.getDevicePath());
+ }
+
+ /** An External Connection to watch. */
+ public static final class ExtconInfo {
+ private static final String TAG = "ExtconInfo";
+
+ private final String mName;
+
+ public ExtconInfo(String name) {
+ mName = name;
+ }
+
+ /** The name of the external connection */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * The path to the device for this external connection.
+ *
+ * <p><b>NOTE</b> getting this path involves resolving a symlink.
+ *
+ * @return the device path, or null if it not found.
+ */
+ @Nullable
+ public String getDevicePath() {
+ try {
+ String extconPath = String.format(Locale.US, "/sys/class/extcon/%s", mName);
+ File devPath = new File(extconPath);
+ if (devPath.exists()) {
+ String canonicalPath = devPath.getCanonicalPath();
+ int start = canonicalPath.indexOf("/devices");
+ return canonicalPath.substring(start);
+ }
+ return null;
+ } catch (IOException e) {
+ Slog.e(TAG, "Could not get the extcon device path for " + mName, e);
+ return null;
+ }
+ }
+
+ /** The path to the state file */
+ public String getStatePath() {
+ return String.format(Locale.US, "/sys/class/extcon/%s/state", mName);
+ }
+ }
+
+ /** Does the {@link /sys/class/extcon} directory exist */
+ public static boolean extconExists() {
+ File extconDir = new File("/sys/class/extcon");
+ return extconDir.exists() && extconDir.isDirectory();
+ }
+}
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 6d08b5a..e29bf8d 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -34,7 +34,6 @@
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
import static android.net.NetworkStats.SET_DEFAULT;
import static android.net.NetworkStats.STATS_PER_UID;
-import static android.net.NetworkStats.TAG_ALL;
import static android.net.NetworkStats.TAG_NONE;
import static android.net.TrafficStats.UID_TETHERING;
@@ -90,7 +89,6 @@
import com.android.internal.util.DumpUtils;
import com.android.internal.util.HexDump;
import com.android.internal.util.Preconditions;
-import com.android.server.net.NetworkStatsFactory;
import com.google.android.collect.Maps;
@@ -164,8 +162,6 @@
private final RemoteCallbackList<INetworkManagementEventObserver> mObservers =
new RemoteCallbackList<>();
- private final NetworkStatsFactory mStatsFactory = new NetworkStatsFactory();
-
@GuardedBy("mTetheringStatsProviders")
private final HashMap<ITetheringStatsProvider, String>
mTetheringStatsProviders = Maps.newHashMap();
@@ -1207,36 +1203,6 @@
}
@Override
- public NetworkStats getNetworkStatsSummaryDev() {
- mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
- try {
- return mStatsFactory.readNetworkStatsSummaryDev();
- } catch (IOException e) {
- throw new IllegalStateException(e);
- }
- }
-
- @Override
- public NetworkStats getNetworkStatsSummaryXt() {
- mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
- try {
- return mStatsFactory.readNetworkStatsSummaryXt();
- } catch (IOException e) {
- throw new IllegalStateException(e);
- }
- }
-
- @Override
- public NetworkStats getNetworkStatsDetail() {
- mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
- try {
- return mStatsFactory.readNetworkStatsDetail();
- } catch (IOException e) {
- throw new IllegalStateException(e);
- }
- }
-
- @Override
public void setInterfaceQuota(String iface, long quotaBytes) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
@@ -1535,16 +1501,6 @@
return true;
}
- @Override
- public NetworkStats getNetworkStatsUidDetail(int uid, String[] ifaces) {
- mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
- try {
- return mStatsFactory.readNetworkStatsDetail(uid, ifaces, TAG_ALL);
- } catch (IOException e) {
- throw new IllegalStateException(e);
- }
- }
-
private class NetdTetheringStatsProvider extends ITetheringStatsProvider.Stub {
@Override
public NetworkStats getTetherStats(int how) {
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 864a793..5b04379 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -155,9 +155,9 @@
// Whether a captive portal was found during the last network validation attempt.
public boolean lastCaptivePortalDetected;
- // Indicates the user was notified of a successful captive portal login since a portal was
- // last detected.
- public boolean captivePortalLoginNotified;
+ // Indicates the captive portal app was opened to show a login UI to the user, but the network
+ // has not validated yet.
+ public volatile boolean captivePortalValidationPending;
// Set to true when partial connectivity was detected.
public boolean partialConnectivity;
@@ -629,7 +629,7 @@
+ "acceptUnvalidated{" + networkMisc.acceptUnvalidated + "} "
+ "everCaptivePortalDetected{" + everCaptivePortalDetected + "} "
+ "lastCaptivePortalDetected{" + lastCaptivePortalDetected + "} "
- + "captivePortalLoginNotified{" + captivePortalLoginNotified + "} "
+ + "captivePortalValidationPending{" + captivePortalValidationPending + "} "
+ "partialConnectivity{" + partialConnectivity + "} "
+ "acceptPartialConnectivity{" + networkMisc.acceptPartialConnectivity + "} "
+ "clat{" + clatd + "} "
diff --git a/services/core/java/com/android/server/net/NetworkStatsFactory.java b/services/core/java/com/android/server/net/NetworkStatsFactory.java
index 7687718..3ca1803 100644
--- a/services/core/java/com/android/server/net/NetworkStatsFactory.java
+++ b/services/core/java/com/android/server/net/NetworkStatsFactory.java
@@ -78,17 +78,17 @@
* <p>In order to prevent deadlocks, critical sections protected by this lock SHALL NOT call out
* to other code that will acquire other locks within the system server. See b/134244752.
*/
- private static final Object sPersistentDataLock = new Object();
+ private final Object mPersistentDataLock = new Object();
/** Set containing info about active VPNs and their underlying networks. */
- private static volatile VpnInfo[] sVpnInfos = new VpnInfo[0];
+ private volatile VpnInfo[] mVpnInfos = new VpnInfo[0];
// A persistent snapshot of cumulative stats since device start
- @GuardedBy("sPersistentDataLock")
+ @GuardedBy("mPersistentDataLock")
private NetworkStats mPersistSnapshot;
// The persistent snapshot of tun and 464xlat adjusted stats since device start
- @GuardedBy("sPersistentDataLock")
+ @GuardedBy("mPersistentDataLock")
private NetworkStats mTunAnd464xlatAdjustedStats;
/**
@@ -97,12 +97,13 @@
* Because counters must never roll backwards, once a given interface is stacked on top of an
* underlying interface, the stacked interface can never be stacked on top of
* another interface. */
- private static final ConcurrentHashMap<String, String> sStackedIfaces
+ private final ConcurrentHashMap<String, String> mStackedIfaces
= new ConcurrentHashMap<>();
- public static void noteStackedIface(String stackedIface, String baseIface) {
+ /** Informs the factory of a new stacked interface. */
+ public void noteStackedIface(String stackedIface, String baseIface) {
if (stackedIface != null && baseIface != null) {
- sStackedIfaces.put(stackedIface, baseIface);
+ mStackedIfaces.put(stackedIface, baseIface);
}
}
@@ -115,13 +116,8 @@
*
* @param vpnArray The snapshot of the currently-running VPNs.
*/
- public static void updateVpnInfos(VpnInfo[] vpnArray) {
- sVpnInfos = vpnArray.clone();
- }
-
- @VisibleForTesting
- public static VpnInfo[] getVpnInfos() {
- return sVpnInfos.clone();
+ public void updateVpnInfos(VpnInfo[] vpnArray) {
+ mVpnInfos = vpnArray.clone();
}
/**
@@ -132,7 +128,7 @@
* {@link #noteStackedIface(String, String)}, but only interfaces noted before this method
* is called are guaranteed to be included.
*/
- public static String[] augmentWithStackedInterfaces(@Nullable String[] requiredIfaces) {
+ public String[] augmentWithStackedInterfaces(@Nullable String[] requiredIfaces) {
if (requiredIfaces == NetworkStats.INTERFACES_ALL) {
return null;
}
@@ -142,7 +138,7 @@
// elements as they existed upon construction exactly once, and may
// (but are not guaranteed to) reflect any modifications subsequent to construction".
// This is enough here.
- for (Map.Entry<String, String> entry : sStackedIfaces.entrySet()) {
+ for (Map.Entry<String, String> entry : mStackedIfaces.entrySet()) {
if (relatedIfaces.contains(entry.getKey())) {
relatedIfaces.add(entry.getValue());
} else if (relatedIfaces.contains(entry.getValue())) {
@@ -158,17 +154,12 @@
* Applies 464xlat adjustments with ifaces noted with {@link #noteStackedIface(String, String)}.
* @see NetworkStats#apply464xlatAdjustments(NetworkStats, NetworkStats, Map, boolean)
*/
- public static void apply464xlatAdjustments(NetworkStats baseTraffic,
+ public void apply464xlatAdjustments(NetworkStats baseTraffic,
NetworkStats stackedTraffic, boolean useBpfStats) {
- NetworkStats.apply464xlatAdjustments(baseTraffic, stackedTraffic, sStackedIfaces,
+ NetworkStats.apply464xlatAdjustments(baseTraffic, stackedTraffic, mStackedIfaces,
useBpfStats);
}
- @VisibleForTesting
- public static void clearStackedIfaces() {
- sStackedIfaces.clear();
- }
-
public NetworkStatsFactory() {
this(new File("/proc/"), new File("/sys/fs/bpf/map_netd_app_uid_stats_map").exists());
}
@@ -179,8 +170,10 @@
mStatsXtIfaceFmt = new File(procRoot, "net/xt_qtaguid/iface_stat_fmt");
mStatsXtUid = new File(procRoot, "net/xt_qtaguid/stats");
mUseBpfStats = useBpfStats;
- mPersistSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), -1);
- mTunAnd464xlatAdjustedStats = new NetworkStats(SystemClock.elapsedRealtime(), -1);
+ synchronized (mPersistentDataLock) {
+ mPersistSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), -1);
+ mTunAnd464xlatAdjustedStats = new NetworkStats(SystemClock.elapsedRealtime(), -1);
+ }
}
public NetworkStats readBpfNetworkStatsDev() throws IOException {
@@ -302,7 +295,7 @@
return readNetworkStatsDetail(UID_ALL, INTERFACES_ALL, TAG_ALL);
}
- @GuardedBy("sPersistentDataLock")
+ @GuardedBy("mPersistentDataLock")
private void requestSwapActiveStatsMapLocked() throws RemoteException {
// Ask netd to do a active map stats swap. When the binder call successfully returns,
// the system server should be able to safely read and clean the inactive map
@@ -326,9 +319,9 @@
int limitUid, String[] limitIfaces, int limitTag) throws IOException {
// In order to prevent deadlocks, anything protected by this lock MUST NOT call out to other
// code that will acquire other locks within the system server. See b/134244752.
- synchronized (sPersistentDataLock) {
+ synchronized (mPersistentDataLock) {
// Take a reference. If this gets swapped out, we still have the old reference.
- final VpnInfo[] vpnArray = sVpnInfos;
+ final VpnInfo[] vpnArray = mVpnInfos;
// Take a defensive copy. mPersistSnapshot is mutated in some cases below
final NetworkStats prev = mPersistSnapshot.clone();
@@ -377,7 +370,7 @@
}
}
- @GuardedBy("sPersistentDataLock")
+ @GuardedBy("mPersistentDataLock")
private NetworkStats adjustForTunAnd464Xlat(
NetworkStats uidDetailStats, NetworkStats previousStats, VpnInfo[] vpnArray) {
// Calculate delta from last snapshot
@@ -387,7 +380,7 @@
// network, the overhead is their fault.
// No locking here: apply464xlatAdjustments behaves fine with an add-only
// ConcurrentHashMap.
- delta.apply464xlatAdjustments(sStackedIfaces, mUseBpfStats);
+ delta.apply464xlatAdjustments(mStackedIfaces, mUseBpfStats);
// Migrate data usage over a VPN to the TUN network.
for (VpnInfo info : vpnArray) {
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 5505828..4f4377d 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -130,6 +130,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.net.VpnInfo;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FileRotator;
@@ -180,6 +181,7 @@
private final Context mContext;
private final INetworkManagementService mNetworkManager;
+ private final NetworkStatsFactory mStatsFactory;
private final AlarmManager mAlarmManager;
private final Clock mClock;
private final TelephonyManager mTeleManager;
@@ -329,8 +331,8 @@
NetworkStatsService service = new NetworkStatsService(context, networkManager, alarmManager,
wakeLock, getDefaultClock(), TelephonyManager.getDefault(),
- new DefaultNetworkStatsSettings(context), new NetworkStatsObservers(),
- getDefaultSystemDir(), getDefaultBaseDir());
+ new DefaultNetworkStatsSettings(context), new NetworkStatsFactory(),
+ new NetworkStatsObservers(), getDefaultSystemDir(), getDefaultBaseDir());
service.registerLocalService();
HandlerThread handlerThread = new HandlerThread(TAG);
@@ -347,7 +349,8 @@
NetworkStatsService(Context context, INetworkManagementService networkManager,
AlarmManager alarmManager, PowerManager.WakeLock wakeLock, Clock clock,
TelephonyManager teleManager, NetworkStatsSettings settings,
- NetworkStatsObservers statsObservers, File systemDir, File baseDir) {
+ NetworkStatsFactory factory, NetworkStatsObservers statsObservers, File systemDir,
+ File baseDir) {
mContext = checkNotNull(context, "missing Context");
mNetworkManager = checkNotNull(networkManager, "missing INetworkManagementService");
mAlarmManager = checkNotNull(alarmManager, "missing AlarmManager");
@@ -355,6 +358,7 @@
mSettings = checkNotNull(settings, "missing NetworkStatsSettings");
mTeleManager = checkNotNull(teleManager, "missing TelephonyManager");
mWakeLock = checkNotNull(wakeLock, "missing WakeLock");
+ mStatsFactory = checkNotNull(factory, "missing factory");
mStatsObservers = checkNotNull(statsObservers, "missing NetworkStatsObservers");
mSystemDir = checkNotNull(systemDir, "missing systemDir");
mBaseDir = checkNotNull(baseDir, "missing baseDir");
@@ -752,14 +756,7 @@
// TODO: switch to data layer stats once kernel exports
// for now, read network layer stats and flatten across all ifaces
- final long token = Binder.clearCallingIdentity();
- final NetworkStats networkLayer;
- try {
- networkLayer = mNetworkManager.getNetworkStatsUidDetail(uid,
- NetworkStats.INTERFACES_ALL);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
+ final NetworkStats networkLayer = readNetworkStatsUidDetail(uid, INTERFACES_ALL, TAG_ALL);
// splice in operation counts
networkLayer.spliceOperationsFrom(mUidOperations);
@@ -781,7 +778,7 @@
public NetworkStats getDetailedUidStats(String[] requiredIfaces) {
try {
final String[] ifacesToQuery =
- NetworkStatsFactory.augmentWithStackedInterfaces(requiredIfaces);
+ mStatsFactory.augmentWithStackedInterfaces(requiredIfaces);
return getNetworkStatsUidDetail(ifacesToQuery);
} catch (RemoteException e) {
Log.wtf(TAG, "Error compiling UID stats", e);
@@ -833,7 +830,8 @@
public void forceUpdateIfaces(
Network[] defaultNetworks,
NetworkState[] networkStates,
- String activeIface) {
+ String activeIface,
+ VpnInfo[] vpnInfos) {
checkNetworkStackPermission(mContext);
final long token = Binder.clearCallingIdentity();
@@ -842,6 +840,11 @@
} finally {
Binder.restoreCallingIdentity(token);
}
+
+ // Update the VPN underlying interfaces only after the poll is made and tun data has been
+ // migrated. Otherwise the migration would use the new interfaces instead of the ones that
+ // were current when the polled data was transferred.
+ mStatsFactory.updateVpnInfos(vpnInfos);
}
@Override
@@ -1190,7 +1193,7 @@
mobileIfaces.add(stackedIface);
}
- NetworkStatsFactory.noteStackedIface(stackedIface, baseIface);
+ mStatsFactory.noteStackedIface(stackedIface, baseIface);
}
}
}
@@ -1220,7 +1223,7 @@
final NetworkStats xtSnapshot = getNetworkStatsXt();
Trace.traceEnd(TRACE_TAG_NETWORK);
Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotDev");
- final NetworkStats devSnapshot = mNetworkManager.getNetworkStatsSummaryDev();
+ final NetworkStats devSnapshot = readNetworkStatsSummaryDev();
Trace.traceEnd(TRACE_TAG_NETWORK);
// Tethering snapshot for dev and xt stats. Counts per-interface data from tethering stats
@@ -1614,6 +1617,30 @@
}
}
+ private NetworkStats readNetworkStatsSummaryDev() {
+ try {
+ return mStatsFactory.readNetworkStatsSummaryDev();
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ private NetworkStats readNetworkStatsSummaryXt() {
+ try {
+ return mStatsFactory.readNetworkStatsSummaryXt();
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ private NetworkStats readNetworkStatsUidDetail(int uid, String[] ifaces, int tag) {
+ try {
+ return mStatsFactory.readNetworkStatsDetail(uid, ifaces, tag);
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
/**
* Return snapshot of current UID statistics, including any
* {@link TrafficStats#UID_TETHERING}, video calling data usage, and {@link #mUidOperations}
@@ -1624,13 +1651,12 @@
*/
private NetworkStats getNetworkStatsUidDetail(String[] ifaces)
throws RemoteException {
- final NetworkStats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL,
- ifaces);
+ final NetworkStats uidSnapshot = readNetworkStatsUidDetail(UID_ALL, ifaces, TAG_ALL);
// fold tethering stats and operations into uid snapshot
final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_UID);
tetherSnapshot.filter(UID_ALL, ifaces, TAG_ALL);
- NetworkStatsFactory.apply464xlatAdjustments(uidSnapshot, tetherSnapshot,
+ mStatsFactory.apply464xlatAdjustments(uidSnapshot, tetherSnapshot,
mUseBpfTrafficStats);
uidSnapshot.combineAllValues(tetherSnapshot);
@@ -1641,7 +1667,7 @@
final NetworkStats vtStats = telephonyManager.getVtDataUsage(STATS_PER_UID);
if (vtStats != null) {
vtStats.filter(UID_ALL, ifaces, TAG_ALL);
- NetworkStatsFactory.apply464xlatAdjustments(uidSnapshot, vtStats,
+ mStatsFactory.apply464xlatAdjustments(uidSnapshot, vtStats,
mUseBpfTrafficStats);
uidSnapshot.combineAllValues(vtStats);
}
@@ -1655,7 +1681,7 @@
* Return snapshot of current XT statistics with video calling data usage statistics.
*/
private NetworkStats getNetworkStatsXt() throws RemoteException {
- final NetworkStats xtSnapshot = mNetworkManager.getNetworkStatsSummaryXt();
+ final NetworkStats xtSnapshot = readNetworkStatsSummaryXt();
final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
Context.TELEPHONY_SERVICE);
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 6ae05ff..3ccc4a8 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -16,6 +16,28 @@
package com.android.server.pm;
+import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_DISABLED;
+
+import static com.android.server.pm.Installer.DEXOPT_BOOTCOMPLETE;
+import static com.android.server.pm.Installer.DEXOPT_DEBUGGABLE;
+import static com.android.server.pm.Installer.DEXOPT_ENABLE_HIDDEN_API_CHECKS;
+import static com.android.server.pm.Installer.DEXOPT_FORCE;
+import static com.android.server.pm.Installer.DEXOPT_GENERATE_APP_IMAGE;
+import static com.android.server.pm.Installer.DEXOPT_GENERATE_COMPACT_DEX;
+import static com.android.server.pm.Installer.DEXOPT_IDLE_BACKGROUND_JOB;
+import static com.android.server.pm.Installer.DEXOPT_PROFILE_GUIDED;
+import static com.android.server.pm.Installer.DEXOPT_PUBLIC;
+import static com.android.server.pm.Installer.DEXOPT_SECONDARY_DEX;
+import static com.android.server.pm.Installer.DEXOPT_STORAGE_CE;
+import static com.android.server.pm.Installer.DEXOPT_STORAGE_DE;
+import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
+import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
+import static com.android.server.pm.PackageManagerService.WATCHDOG_TIMEOUT;
+import static com.android.server.pm.PackageManagerServiceCompilerMapping.getReasonName;
+
+import static dalvik.system.DexFile.getSafeModeCompilerFilter;
+import static dalvik.system.DexFile.isProfileGuidedCompilerFilter;
+
import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -25,12 +47,10 @@
import android.content.pm.dex.DexMetadataHelper;
import android.os.FileUtils;
import android.os.PowerManager;
-import android.os.Process;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.WorkSource;
-import android.os.storage.StorageManager;
import android.util.Log;
import android.util.Slog;
@@ -43,6 +63,8 @@
import com.android.server.pm.dex.DexoptUtils;
import com.android.server.pm.dex.PackageDexUsage;
+import dalvik.system.DexFile;
+
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
@@ -50,32 +72,6 @@
import java.util.List;
import java.util.Map;
-import dalvik.system.DexFile;
-
-import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_DISABLED;
-
-import static com.android.server.pm.Installer.DEXOPT_BOOTCOMPLETE;
-import static com.android.server.pm.Installer.DEXOPT_DEBUGGABLE;
-import static com.android.server.pm.Installer.DEXOPT_PROFILE_GUIDED;
-import static com.android.server.pm.Installer.DEXOPT_PUBLIC;
-import static com.android.server.pm.Installer.DEXOPT_SECONDARY_DEX;
-import static com.android.server.pm.Installer.DEXOPT_FORCE;
-import static com.android.server.pm.Installer.DEXOPT_STORAGE_CE;
-import static com.android.server.pm.Installer.DEXOPT_STORAGE_DE;
-import static com.android.server.pm.Installer.DEXOPT_IDLE_BACKGROUND_JOB;
-import static com.android.server.pm.Installer.DEXOPT_ENABLE_HIDDEN_API_CHECKS;
-import static com.android.server.pm.Installer.DEXOPT_GENERATE_COMPACT_DEX;
-import static com.android.server.pm.Installer.DEXOPT_GENERATE_APP_IMAGE;
-import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
-import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
-
-import static com.android.server.pm.PackageManagerService.WATCHDOG_TIMEOUT;
-
-import static com.android.server.pm.PackageManagerServiceCompilerMapping.getReasonName;
-
-import static dalvik.system.DexFile.getSafeModeCompilerFilter;
-import static dalvik.system.DexFile.isProfileGuidedCompilerFilter;
-
/**
* Helper class for running dexopt command on packages.
*/
@@ -271,10 +267,7 @@
return DEX_OPT_SKIPPED;
}
- // TODO(calin): there's no need to try to create the oat dir over and over again,
- // especially since it involve an extra installd call. We should create
- // if (if supported) on the fly during the dexopt call.
- String oatDir = createOatDirIfSupported(pkg, isa);
+ String oatDir = getPackageOatDirIfSupported(pkg);
Log.i(TAG, "Running dexopt (dexoptNeeded=" + dexoptNeeded + ") on: " + path
+ " pkg=" + pkg.applicationInfo.packageName + " isa=" + isa
@@ -639,7 +632,7 @@
}
/**
- * Creates oat dir for the specified package if needed and supported.
+ * Gets oat dir for the specified package if needed and supported.
* In certain cases oat directory
* <strong>cannot</strong> be created:
* <ul>
@@ -647,29 +640,19 @@
* <li>Package location is not a directory, i.e. monolithic install.</li>
* </ul>
*
- * @return Absolute path to the oat directory or null, if oat directory
- * cannot be created.
+ * @return Absolute path to the oat directory or null, if oat directories
+ * not needed or unsupported for the package.
*/
@Nullable
- private String createOatDirIfSupported(PackageParser.Package pkg, String dexInstructionSet) {
+ private String getPackageOatDirIfSupported(PackageParser.Package pkg) {
if (!pkg.canHaveOatDir()) {
return null;
}
File codePath = new File(pkg.codePath);
- if (codePath.isDirectory()) {
- // TODO(calin): why do we create this only if the codePath is a directory? (i.e for
- // cluster packages). It seems that the logic for the folder creation is
- // split between installd and here.
- File oatDir = getOatDir(codePath);
- try {
- mInstaller.createOatDir(oatDir.getAbsolutePath(), dexInstructionSet);
- } catch (InstallerException e) {
- Slog.w(TAG, "Failed to create oat dir", e);
- return null;
- }
- return oatDir.getAbsolutePath();
+ if (!codePath.isDirectory()) {
+ return null;
}
- return null;
+ return getOatDir(codePath).getAbsolutePath();
}
static File getOatDir(File codePath) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 0149d30..caf0b92 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -6482,7 +6482,7 @@
case KeyEvent.KEYCODE_VOLUME_MUTE:
return mDockMode != Intent.EXTRA_DOCK_STATE_UNDOCKED;
- // ignore media and camera keys
+ // ignore media keys
case KeyEvent.KEYCODE_MUTE:
case KeyEvent.KEYCODE_HEADSETHOOK:
case KeyEvent.KEYCODE_MEDIA_PLAY:
@@ -6495,7 +6495,6 @@
case KeyEvent.KEYCODE_MEDIA_RECORD:
case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK:
- case KeyEvent.KEYCODE_CAMERA:
return false;
}
return true;
diff --git a/startop/apps/test/Android.bp b/startop/apps/test/Android.bp
index 3adc05e..7a1678a 100644
--- a/startop/apps/test/Android.bp
+++ b/startop/apps/test/Android.bp
@@ -18,6 +18,9 @@
name: "startop_test_app",
srcs: [
"src/EmptyActivity.java",
- "src/LayoutInflation.java",
+ "src/LayoutInflationActivity.java",
+ "src/ComplexLayoutInflationActivity.java",
+ "src/FrameLayoutInflationActivity.java",
+ "src/TextViewInflationActivity.java",
],
}
diff --git a/startop/apps/test/AndroidManifest.xml b/startop/apps/test/AndroidManifest.xml
index 6b08118..467d8f7 100644
--- a/startop/apps/test/AndroidManifest.xml
+++ b/startop/apps/test/AndroidManifest.xml
@@ -23,7 +23,12 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true">
- <activity android:name=".EmptyActivity">
+
+ <activity
+ android:label="Complex Layout Test"
+ android:name=".ComplexLayoutInflationActivity"
+ android:exported="true" >
+
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@@ -31,7 +36,41 @@
</intent-filter>
</activity>
- <activity android:name=".LayoutInflation" android:exported="true" />
+ <activity
+ android:label="Empty Activity Layout Test"
+ android:name=".EmptyActivity"
+ android:exported="true" >
+
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity
+ android:label="FrameLayout Layout Test"
+ android:name=".FrameLayoutInflationActivity"
+ android:exported="true" >
+
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity
+ android:label="TextView Layout Test"
+ android:name=".TextViewInflationActivity"
+ android:exported="true" >
+
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
</application>
</manifest>
diff --git a/startop/apps/test/README.md b/startop/apps/test/README.md
index 53c184b..dadc66a 100644
--- a/startop/apps/test/README.md
+++ b/startop/apps/test/README.md
@@ -23,4 +23,4 @@
spent in view inflation to make it easier to focus on the time spent in view
inflation.
- adb shell am start -n com.android.startop.test/.LayoutInflation
+ adb shell am start -n com.android.startop.test/.ComplexLayoutInflationActivity
diff --git a/startop/apps/test/res/layout/framelayout_list.xml b/startop/apps/test/res/layout/framelayout_list.xml
new file mode 100644
index 0000000..2dd8219
--- /dev/null
+++ b/startop/apps/test/res/layout/framelayout_list.xml
@@ -0,0 +1,5013 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ffaaaaaa" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:background="#ff000000" />
+ </LinearLayout>
+</ScrollView>
diff --git a/startop/apps/test/res/layout/textview_list.xml b/startop/apps/test/res/layout/textview_list.xml
new file mode 100644
index 0000000..1cff5b2
--- /dev/null
+++ b/startop/apps/test/res/layout/textview_list.xml
@@ -0,0 +1,5014 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ </LinearLayout>
+</ScrollView>
diff --git a/startop/apps/test/src/ComplexLayoutInflationActivity.java b/startop/apps/test/src/ComplexLayoutInflationActivity.java
new file mode 100644
index 0000000..a357073
--- /dev/null
+++ b/startop/apps/test/src/ComplexLayoutInflationActivity.java
@@ -0,0 +1,34 @@
+/*
+ * 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.android.startop.test;
+
+import android.os.Bundle;
+
+/**
+ * This activity inflates a reasonably complex layout to see the impact of
+ * layout inflation. The layout is supported by the viewcompiler, so this can be
+ * used for testing precompiled layout performance.
+ */
+public class ComplexLayoutInflationActivity extends LayoutInflationActivity {
+ protected void onCreate(Bundle savedInstanceState) {
+ Bundle newState = savedInstanceState == null
+ ? new Bundle() : new Bundle(savedInstanceState);
+ newState.putInt(LAYOUT_ID, R.layout.activity_main);
+
+ super.onCreate(newState);
+ }
+}
diff --git a/startop/apps/test/src/EmptyActivity.java b/startop/apps/test/src/EmptyActivity.java
index 5202938..bcb2e70 100644
--- a/startop/apps/test/src/EmptyActivity.java
+++ b/startop/apps/test/src/EmptyActivity.java
@@ -1,18 +1,18 @@
-//
-// 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.
-//
+/*
+ * 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.android.startop.test;
diff --git a/startop/apps/test/src/FrameLayoutInflationActivity.java b/startop/apps/test/src/FrameLayoutInflationActivity.java
new file mode 100644
index 0000000..b995e79
--- /dev/null
+++ b/startop/apps/test/src/FrameLayoutInflationActivity.java
@@ -0,0 +1,29 @@
+/*
+ * 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.android.startop.test;
+
+import android.os.Bundle;
+
+public class FrameLayoutInflationActivity extends LayoutInflationActivity {
+ protected void onCreate(Bundle savedInstanceState) {
+ Bundle newState = savedInstanceState == null
+ ? new Bundle() : new Bundle(savedInstanceState);
+ newState.putInt(LAYOUT_ID, R.layout.framelayout_list);
+
+ super.onCreate(newState);
+ }
+}
diff --git a/startop/apps/test/src/LayoutInflation.java b/startop/apps/test/src/LayoutInflation.java
deleted file mode 100644
index daa4e45..0000000
--- a/startop/apps/test/src/LayoutInflation.java
+++ /dev/null
@@ -1,39 +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.android.startop.test;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.os.Trace;
-import android.view.LayoutInflater;
-import android.view.View;
-
-/**
- * This activity inflates a reasonably complex layout to see the impact of
- * layout inflation. The layout is supported by the viewcompiler, so this can be
- * used for testing precompiled layout performance.
- */
-public class LayoutInflation extends Activity {
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- LayoutInflater inflater = LayoutInflater.from(this);
- Trace.beginSection("inflate layout:activity_main");
- View view = inflater.inflate(R.layout.activity_main, /*root=*/null);
- Trace.endSection();
- setContentView(view);
- }
-}
diff --git a/startop/apps/test/src/LayoutInflationActivity.java b/startop/apps/test/src/LayoutInflationActivity.java
new file mode 100644
index 0000000..06a0570
--- /dev/null
+++ b/startop/apps/test/src/LayoutInflationActivity.java
@@ -0,0 +1,39 @@
+/*
+ * 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.android.startop.test;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Trace;
+import android.view.LayoutInflater;
+import android.view.View;
+
+public class LayoutInflationActivity extends Activity {
+ public static String LAYOUT_ID = "layout-id";
+
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ int layoutId = savedInstanceState.getInt(LAYOUT_ID);
+ String layoutName = getResources().getResourceEntryName(layoutId);
+
+ LayoutInflater inflater = LayoutInflater.from(this);
+ Trace.beginSection("inflate layout: " + layoutName);
+ View view = inflater.inflate(layoutId, /*root=*/null);
+ Trace.endSection();
+ setContentView(view);
+ }
+}
diff --git a/startop/apps/test/src/TextViewInflationActivity.java b/startop/apps/test/src/TextViewInflationActivity.java
new file mode 100644
index 0000000..30e308e
--- /dev/null
+++ b/startop/apps/test/src/TextViewInflationActivity.java
@@ -0,0 +1,29 @@
+/*
+ * 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.android.startop.test;
+
+import android.os.Bundle;
+
+public class TextViewInflationActivity extends LayoutInflationActivity {
+ protected void onCreate(Bundle savedInstanceState) {
+ Bundle newState = savedInstanceState == null
+ ? new Bundle() : new Bundle(savedInstanceState);
+ newState.putInt(LAYOUT_ID, R.layout.textview_list);
+
+ super.onCreate(newState);
+ }
+}
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 63e3801..d4ea29f 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -16,9 +16,11 @@
package android.telephony;
+import android.annotation.IntDef;
import android.annotation.RequiresPermission;
import android.annotation.SuppressAutoDoc;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.app.ActivityThread;
import android.app.PendingIntent;
@@ -43,6 +45,8 @@
import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.SmsRawData;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -2798,4 +2802,85 @@
config.getBoolean(MMS_CONFIG_SUPPORT_HTTP_CHARSET_HEADER));
return filtered;
}
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"SMS_CATEGORY_"},
+ value = {
+ SmsManager.SMS_CATEGORY_NOT_SHORT_CODE,
+ SmsManager.SMS_CATEGORY_FREE_SHORT_CODE,
+ SmsManager.SMS_CATEGORY_STANDARD_SHORT_CODE,
+ SmsManager.SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE,
+ SmsManager.SMS_CATEGORY_PREMIUM_SHORT_CODE})
+ public @interface SmsShortCodeCategory {}
+
+ /**
+ * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for regular
+ * phone numbers.
+ * @hide
+ */
+ @TestApi
+ public static final int SMS_CATEGORY_NOT_SHORT_CODE = 0;
+ /**
+ * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for free
+ * (no cost) short codes.
+ * @hide
+ */
+ @TestApi
+ public static final int SMS_CATEGORY_FREE_SHORT_CODE = 1;
+ /**
+ * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for
+ * standard rate (non-premium)
+ * short codes.
+ * @hide
+ */
+ @TestApi
+ public static final int SMS_CATEGORY_STANDARD_SHORT_CODE = 2;
+ /**
+ * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for possible
+ * premium short codes.
+ * @hide
+ */
+ @TestApi
+ public static final int SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3;
+ /**
+ * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for
+ * premium short codes.
+ * @hide
+ */
+ @TestApi
+ public static final int SMS_CATEGORY_PREMIUM_SHORT_CODE = 4;
+
+ /**
+ * Check if the destination address is a possible premium short code.
+ * NOTE: the caller is expected to strip non-digits from the destination number with
+ * {@link PhoneNumberUtils#extractNetworkPortion} before calling this method.
+ *
+ * @param destAddress the destination address to test for possible short code
+ * @param countryIso the ISO country code
+ *
+ * @return
+ * {@link SmsManager#SMS_CATEGORY_NOT_SHORT_CODE},
+ * {@link SmsManager#SMS_CATEGORY_FREE_SHORT_CODE},
+ * {@link SmsManager#SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE},
+ * {@link SmsManager#SMS_CATEGORY_PREMIUM_SHORT_CODE}, or
+ * {@link SmsManager#SMS_CATEGORY_STANDARD_SHORT_CODE}
+ *
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+ @TestApi
+ public @SmsShortCodeCategory int checkSmsShortCodeDestination(
+ String destAddress, String countryIso) {
+ try {
+ ISms iccISms = getISmsServiceOrThrow();
+ if (iccISms != null) {
+ return iccISms.checkSmsShortCodeDestination(getSubscriptionId(),
+ ActivityThread.currentPackageName(), destAddress, countryIso);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "checkSmsShortCodeDestination() RemoteException", e);
+ }
+ return SmsManager.SMS_CATEGORY_NOT_SHORT_CODE;
+ }
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index a88434d..03a5c74 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -4777,8 +4777,7 @@
ITelephony telephony = getITelephony();
if (telephony == null)
return DATA_ACTIVITY_NONE;
- return telephony.getDataActivity(
- getSubId(SubscriptionManager.getActiveDataSubscriptionId()));
+ return telephony.getDataActivity();
} catch (RemoteException ex) {
// the phone process is restarting.
return DATA_ACTIVITY_NONE;
@@ -4826,8 +4825,7 @@
ITelephony telephony = getITelephony();
if (telephony == null)
return DATA_DISCONNECTED;
- return telephony.getDataState(
- getSubId(SubscriptionManager.getActiveDataSubscriptionId()));
+ return telephony.getDataState();
} catch (RemoteException ex) {
// the phone process is restarting.
return DATA_DISCONNECTED;
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index c3dcc3d..87aff8a 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -551,4 +551,11 @@
* @param intent PendingIntent to be sent when an SMS is received containing the token.
*/
String createAppSpecificSmsToken(int subId, String callingPkg, in PendingIntent intent);
+
+ /**
+ * Check if the destination is a possible premium short code.
+ *
+ * @param destAddress the destination address to test for possible short code
+ */
+ int checkSmsShortCodeDestination(int subId, String callingApk, String destAddress, String countryIso);
}
diff --git a/telephony/java/com/android/internal/telephony/ISmsImplBase.java b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
index 1cdf44d..194f461 100644
--- a/telephony/java/com/android/internal/telephony/ISmsImplBase.java
+++ b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
@@ -188,4 +188,10 @@
public String createAppSpecificSmsToken(int subId, String callingPkg, PendingIntent intent) {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public int checkSmsShortCodeDestination(
+ int subid, String callingApk, String destAddress, String countryIso) {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 4de1917..1aba95b 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -308,36 +308,18 @@
*/
List<NeighboringCellInfo> getNeighboringCellInfo(String callingPkg);
- @UnsupportedAppUsage
- int getCallState();
+ @UnsupportedAppUsage
+ int getCallState();
/**
* Returns the call state for a slot.
*/
int getCallStateForSlot(int slotIndex);
- /**
- * Returns a constant indicating the type of activity on a data connection
- * (cellular).
- *
- * @see #DATA_ACTIVITY_NONE
- * @see #DATA_ACTIVITY_IN
- * @see #DATA_ACTIVITY_OUT
- * @see #DATA_ACTIVITY_INOUT
- * @see #DATA_ACTIVITY_DORMANT
- */
- int getDataActivity(int subId);
-
- /**
- * Returns a constant indicating the current data connection state
- * (cellular).
- *
- * @see #DATA_DISCONNECTED
- * @see #DATA_CONNECTING
- * @see #DATA_CONNECTED
- * @see #DATA_SUSPENDED
- */
- int getDataState(int subId);
+ @UnsupportedAppUsage
+ int getDataActivity();
+ @UnsupportedAppUsage
+ int getDataState();
/**
* Returns the current active phone type as integer.
diff --git a/tests/HwAccelerationTest/res/drawable-nodpi/very_large_photo.jpg b/tests/HwAccelerationTest/res/drawable-nodpi/very_large_photo.jpg
index 7f047b1..6e1a866 100644
--- a/tests/HwAccelerationTest/res/drawable-nodpi/very_large_photo.jpg
+++ b/tests/HwAccelerationTest/res/drawable-nodpi/very_large_photo.jpg
Binary files differ
diff --git a/tests/UiBench/res/drawable-nodpi/frantic.jpg b/tests/UiBench/res/drawable-nodpi/frantic.jpg
index 4c62333..856b419 100644
--- a/tests/UiBench/res/drawable-nodpi/frantic.jpg
+++ b/tests/UiBench/res/drawable-nodpi/frantic.jpg
Binary files differ
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 7317d62..7dd2bbf 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -18,6 +18,7 @@
import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static android.content.pm.PackageManager.MATCH_ANY_USER;
+import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.NETID_UNSET;
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
@@ -70,6 +71,7 @@
import static com.android.testutils.ConcurrentUtilsKt.await;
import static com.android.testutils.ConcurrentUtilsKt.durationOf;
+import static com.android.testutils.ExceptionUtils.ignoreExceptions;
import static com.android.testutils.HandlerUtilsKt.waitForIdleSerialExecutor;
import static com.android.testutils.MiscAssertsKt.assertContainsExactly;
import static com.android.testutils.MiscAssertsKt.assertEmpty;
@@ -84,13 +86,13 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -145,6 +147,7 @@
import android.net.NetworkMisc;
import android.net.NetworkRequest;
import android.net.NetworkSpecifier;
+import android.net.NetworkStack;
import android.net.NetworkStackClient;
import android.net.NetworkState;
import android.net.NetworkUtils;
@@ -157,7 +160,9 @@
import android.net.shared.NetworkMonitorUtils;
import android.net.shared.PrivateDnsConfig;
import android.net.util.MultinetworkPolicyTracker;
+import android.os.BadParcelableException;
import android.os.Binder;
+import android.os.Bundle;
import android.os.ConditionVariable;
import android.os.Handler;
import android.os.HandlerThread;
@@ -195,14 +200,14 @@
import com.android.server.connectivity.IpConnectivityMetrics;
import com.android.server.connectivity.MockableSystemProperties;
import com.android.server.connectivity.Nat464Xlat;
+import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
import com.android.server.connectivity.ProxyTracker;
import com.android.server.connectivity.Tethering;
import com.android.server.connectivity.Vpn;
import com.android.server.net.NetworkPinner;
import com.android.server.net.NetworkPolicyManagerInternal;
-import com.android.server.net.NetworkStatsFactory;
+import com.android.testutils.ExceptionUtils;
import com.android.testutils.HandlerUtilsKt;
-import com.android.testutils.ThrowingConsumer;
import org.junit.After;
import org.junit.Before;
@@ -223,7 +228,6 @@
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
-import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -289,6 +293,7 @@
@Mock NetworkStackClient mNetworkStack;
@Mock PackageManager mPackageManager;
@Mock UserManager mUserManager;
+ @Mock NotificationManager mNotificationManager;
private ArgumentCaptor<ResolverParamsParcel> mResolverParamsParcelCaptor =
ArgumentCaptor.forClass(ResolverParamsParcel.class);
@@ -358,7 +363,7 @@
@Override
public Object getSystemService(String name) {
if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm;
- if (Context.NOTIFICATION_SERVICE.equals(name)) return mock(NotificationManager.class);
+ if (Context.NOTIFICATION_SERVICE.equals(name)) return mNotificationManager;
if (Context.NETWORK_STACK_SERVICE.equals(name)) return mNetworkStack;
if (Context.USER_SERVICE.equals(name)) return mUserManager;
return super.getSystemService(name);
@@ -378,7 +383,17 @@
public PackageManager getPackageManager() {
return mPackageManager;
}
- }
+
+ @Override
+ public void enforceCallingOrSelfPermission(String permission, String message) {
+ // The mainline permission can only be held if signed with the network stack certificate
+ // Skip testing for this permission.
+ if (NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK.equals(permission)) return;
+ // All other permissions should be held by the test or unnecessary: check as normal to
+ // make sure the code does not rely on unexpected permissions.
+ super.enforceCallingOrSelfPermission(permission, message);
+ }
+ }
public void waitForIdle(int timeoutMsAsInt) {
long timeoutMs = timeoutMsAsInt;
@@ -402,7 +417,7 @@
}
@Test
- public void testWaitForIdle() {
+ public void testWaitForIdle() throws Exception {
final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng.
// Tests that waitForIdle returns immediately if the service is already idle.
@@ -429,7 +444,7 @@
// This test has an inherent race condition in it, and cannot be enabled for continuous testing
// or presubmit tests. It is kept for manual runs and documentation purposes.
@Ignore
- public void verifyThatNotWaitingForIdleCausesRaceConditions() {
+ public void verifyThatNotWaitingForIdleCausesRaceConditions() throws Exception {
// Bring up a network that we can use to send messages to ConnectivityService.
ConditionVariable cv = waitForConnectivityBroadcasts(1);
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
@@ -509,11 +524,11 @@
mNmValidationRedirectUrl = null;
}
- MockNetworkAgent(int transport) {
+ MockNetworkAgent(int transport) throws Exception {
this(transport, new LinkProperties());
}
- MockNetworkAgent(int transport, LinkProperties linkProperties) {
+ MockNetworkAgent(int transport, LinkProperties linkProperties) throws Exception {
final int type = transportToLegacyType(transport);
final String typeName = ConnectivityManager.getNetworkTypeName(type);
mNetworkInfo = new NetworkInfo(type, 0, typeName, "Mock");
@@ -544,16 +559,12 @@
mNetworkMonitor = mock(INetworkMonitor.class);
final Answer validateAnswer = inv -> {
- new Thread(this::onValidationRequested).start();
+ new Thread(ignoreExceptions(this::onValidationRequested)).start();
return null;
};
- try {
- doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnected(any(), any());
- doAnswer(validateAnswer).when(mNetworkMonitor).forceReevaluation(anyInt());
- } catch (RemoteException e) {
- fail(e.getMessage());
- }
+ doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnected(any(), any());
+ doAnswer(validateAnswer).when(mNetworkMonitor).forceReevaluation(anyInt());
final ArgumentCaptor<Network> nmNetworkCaptor = ArgumentCaptor.forClass(Network.class);
final ArgumentCaptor<INetworkMonitorCallbacks> nmCbCaptor =
@@ -608,35 +619,27 @@
assertEquals(mNetworkAgent.netId, nmNetworkCaptor.getValue().netId);
mNmCallbacks = nmCbCaptor.getValue();
- try {
- mNmCallbacks.onNetworkMonitorCreated(mNetworkMonitor);
- } catch (RemoteException e) {
- fail(e.getMessage());
- }
+ mNmCallbacks.onNetworkMonitorCreated(mNetworkMonitor);
// Waits for the NetworkAgent to be registered, which includes the creation of the
// NetworkMonitor.
waitForIdle();
}
- private void onValidationRequested() {
- try {
- if (mNmProvNotificationRequested
- && ((mNmValidationResult & NETWORK_VALIDATION_RESULT_VALID) != 0)) {
- mNmCallbacks.hideProvisioningNotification();
- mNmProvNotificationRequested = false;
- }
+ private void onValidationRequested() throws Exception {
+ if (mNmProvNotificationRequested
+ && ((mNmValidationResult & NETWORK_VALIDATION_RESULT_VALID) != 0)) {
+ mNmCallbacks.hideProvisioningNotification();
+ mNmProvNotificationRequested = false;
+ }
- mNmCallbacks.notifyNetworkTested(
- mNmValidationResult, mNmValidationRedirectUrl);
+ mNmCallbacks.notifyNetworkTested(
+ mNmValidationResult, mNmValidationRedirectUrl);
- if (mNmValidationRedirectUrl != null) {
- mNmCallbacks.showProvisioningNotification(
- "test_provisioning_notif_action", "com.android.test.package");
- mNmProvNotificationRequested = true;
- }
- } catch (RemoteException e) {
- fail(e.getMessage());
+ if (mNmValidationRedirectUrl != null) {
+ mNmCallbacks.showProvisioningNotification(
+ "test_provisioning_notif_action", "com.android.test.package");
+ mNmProvNotificationRequested = true;
}
}
@@ -1234,18 +1237,13 @@
waitForIdle(TIMEOUT_MS);
}
- public void setUidRulesChanged(int uidRules) {
- try {
- mPolicyListener.onUidRulesChanged(Process.myUid(), uidRules);
- } catch (RemoteException ignored) {
- }
+ public void setUidRulesChanged(int uidRules) throws RemoteException {
+ mPolicyListener.onUidRulesChanged(Process.myUid(), uidRules);
}
- public void setRestrictBackgroundChanged(boolean restrictBackground) {
- try {
- mPolicyListener.onRestrictBackgroundChanged(restrictBackground);
- } catch (RemoteException ignored) {
- }
+ public void setRestrictBackgroundChanged(boolean restrictBackground)
+ throws RemoteException {
+ mPolicyListener.onRestrictBackgroundChanged(restrictBackground);
}
}
@@ -1800,12 +1798,9 @@
return mLastAvailableNetwork;
}
- CallbackInfo nextCallback(int timeoutMs) {
+ CallbackInfo nextCallback(int timeoutMs) throws InterruptedException {
CallbackInfo cb = null;
- try {
- cb = mCallbacks.poll(timeoutMs, TimeUnit.MILLISECONDS);
- } catch (InterruptedException e) {
- }
+ cb = mCallbacks.poll(timeoutMs, TimeUnit.MILLISECONDS);
if (cb == null) {
// LinkedBlockingQueue.poll() returns null if it timeouts.
fail("Did not receive callback after " + timeoutMs + "ms");
@@ -1813,7 +1808,8 @@
return cb;
}
- CallbackInfo expectCallback(CallbackState state, MockNetworkAgent agent, int timeoutMs) {
+ CallbackInfo expectCallback(CallbackState state, MockNetworkAgent agent, int timeoutMs)
+ throws Exception {
final Network expectedNetwork = (agent != null) ? agent.getNetwork() : null;
CallbackInfo expected = new CallbackInfo(state, expectedNetwork, 0);
CallbackInfo actual = nextCallback(timeoutMs);
@@ -1830,15 +1826,16 @@
return actual;
}
- CallbackInfo expectCallback(CallbackState state, MockNetworkAgent agent) {
+ CallbackInfo expectCallback(CallbackState state, MockNetworkAgent agent) throws Exception {
return expectCallback(state, agent, TEST_CALLBACK_TIMEOUT_MS);
}
- CallbackInfo expectCallbackLike(Predicate<CallbackInfo> fn) {
+ CallbackInfo expectCallbackLike(Predicate<CallbackInfo> fn) throws Exception {
return expectCallbackLike(fn, TEST_CALLBACK_TIMEOUT_MS);
}
- CallbackInfo expectCallbackLike(Predicate<CallbackInfo> fn, int timeoutMs) {
+ CallbackInfo expectCallbackLike(Predicate<CallbackInfo> fn, int timeoutMs)
+ throws Exception {
int timeLeft = timeoutMs;
while (timeLeft > 0) {
long start = SystemClock.elapsedRealtime();
@@ -1864,7 +1861,7 @@
// onCapabilitiesChanged callback.
// @param timeoutMs how long to wait for the callbacks.
void expectAvailableCallbacks(MockNetworkAgent agent, boolean expectSuspended,
- boolean expectValidated, boolean expectBlocked, int timeoutMs) {
+ boolean expectValidated, boolean expectBlocked, int timeoutMs) throws Exception {
expectCallback(CallbackState.AVAILABLE, agent, timeoutMs);
if (expectSuspended) {
expectCallback(CallbackState.SUSPENDED, agent, timeoutMs);
@@ -1879,23 +1876,26 @@
}
// Expects the available callbacks (validated), plus onSuspended.
- void expectAvailableAndSuspendedCallbacks(MockNetworkAgent agent, boolean expectValidated) {
+ void expectAvailableAndSuspendedCallbacks(MockNetworkAgent agent, boolean expectValidated)
+ throws Exception {
expectAvailableCallbacks(agent, true, expectValidated, false, TEST_CALLBACK_TIMEOUT_MS);
}
- void expectAvailableCallbacksValidated(MockNetworkAgent agent) {
+ void expectAvailableCallbacksValidated(MockNetworkAgent agent)
+ throws Exception {
expectAvailableCallbacks(agent, false, true, false, TEST_CALLBACK_TIMEOUT_MS);
}
- void expectAvailableCallbacksValidatedAndBlocked(MockNetworkAgent agent) {
+ void expectAvailableCallbacksValidatedAndBlocked(MockNetworkAgent agent) throws Exception {
expectAvailableCallbacks(agent, false, true, true, TEST_CALLBACK_TIMEOUT_MS);
}
- void expectAvailableCallbacksUnvalidated(MockNetworkAgent agent) {
+ void expectAvailableCallbacksUnvalidated(MockNetworkAgent agent) throws Exception {
expectAvailableCallbacks(agent, false, false, false, TEST_CALLBACK_TIMEOUT_MS);
}
- void expectAvailableCallbacksUnvalidatedAndBlocked(MockNetworkAgent agent) {
+ void expectAvailableCallbacksUnvalidatedAndBlocked(MockNetworkAgent agent)
+ throws Exception {
expectAvailableCallbacks(agent, false, false, true, TEST_CALLBACK_TIMEOUT_MS);
}
@@ -1903,7 +1903,7 @@
// VALIDATED capability), plus another onCapabilitiesChanged which is identical to the
// one we just sent.
// TODO: this is likely a bug. Fix it and remove this method.
- void expectAvailableDoubleValidatedCallbacks(MockNetworkAgent agent) {
+ void expectAvailableDoubleValidatedCallbacks(MockNetworkAgent agent) throws Exception {
expectCallback(CallbackState.AVAILABLE, agent, TEST_CALLBACK_TIMEOUT_MS);
NetworkCapabilities nc1 = expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, agent);
expectCallback(CallbackState.LINK_PROPERTIES, agent, TEST_CALLBACK_TIMEOUT_MS);
@@ -1917,48 +1917,53 @@
// Expects the available callbacks where the onCapabilitiesChanged must not have validated,
// then expects another onCapabilitiesChanged that has the validated bit set. This is used
// when a network connects and satisfies a callback, and then immediately validates.
- void expectAvailableThenValidatedCallbacks(MockNetworkAgent agent) {
+ void expectAvailableThenValidatedCallbacks(MockNetworkAgent agent) throws Exception {
expectAvailableCallbacksUnvalidated(agent);
expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, agent);
}
- NetworkCapabilities expectCapabilitiesWith(int capability, MockNetworkAgent agent) {
+ NetworkCapabilities expectCapabilitiesWith(int capability, MockNetworkAgent agent)
+ throws Exception {
return expectCapabilitiesWith(capability, agent, TEST_CALLBACK_TIMEOUT_MS);
}
NetworkCapabilities expectCapabilitiesWith(int capability, MockNetworkAgent agent,
- int timeoutMs) {
+ int timeoutMs) throws Exception {
CallbackInfo cbi = expectCallback(CallbackState.NETWORK_CAPABILITIES, agent, timeoutMs);
NetworkCapabilities nc = (NetworkCapabilities) cbi.arg;
assertTrue(nc.hasCapability(capability));
return nc;
}
- NetworkCapabilities expectCapabilitiesWithout(int capability, MockNetworkAgent agent) {
+ NetworkCapabilities expectCapabilitiesWithout(int capability, MockNetworkAgent agent)
+ throws Exception {
return expectCapabilitiesWithout(capability, agent, TEST_CALLBACK_TIMEOUT_MS);
}
NetworkCapabilities expectCapabilitiesWithout(int capability, MockNetworkAgent agent,
- int timeoutMs) {
+ int timeoutMs) throws Exception {
CallbackInfo cbi = expectCallback(CallbackState.NETWORK_CAPABILITIES, agent, timeoutMs);
NetworkCapabilities nc = (NetworkCapabilities) cbi.arg;
assertFalse(nc.hasCapability(capability));
return nc;
}
- void expectCapabilitiesLike(Predicate<NetworkCapabilities> fn, MockNetworkAgent agent) {
+ void expectCapabilitiesLike(Predicate<NetworkCapabilities> fn, MockNetworkAgent agent)
+ throws Exception {
CallbackInfo cbi = expectCallback(CallbackState.NETWORK_CAPABILITIES, agent);
assertTrue("Received capabilities don't match expectations : " + cbi.arg,
fn.test((NetworkCapabilities) cbi.arg));
}
- void expectLinkPropertiesLike(Predicate<LinkProperties> fn, MockNetworkAgent agent) {
+ void expectLinkPropertiesLike(Predicate<LinkProperties> fn, MockNetworkAgent agent)
+ throws Exception {
CallbackInfo cbi = expectCallback(CallbackState.LINK_PROPERTIES, agent);
assertTrue("Received LinkProperties don't match expectations : " + cbi.arg,
fn.test((LinkProperties) cbi.arg));
}
- void expectBlockedStatusCallback(boolean expectBlocked, MockNetworkAgent agent) {
+ void expectBlockedStatusCallback(boolean expectBlocked, MockNetworkAgent agent)
+ throws Exception {
CallbackInfo cbi = expectCallback(CallbackState.BLOCKED_STATUS, agent);
boolean actualBlocked = (boolean) cbi.arg;
assertEquals(expectBlocked, actualBlocked);
@@ -2070,7 +2075,7 @@
}
@Test
- public void testMultipleLingering() {
+ public void testMultipleLingering() throws Exception {
// This test would be flaky with the default 120ms timer: that is short enough that
// lingered networks are torn down before assertions can be run. We don't want to mock the
// lingering timer to keep the WakeupMessage logic realistic: this has already proven useful
@@ -2325,7 +2330,7 @@
}
@Test
- public void testNetworkGoesIntoBackgroundAfterLinger() {
+ public void testNetworkGoesIntoBackgroundAfterLinger() throws Exception {
setAlwaysOnNetworks(true);
NetworkRequest request = new NetworkRequest.Builder()
.clearCapabilities()
@@ -2370,7 +2375,7 @@
}
@Test
- public void testExplicitlySelected() {
+ public void testExplicitlySelected() throws Exception {
NetworkRequest request = new NetworkRequest.Builder()
.clearCapabilities().addCapability(NET_CAPABILITY_INTERNET)
.build();
@@ -2651,7 +2656,7 @@
}
@Test
- public void testPartialConnectivity() {
+ public void testPartialConnectivity() throws Exception {
// Register network callback.
NetworkRequest request = new NetworkRequest.Builder()
.clearCapabilities().addCapability(NET_CAPABILITY_INTERNET)
@@ -2684,11 +2689,7 @@
// If user accepts partial connectivity network,
// NetworkMonitor#setAcceptPartialConnectivity() should be called too.
waitForIdle();
- try {
- verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
- } catch (RemoteException e) {
- fail(e.getMessage());
- }
+ verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
// Need a trigger point to let NetworkMonitor tell ConnectivityService that network is
// validated.
mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
@@ -2725,11 +2726,7 @@
// NetworkMonitor#setAcceptPartialConnectivity() will be called in
// ConnectivityService#updateNetworkInfo().
waitForIdle();
- try {
- verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
- } catch (RemoteException e) {
- fail(e.getMessage());
- }
+ verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
nc = callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
@@ -2753,11 +2750,7 @@
// NetworkMonitor#setAcceptPartialConnectivity() will be called in
// ConnectivityService#updateNetworkInfo().
waitForIdle();
- try {
- verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
- } catch (RemoteException e) {
- fail(e.getMessage());
- }
+ verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
// TODO: If the user accepted partial connectivity, we shouldn't switch to wifi until
@@ -2774,7 +2767,7 @@
}
@Test
- public void testCaptivePortalOnPartialConnectivity() throws RemoteException {
+ public void testCaptivePortalOnPartialConnectivity() throws Exception {
final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
@@ -2823,7 +2816,7 @@
}
@Test
- public void testCaptivePortal() {
+ public void testCaptivePortal() throws Exception {
final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
@@ -2863,6 +2856,9 @@
// Expect NET_CAPABILITY_VALIDATED onAvailable callback.
validatedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
+ // Expect no notification to be shown when captive portal disappears by itself
+ verify(mNotificationManager, never()).notifyAsUser(
+ anyString(), eq(NotificationType.LOGGED_IN.eventId), any(), any());
// Break network connectivity.
// Expect NET_CAPABILITY_VALIDATED onLost callback.
@@ -2872,7 +2868,7 @@
}
@Test
- public void testCaptivePortalApp() throws RemoteException {
+ public void testCaptivePortalApp() throws Exception {
final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
@@ -2892,6 +2888,8 @@
// Check that calling startCaptivePortalApp does nothing.
final int fastTimeoutMs = 100;
mCm.startCaptivePortalApp(wifiNetwork);
+ waitForIdle();
+ verify(mWiFiNetworkAgent.mNetworkMonitor, never()).launchCaptivePortalApp();
mServiceContext.expectNoStartActivityIntent(fastTimeoutMs);
// Turn into a captive portal.
@@ -2902,21 +2900,33 @@
// Check that startCaptivePortalApp sends the expected command to NetworkMonitor.
mCm.startCaptivePortalApp(wifiNetwork);
- verify(mWiFiNetworkAgent.mNetworkMonitor, timeout(TIMEOUT_MS).times(1))
- .launchCaptivePortalApp();
+ waitForIdle();
+ verify(mWiFiNetworkAgent.mNetworkMonitor).launchCaptivePortalApp();
+
+ // NetworkMonitor uses startCaptivePortal(Network, Bundle) (startCaptivePortalAppInternal)
+ final Bundle testBundle = new Bundle();
+ final String testKey = "testkey";
+ final String testValue = "testvalue";
+ testBundle.putString(testKey, testValue);
+ mCm.startCaptivePortalApp(wifiNetwork, testBundle);
+ final Intent signInIntent = mServiceContext.expectStartActivityIntent(TIMEOUT_MS);
+ assertEquals(ACTION_CAPTIVE_PORTAL_SIGN_IN, signInIntent.getAction());
+ assertEquals(testValue, signInIntent.getStringExtra(testKey));
// Report that the captive portal is dismissed, and check that callbacks are fired
mWiFiNetworkAgent.setNetworkValid();
mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid());
validatedCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
captivePortalCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+ verify(mNotificationManager, times(1)).notifyAsUser(anyString(),
+ eq(NotificationType.LOGGED_IN.eventId), any(), eq(UserHandle.ALL));
mCm.unregisterNetworkCallback(validatedCallback);
mCm.unregisterNetworkCallback(captivePortalCallback);
}
@Test
- public void testAvoidOrIgnoreCaptivePortals() {
+ public void testAvoidOrIgnoreCaptivePortals() throws Exception {
final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
@@ -2956,7 +2966,7 @@
* does work.
*/
@Test
- public void testNetworkSpecifier() {
+ public void testNetworkSpecifier() throws Exception {
// A NetworkSpecifier subclass that matches all networks but must not be visible to apps.
class ConfidentialMatchAllNetworkSpecifier extends NetworkSpecifier implements
Parcelable {
@@ -3096,24 +3106,18 @@
@Test
public void testInvalidNetworkSpecifier() {
- try {
+ assertThrows(IllegalArgumentException.class, () -> {
NetworkRequest.Builder builder = new NetworkRequest.Builder();
builder.setNetworkSpecifier(new MatchAllNetworkSpecifier());
- fail("NetworkRequest builder with MatchAllNetworkSpecifier");
- } catch (IllegalArgumentException expected) {
- // expected
- }
+ });
- try {
+ assertThrows(IllegalArgumentException.class, () -> {
NetworkCapabilities networkCapabilities = new NetworkCapabilities();
networkCapabilities.addTransportType(TRANSPORT_WIFI)
.setNetworkSpecifier(new MatchAllNetworkSpecifier());
mService.requestNetwork(networkCapabilities, null, 0, null,
ConnectivityManager.TYPE_WIFI);
- fail("ConnectivityService requestNetwork with MatchAllNetworkSpecifier");
- } catch (IllegalArgumentException expected) {
- // expected
- }
+ });
class NonParcelableSpecifier extends NetworkSpecifier {
public boolean satisfiedBy(NetworkSpecifier other) { return false; }
@@ -3122,24 +3126,22 @@
@Override public int describeContents() { return 0; }
@Override public void writeToParcel(Parcel p, int flags) {}
}
- NetworkRequest.Builder builder;
- builder = new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET);
- try {
+ final NetworkRequest.Builder builder =
+ new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET);
+ assertThrows(ClassCastException.class, () -> {
builder.setNetworkSpecifier(new NonParcelableSpecifier());
Parcel parcelW = Parcel.obtain();
builder.build().writeToParcel(parcelW, 0);
- fail("Parceling a non-parcelable specifier did not throw an exception");
- } catch (Exception e) {
- // expected
- }
+ });
- builder = new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET);
- builder.setNetworkSpecifier(new ParcelableSpecifier());
- NetworkRequest nr = builder.build();
+ final NetworkRequest nr =
+ new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET)
+ .setNetworkSpecifier(new ParcelableSpecifier())
+ .build();
assertNotNull(nr);
- try {
+ assertThrows(BadParcelableException.class, () -> {
Parcel parcelW = Parcel.obtain();
nr.writeToParcel(parcelW, 0);
byte[] bytes = parcelW.marshall();
@@ -3149,14 +3151,11 @@
parcelR.unmarshall(bytes, 0, bytes.length);
parcelR.setDataPosition(0);
NetworkRequest rereadNr = NetworkRequest.CREATOR.createFromParcel(parcelR);
- fail("Unparceling a non-framework NetworkSpecifier did not throw an exception");
- } catch (Exception e) {
- // expected
- }
+ });
}
@Test
- public void testNetworkSpecifierUidSpoofSecurityException() {
+ public void testNetworkSpecifierUidSpoofSecurityException() throws Exception {
class UidAwareNetworkSpecifier extends NetworkSpecifier implements Parcelable {
@Override
public boolean satisfiedBy(NetworkSpecifier other) {
@@ -3181,12 +3180,9 @@
NetworkRequest networkRequest = newWifiRequestBuilder().setNetworkSpecifier(
networkSpecifier).build();
TestNetworkCallback networkCallback = new TestNetworkCallback();
- try {
+ assertThrows(SecurityException.class, () -> {
mCm.requestNetwork(networkRequest, networkCallback);
- fail("Network request with spoofed UID did not throw a SecurityException");
- } catch (SecurityException e) {
- // expected
- }
+ });
}
@Test
@@ -3198,36 +3194,20 @@
.build();
// Registering a NetworkCallback with signal strength but w/o NETWORK_SIGNAL_STRENGTH_WAKEUP
// permission should get SecurityException.
- try {
- mCm.registerNetworkCallback(r, new NetworkCallback());
- fail("Expected SecurityException filing a callback with signal strength");
- } catch (SecurityException expected) {
- // expected
- }
+ assertThrows(SecurityException.class, () ->
+ mCm.registerNetworkCallback(r, new NetworkCallback()));
- try {
- mCm.registerNetworkCallback(r, PendingIntent.getService(
- mServiceContext, 0, new Intent(), 0));
- fail("Expected SecurityException filing a callback with signal strength");
- } catch (SecurityException expected) {
- // expected
- }
+ assertThrows(SecurityException.class, () ->
+ mCm.registerNetworkCallback(r, PendingIntent.getService(
+ mServiceContext, 0, new Intent(), 0)));
// Requesting a Network with signal strength should get IllegalArgumentException.
- try {
- mCm.requestNetwork(r, new NetworkCallback());
- fail("Expected IllegalArgumentException filing a request with signal strength");
- } catch (IllegalArgumentException expected) {
- // expected
- }
+ assertThrows(IllegalArgumentException.class, () ->
+ mCm.requestNetwork(r, new NetworkCallback()));
- try {
- mCm.requestNetwork(r, PendingIntent.getService(
- mServiceContext, 0, new Intent(), 0));
- fail("Expected IllegalArgumentException filing a request with signal strength");
- } catch (IllegalArgumentException expected) {
- // expected
- }
+ assertThrows(IllegalArgumentException.class, () ->
+ mCm.requestNetwork(r, PendingIntent.getService(
+ mServiceContext, 0, new Intent(), 0)));
}
@Test
@@ -3788,7 +3768,7 @@
* time-out period expires.
*/
@Test
- public void testSatisfiedNetworkRequestDoesNotTriggerOnUnavailable() {
+ public void testSatisfiedNetworkRequestDoesNotTriggerOnUnavailable() throws Exception {
NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
NetworkCapabilities.TRANSPORT_WIFI).build();
final TestNetworkCallback networkCallback = new TestNetworkCallback();
@@ -3808,7 +3788,7 @@
* not trigger onUnavailable() once the time-out period expires.
*/
@Test
- public void testSatisfiedThenLostNetworkRequestDoesNotTriggerOnUnavailable() {
+ public void testSatisfiedThenLostNetworkRequestDoesNotTriggerOnUnavailable() throws Exception {
NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
NetworkCapabilities.TRANSPORT_WIFI).build();
final TestNetworkCallback networkCallback = new TestNetworkCallback();
@@ -3831,7 +3811,7 @@
* (somehow) satisfied - the callback isn't called later.
*/
@Test
- public void testTimedoutNetworkRequest() {
+ public void testTimedoutNetworkRequest() throws Exception {
NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
NetworkCapabilities.TRANSPORT_WIFI).build();
final TestNetworkCallback networkCallback = new TestNetworkCallback();
@@ -3852,7 +3832,7 @@
* trigger the callback.
*/
@Test
- public void testNoCallbackAfterUnregisteredNetworkRequest() {
+ public void testNoCallbackAfterUnregisteredNetworkRequest() throws Exception {
NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
NetworkCapabilities.TRANSPORT_WIFI).build();
final TestNetworkCallback networkCallback = new TestNetworkCallback();
@@ -3944,7 +3924,7 @@
private static class TestKeepaliveCallback extends PacketKeepaliveCallback {
- public static enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR };
+ public enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR }
private class CallbackValue {
public CallbackType callbackType;
@@ -3992,25 +3972,19 @@
mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error));
}
- private void expectCallback(CallbackValue callbackValue) {
- try {
- assertEquals(
- callbackValue,
- mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- } catch (InterruptedException e) {
- fail(callbackValue.callbackType + " callback not seen after " + TIMEOUT_MS + " ms");
- }
+ private void expectCallback(CallbackValue callbackValue) throws InterruptedException {
+ assertEquals(callbackValue, mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
}
- public void expectStarted() {
+ public void expectStarted() throws Exception {
expectCallback(new CallbackValue(CallbackType.ON_STARTED));
}
- public void expectStopped() {
+ public void expectStopped() throws Exception {
expectCallback(new CallbackValue(CallbackType.ON_STOPPED));
}
- public void expectError(int error) {
+ public void expectError(int error) throws Exception {
expectCallback(new CallbackValue(CallbackType.ON_ERROR, error));
}
}
@@ -4071,25 +4045,20 @@
mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error));
}
- private void expectCallback(CallbackValue callbackValue) {
- try {
- assertEquals(
- callbackValue,
- mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- } catch (InterruptedException e) {
- fail(callbackValue.callbackType + " callback not seen after " + TIMEOUT_MS + " ms");
- }
+ private void expectCallback(CallbackValue callbackValue) throws InterruptedException {
+ assertEquals(callbackValue, mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+
}
- public void expectStarted() {
+ public void expectStarted() throws InterruptedException {
expectCallback(new CallbackValue(CallbackType.ON_STARTED));
}
- public void expectStopped() {
+ public void expectStopped() throws InterruptedException {
expectCallback(new CallbackValue(CallbackType.ON_STOPPED));
}
- public void expectError(int error) {
+ public void expectError(int error) throws InterruptedException {
expectCallback(new CallbackValue(CallbackType.ON_ERROR, error));
}
@@ -4100,7 +4069,7 @@
}
}
- private Network connectKeepaliveNetwork(LinkProperties lp) {
+ private Network connectKeepaliveNetwork(LinkProperties lp) throws Exception {
// Ensure the network is disconnected before we do anything.
if (mWiFiNetworkAgent != null) {
assertNull(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()));
@@ -4234,7 +4203,8 @@
}
// Helper method to prepare the executor and run test
- private void runTestWithSerialExecutors(ThrowingConsumer<Executor> functor) throws Exception {
+ private void runTestWithSerialExecutors(ExceptionUtils.ThrowingConsumer<Executor> functor)
+ throws Exception {
final ExecutorService executorSingleThread = Executors.newSingleThreadExecutor();
final Executor executorInline = (Runnable r) -> r.run();
functor.accept(executorSingleThread);
@@ -4552,7 +4522,7 @@
private static boolean isUdpPortInUse(int port) {
try (DatagramSocket ignored = new DatagramSocket(port)) {
return false;
- } catch (IOException ignored) {
+ } catch (IOException alreadyInUse) {
return true;
}
}
@@ -4564,23 +4534,19 @@
}
private static class TestNetworkPinner extends NetworkPinner {
- public static boolean awaitPin(int timeoutMs) {
+ public static boolean awaitPin(int timeoutMs) throws InterruptedException {
synchronized(sLock) {
if (sNetwork == null) {
- try {
- sLock.wait(timeoutMs);
- } catch (InterruptedException e) {}
+ sLock.wait(timeoutMs);
}
return sNetwork != null;
}
}
- public static boolean awaitUnpin(int timeoutMs) {
+ public static boolean awaitUnpin(int timeoutMs) throws InterruptedException {
synchronized(sLock) {
if (sNetwork != null) {
- try {
- sLock.wait(timeoutMs);
- } catch (InterruptedException e) {}
+ sLock.wait(timeoutMs);
}
return sNetwork == null;
}
@@ -4603,7 +4569,7 @@
}
@Test
- public void testNetworkPinner() {
+ public void testNetworkPinner() throws Exception {
NetworkRequest wifiRequest = new NetworkRequest.Builder()
.addTransportType(TRANSPORT_WIFI)
.build();
@@ -4698,25 +4664,20 @@
}
// Test that the limit is enforced when MAX_REQUESTS simultaneous requests are added.
- try {
- mCm.requestNetwork(networkRequest, new NetworkCallback());
- fail("Registering " + MAX_REQUESTS + " network requests did not throw exception");
- } catch (TooManyRequestsException expected) {}
- try {
- mCm.registerNetworkCallback(networkRequest, new NetworkCallback());
- fail("Registering " + MAX_REQUESTS + " network callbacks did not throw exception");
- } catch (TooManyRequestsException expected) {}
- try {
- mCm.requestNetwork(networkRequest,
- PendingIntent.getBroadcast(mContext, 0, new Intent("c"), 0));
- fail("Registering " + MAX_REQUESTS + " PendingIntent requests did not throw exception");
- } catch (TooManyRequestsException expected) {}
- try {
- mCm.registerNetworkCallback(networkRequest,
- PendingIntent.getBroadcast(mContext, 0, new Intent("d"), 0));
- fail("Registering " + MAX_REQUESTS
- + " PendingIntent callbacks did not throw exception");
- } catch (TooManyRequestsException expected) {}
+ assertThrows(TooManyRequestsException.class, () ->
+ mCm.requestNetwork(networkRequest, new NetworkCallback())
+ );
+ assertThrows(TooManyRequestsException.class, () ->
+ mCm.registerNetworkCallback(networkRequest, new NetworkCallback())
+ );
+ assertThrows(TooManyRequestsException.class, () ->
+ mCm.requestNetwork(networkRequest,
+ PendingIntent.getBroadcast(mContext, 0, new Intent("c"), 0))
+ );
+ assertThrows(TooManyRequestsException.class, () ->
+ mCm.registerNetworkCallback(networkRequest,
+ PendingIntent.getBroadcast(mContext, 0, new Intent("d"), 0))
+ );
for (Object o : registered) {
if (o instanceof NetworkCallback) {
@@ -4760,7 +4721,7 @@
}
@Test
- public void testNetworkInfoOfTypeNone() {
+ public void testNetworkInfoOfTypeNone() throws Exception {
ConditionVariable broadcastCV = waitForConnectivityBroadcasts(1);
verifyNoNetwork();
@@ -4821,7 +4782,7 @@
}
@Test
- public void testLinkPropertiesEnsuresDirectlyConnectedRoutes() {
+ public void testLinkPropertiesEnsuresDirectlyConnectedRoutes() throws Exception {
final NetworkRequest networkRequest = new NetworkRequest.Builder()
.addTransportType(TRANSPORT_WIFI).build();
final TestNetworkCallback networkCallback = new TestNetworkCallback();
@@ -4884,11 +4845,8 @@
mCellNetworkAgent.sendLinkProperties(cellLp);
waitForIdle();
verify(mStatsService, atLeastOnce())
- .forceUpdateIfaces(
- eq(onlyCell),
- any(NetworkState[].class),
- eq(MOBILE_IFNAME));
- assertEquals(new VpnInfo[0], NetworkStatsFactory.getVpnInfos());
+ .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME),
+ eq(new VpnInfo[0]));
reset(mStatsService);
// Default network switch should update ifaces.
@@ -4897,65 +4855,47 @@
waitForIdle();
assertEquals(wifiLp, mService.getActiveLinkProperties());
verify(mStatsService, atLeastOnce())
- .forceUpdateIfaces(
- eq(onlyWifi),
- any(NetworkState[].class),
- eq(WIFI_IFNAME));
- assertEquals(new VpnInfo[0], NetworkStatsFactory.getVpnInfos());
+ .forceUpdateIfaces(eq(onlyWifi), any(NetworkState[].class), eq(WIFI_IFNAME),
+ eq(new VpnInfo[0]));
reset(mStatsService);
// Disconnect should update ifaces.
mWiFiNetworkAgent.disconnect();
waitForIdle();
verify(mStatsService, atLeastOnce())
- .forceUpdateIfaces(
- eq(onlyCell),
- any(NetworkState[].class),
- eq(MOBILE_IFNAME));
- assertEquals(new VpnInfo[0], NetworkStatsFactory.getVpnInfos());
+ .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class),
+ eq(MOBILE_IFNAME), eq(new VpnInfo[0]));
reset(mStatsService);
// Metered change should update ifaces
mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
waitForIdle();
verify(mStatsService, atLeastOnce())
- .forceUpdateIfaces(
- eq(onlyCell),
- any(NetworkState[].class),
- eq(MOBILE_IFNAME));
- assertEquals(new VpnInfo[0], NetworkStatsFactory.getVpnInfos());
+ .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME),
+ eq(new VpnInfo[0]));
reset(mStatsService);
mCellNetworkAgent.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
waitForIdle();
verify(mStatsService, atLeastOnce())
- .forceUpdateIfaces(
- eq(onlyCell),
- any(NetworkState[].class),
- eq(MOBILE_IFNAME));
- assertEquals(new VpnInfo[0], NetworkStatsFactory.getVpnInfos());
+ .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME),
+ eq(new VpnInfo[0]));
reset(mStatsService);
// Captive portal change shouldn't update ifaces
mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL);
waitForIdle();
verify(mStatsService, never())
- .forceUpdateIfaces(
- eq(onlyCell),
- any(NetworkState[].class),
- eq(MOBILE_IFNAME));
- assertEquals(new VpnInfo[0], NetworkStatsFactory.getVpnInfos());
+ .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME),
+ eq(new VpnInfo[0]));
reset(mStatsService);
// Roaming change should update ifaces
mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
waitForIdle();
verify(mStatsService, atLeastOnce())
- .forceUpdateIfaces(
- eq(onlyCell),
- any(NetworkState[].class),
- eq(MOBILE_IFNAME));
- assertEquals(new VpnInfo[0], NetworkStatsFactory.getVpnInfos());
+ .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME),
+ eq(new VpnInfo[0]));
reset(mStatsService);
}
@@ -5250,7 +5190,7 @@
}
@Test
- public void testVpnNetworkActive() {
+ public void testVpnNetworkActive() throws Exception {
final int uid = Process.myUid();
final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback();
@@ -5362,7 +5302,7 @@
}
@Test
- public void testVpnWithoutInternet() {
+ public void testVpnWithoutInternet() throws Exception {
final int uid = Process.myUid();
final TestNetworkCallback defaultCallback = new TestNetworkCallback();
@@ -5392,7 +5332,7 @@
}
@Test
- public void testVpnWithInternet() {
+ public void testVpnWithInternet() throws Exception {
final int uid = Process.myUid();
final TestNetworkCallback defaultCallback = new TestNetworkCallback();
@@ -5475,7 +5415,7 @@
}
@Test
- public void testVpnSetUnderlyingNetworks() {
+ public void testVpnSetUnderlyingNetworks() throws Exception {
final int uid = Process.myUid();
final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback();
@@ -5573,7 +5513,7 @@
}
@Test
- public void testNullUnderlyingNetworks() {
+ public void testNullUnderlyingNetworks() throws Exception {
final int uid = Process.myUid();
final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback();
@@ -5637,7 +5577,7 @@
}
@Test
- public void testIsActiveNetworkMeteredOverWifi() {
+ public void testIsActiveNetworkMeteredOverWifi() throws Exception {
// Returns true by default when no network is available.
assertTrue(mCm.isActiveNetworkMetered());
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
@@ -5649,7 +5589,7 @@
}
@Test
- public void testIsActiveNetworkMeteredOverCell() {
+ public void testIsActiveNetworkMeteredOverCell() throws Exception {
// Returns true by default when no network is available.
assertTrue(mCm.isActiveNetworkMetered());
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -5661,7 +5601,7 @@
}
@Test
- public void testIsActiveNetworkMeteredOverVpnTrackingPlatformDefault() {
+ public void testIsActiveNetworkMeteredOverVpnTrackingPlatformDefault() throws Exception {
// Returns true by default when no network is available.
assertTrue(mCm.isActiveNetworkMetered());
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -5715,7 +5655,7 @@
}
@Test
- public void testIsActiveNetworkMeteredOverVpnSpecifyingUnderlyingNetworks() {
+ public void testIsActiveNetworkMeteredOverVpnSpecifyingUnderlyingNetworks() throws Exception {
// Returns true by default when no network is available.
assertTrue(mCm.isActiveNetworkMetered());
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -5786,7 +5726,7 @@
}
@Test
- public void testIsActiveNetworkMeteredOverAlwaysMeteredVpn() {
+ public void testIsActiveNetworkMeteredOverAlwaysMeteredVpn() throws Exception {
// Returns true by default when no network is available.
assertTrue(mCm.isActiveNetworkMetered());
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
@@ -5833,7 +5773,7 @@
}
@Test
- public void testNetworkBlockedStatus() {
+ public void testNetworkBlockedStatus() throws Exception {
final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
final NetworkRequest cellRequest = new NetworkRequest.Builder()
.addTransportType(TRANSPORT_CELLULAR)
@@ -5884,7 +5824,7 @@
}
@Test
- public void testNetworkBlockedStatusBeforeAndAfterConnect() {
+ public void testNetworkBlockedStatusBeforeAndAfterConnect() throws Exception {
final TestNetworkCallback defaultCallback = new TestNetworkCallback();
mCm.registerDefaultNetworkCallback(defaultCallback);
@@ -5953,7 +5893,7 @@
}
@Test
- public void testStackedLinkProperties() throws UnknownHostException, RemoteException {
+ public void testStackedLinkProperties() throws Exception {
final LinkAddress myIpv4 = new LinkAddress("1.2.3.4/24");
final LinkAddress myIpv6 = new LinkAddress("2001:db8:1::1/64");
final String kNat64PrefixString = "2001:db8:64:64:64:64::";
@@ -6116,7 +6056,7 @@
}
@Test
- public void testDataActivityTracking() throws RemoteException {
+ public void testDataActivityTracking() throws Exception {
final TestNetworkCallback networkCallback = new TestNetworkCallback();
final NetworkRequest networkRequest = new NetworkRequest.Builder()
.addCapability(NET_CAPABILITY_INTERNET)
@@ -6191,21 +6131,17 @@
mCm.unregisterNetworkCallback(networkCallback);
}
- private void verifyTcpBufferSizeChange(String tcpBufferSizes) {
+ private void verifyTcpBufferSizeChange(String tcpBufferSizes) throws Exception {
String[] values = tcpBufferSizes.split(",");
String rmemValues = String.join(" ", values[0], values[1], values[2]);
String wmemValues = String.join(" ", values[3], values[4], values[5]);
waitForIdle();
- try {
- verify(mMockNetd, atLeastOnce()).setTcpRWmemorySize(rmemValues, wmemValues);
- } catch (RemoteException e) {
- fail("mMockNetd should never throw RemoteException");
- }
+ verify(mMockNetd, atLeastOnce()).setTcpRWmemorySize(rmemValues, wmemValues);
reset(mMockNetd);
}
@Test
- public void testTcpBufferReset() {
+ public void testTcpBufferReset() throws Exception {
final String testTcpBufferSizes = "1,2,3,4,5,6";
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -6222,7 +6158,7 @@
}
@Test
- public void testGetGlobalProxyForNetwork() {
+ public void testGetGlobalProxyForNetwork() throws Exception {
final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888);
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
final Network wifiNetwork = mWiFiNetworkAgent.getNetwork();
@@ -6231,7 +6167,7 @@
}
@Test
- public void testGetProxyForActiveNetwork() {
+ public void testGetProxyForActiveNetwork() throws Exception {
final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888);
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(true);
@@ -6248,7 +6184,7 @@
}
@Test
- public void testGetProxyForVPN() {
+ public void testGetProxyForVPN() throws Exception {
final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888);
// Set up a WiFi network with no proxy
@@ -6434,7 +6370,7 @@
private MockNetworkAgent establishVpn(LinkProperties lp, int establishingUid,
- Set<UidRange> vpnRange) {
+ Set<UidRange> vpnRange) throws Exception {
final MockNetworkAgent vpnNetworkAgent = new MockNetworkAgent(TRANSPORT_VPN, lp);
vpnNetworkAgent.getNetworkCapabilities().setEstablishingVpnAppUid(establishingUid);
mMockVpn.setNetworkAgent(vpnNetworkAgent);
diff --git a/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java b/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java
index 7329474..a21f509 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java
@@ -79,8 +79,7 @@
// related to networkStatsFactory is compiled to a minimal native library and loaded here.
System.loadLibrary("networkstatsfactorytestjni");
mFactory = new NetworkStatsFactory(mTestProc, false);
- NetworkStatsFactory.updateVpnInfos(new VpnInfo[0]);
- NetworkStatsFactory.clearStackedIfaces();
+ mFactory.updateVpnInfos(new VpnInfo[0]);
}
@After
@@ -107,7 +106,7 @@
@Test
public void vpnRewriteTrafficThroughItself() throws Exception {
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
- NetworkStatsFactory.updateVpnInfos(vpnInfos);
+ mFactory.updateVpnInfos(vpnInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
@@ -136,8 +135,8 @@
@Test
public void vpnWithClat() throws Exception {
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {CLAT_PREFIX + TEST_IFACE})};
- NetworkStatsFactory.updateVpnInfos(vpnInfos);
- NetworkStatsFactory.noteStackedIface(CLAT_PREFIX + TEST_IFACE, TEST_IFACE);
+ mFactory.updateVpnInfos(vpnInfos);
+ mFactory.noteStackedIface(CLAT_PREFIX + TEST_IFACE, TEST_IFACE);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
@@ -169,7 +168,7 @@
@Test
public void vpnWithOneUnderlyingIface() throws Exception {
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
- NetworkStatsFactory.updateVpnInfos(vpnInfos);
+ mFactory.updateVpnInfos(vpnInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
@@ -193,7 +192,7 @@
public void vpnWithOneUnderlyingIfaceAndOwnTraffic() throws Exception {
// WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
- NetworkStatsFactory.updateVpnInfos(vpnInfos);
+ mFactory.updateVpnInfos(vpnInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
@@ -221,7 +220,7 @@
public void vpnWithOneUnderlyingIface_withCompression() throws Exception {
// WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
- NetworkStatsFactory.updateVpnInfos(vpnInfos);
+ mFactory.updateVpnInfos(vpnInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
@@ -244,7 +243,7 @@
// Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
// Additionally, VPN is duplicating traffic across both WiFi and Cell.
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
- NetworkStatsFactory.updateVpnInfos(vpnInfos);
+ mFactory.updateVpnInfos(vpnInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
@@ -270,7 +269,7 @@
// Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
// Additionally, VPN is arbitrarily splitting traffic across WiFi and Cell.
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
- NetworkStatsFactory.updateVpnInfos(vpnInfos);
+ mFactory.updateVpnInfos(vpnInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
@@ -297,7 +296,7 @@
// Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
// Additionally, VPN is arbitrarily splitting compressed traffic across WiFi and Cell.
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
- NetworkStatsFactory.updateVpnInfos(vpnInfos);
+ mFactory.updateVpnInfos(vpnInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface:
// 1000 bytes (100 packets) were sent/received by UID_RED over VPN.
@@ -319,7 +318,7 @@
// WiFi and Cell networks are connected and VPN is using Cell (which has TEST_IFACE2),
// but has declared only WiFi (TEST_IFACE) in its underlying network set.
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
- NetworkStatsFactory.updateVpnInfos(vpnInfos);
+ mFactory.updateVpnInfos(vpnInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
@@ -383,7 +382,7 @@
@Test
public void testDoubleClatAccountingSimple() throws Exception {
- NetworkStatsFactory.noteStackedIface("v4-wlan0", "wlan0");
+ mFactory.noteStackedIface("v4-wlan0", "wlan0");
// xt_qtaguid_with_clat_simple is a synthetic file that simulates
// - 213 received 464xlat packets of size 200 bytes
@@ -398,7 +397,7 @@
@Test
public void testDoubleClatAccounting() throws Exception {
- NetworkStatsFactory.noteStackedIface("v4-wlan0", "wlan0");
+ mFactory.noteStackedIface("v4-wlan0", "wlan0");
NetworkStats stats = parseDetailedStats(R.raw.xt_qtaguid_with_clat);
assertEquals(42, stats.size());
@@ -419,8 +418,6 @@
assertStatsEntry(stats, "lo", 0, SET_DEFAULT, 0x0, 1288L, 1288L);
assertNoStatsEntry(stats, "wlan0", 1029, SET_DEFAULT, 0x0);
-
- NetworkStatsFactory.clearStackedIfaces();
}
@Test
@@ -435,7 +432,7 @@
long rootRxBytesAfter = 1398634L;
assertEquals("UID 0 traffic should be ~0", 4623, rootRxBytesAfter - rootRxBytesBefore);
- NetworkStatsFactory.noteStackedIface("v4-wlan0", "wlan0");
+ mFactory.noteStackedIface("v4-wlan0", "wlan0");
NetworkStats stats;
// Stats snapshot before the download
@@ -447,8 +444,6 @@
stats = parseDetailedStats(R.raw.xt_qtaguid_with_clat_100mb_download_after);
assertStatsEntry(stats, "v4-wlan0", 10106, SET_FOREGROUND, 0x0, appRxBytesAfter, 7867488L);
assertStatsEntry(stats, "wlan0", 0, SET_DEFAULT, 0x0, rootRxBytesAfter, 0L);
-
- NetworkStatsFactory.clearStackedIfaces();
}
/**
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index adaef40..1d29a82 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -37,6 +37,7 @@
import static android.net.NetworkStats.SET_FOREGROUND;
import static android.net.NetworkStats.STATS_PER_IFACE;
import static android.net.NetworkStats.STATS_PER_UID;
+import static android.net.NetworkStats.TAG_ALL;
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkStatsHistory.FIELD_ALL;
@@ -95,6 +96,7 @@
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.internal.net.VpnInfo;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.test.BroadcastInterceptingContext;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
@@ -154,6 +156,7 @@
private File mStatsDir;
private @Mock INetworkManagementService mNetManager;
+ private @Mock NetworkStatsFactory mStatsFactory;
private @Mock NetworkStatsSettings mSettings;
private @Mock IBinder mBinder;
private @Mock AlarmManager mAlarmManager;
@@ -189,8 +192,8 @@
mService = new NetworkStatsService(
mServiceContext, mNetManager, mAlarmManager, wakeLock, mClock,
- TelephonyManager.getDefault(), mSettings, new NetworkStatsObservers(),
- mStatsDir, getBaseDir(mStatsDir));
+ TelephonyManager.getDefault(), mSettings, mStatsFactory,
+ new NetworkStatsObservers(), mStatsDir, getBaseDir(mStatsDir));
mHandlerThread = new HandlerThread("HandlerThread");
mHandlerThread.start();
Handler.Callback callback = new NetworkStatsService.HandlerCallback(mService);
@@ -205,7 +208,7 @@
mService.systemReady();
// Verify that system ready fetches realtime stats
- verify(mNetManager).getNetworkStatsUidDetail(UID_ALL, INTERFACES_ALL);
+ verify(mStatsFactory).readNetworkStatsDetail(UID_ALL, INTERFACES_ALL, TAG_ALL);
mSession = mService.openSession();
assertNotNull("openSession() failed", mSession);
@@ -240,7 +243,7 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
// verify service has empty history for wifi
assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
@@ -283,7 +286,7 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
// verify service has empty history for wifi
assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
@@ -356,7 +359,7 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
// modify some number on wifi, and trigger poll event
incrementCurrentTime(2 * HOUR_IN_MILLIS);
@@ -396,7 +399,7 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states));
+ mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]);
// create some traffic on first network
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -430,7 +433,7 @@
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
.addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
- mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states));
+ mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]);
forcePollAndWaitForIdle();
@@ -469,7 +472,7 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
// create some traffic
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -526,7 +529,7 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states));
+ mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]);
// create some traffic
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -552,7 +555,7 @@
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
- mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states));
+ mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]);
forcePollAndWaitForIdle();
@@ -581,7 +584,7 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
// create some traffic for two apps
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -638,7 +641,7 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
NetworkStats.Entry entry1 = new NetworkStats.Entry(
TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L);
@@ -681,7 +684,7 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
NetworkStats.Entry uidStats = new NetworkStats.Entry(
TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xF00D, 1024L, 8L, 512L, 4L, 0L);
@@ -693,10 +696,13 @@
"otherif", UID_BLUE, SET_DEFAULT, 0xF00D, 1024L, 8L, 512L, 4L, 0L);
final String[] ifaceFilter = new String[] { TEST_IFACE };
+ final String[] augmentedIfaceFilter = new String[] { stackedIface, TEST_IFACE };
incrementCurrentTime(HOUR_IN_MILLIS);
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats());
- when(mNetManager.getNetworkStatsUidDetail(eq(UID_ALL), any()))
+ when(mStatsFactory.augmentWithStackedInterfaces(eq(ifaceFilter)))
+ .thenReturn(augmentedIfaceFilter);
+ when(mStatsFactory.readNetworkStatsDetail(eq(UID_ALL), any(), eq(TAG_ALL)))
.thenReturn(new NetworkStats(getElapsedRealtime(), 1)
.addValues(uidStats));
when(mNetManager.getNetworkStatsTethering(STATS_PER_UID))
@@ -706,15 +712,17 @@
NetworkStats stats = mService.getDetailedUidStats(ifaceFilter);
- // mNetManager#getNetworkStatsUidDetail(UID_ALL, INTERFACES_ALL) has following invocations:
+ // mStatsFactory#readNetworkStatsDetail() has the following invocations:
// 1) NetworkStatsService#systemReady from #setUp.
// 2) mService#forceUpdateIfaces in the test above.
//
// Additionally, we should have one call from the above call to mService#getDetailedUidStats
- // with the augmented ifaceFilter
- verify(mNetManager, times(2)).getNetworkStatsUidDetail(UID_ALL, INTERFACES_ALL);
- verify(mNetManager, times(1)).getNetworkStatsUidDetail(
- eq(UID_ALL), eq(NetworkStatsFactory.augmentWithStackedInterfaces(ifaceFilter)));
+ // with the augmented ifaceFilter.
+ verify(mStatsFactory, times(2)).readNetworkStatsDetail(UID_ALL, INTERFACES_ALL, TAG_ALL);
+ verify(mStatsFactory, times(1)).readNetworkStatsDetail(
+ eq(UID_ALL),
+ eq(augmentedIfaceFilter),
+ eq(TAG_ALL));
assertTrue(ArrayUtils.contains(stats.getUniqueIfaces(), TEST_IFACE));
assertTrue(ArrayUtils.contains(stats.getUniqueIfaces(), stackedIface));
assertEquals(2, stats.size());
@@ -730,7 +738,7 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
// create some initial traffic
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -786,7 +794,7 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
// create some initial traffic
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -825,7 +833,7 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states));
+ mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]);
// Create some traffic
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -862,7 +870,7 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states));
+ mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]);
// create some tethering traffic
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -902,7 +910,7 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
+ mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
// verify service has empty history for wifi
assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
@@ -1062,11 +1070,11 @@
}
private void expectNetworkStatsSummaryDev(NetworkStats summary) throws Exception {
- when(mNetManager.getNetworkStatsSummaryDev()).thenReturn(summary);
+ when(mStatsFactory.readNetworkStatsSummaryDev()).thenReturn(summary);
}
private void expectNetworkStatsSummaryXt(NetworkStats summary) throws Exception {
- when(mNetManager.getNetworkStatsSummaryXt()).thenReturn(summary);
+ when(mStatsFactory.readNetworkStatsSummaryXt()).thenReturn(summary);
}
private void expectNetworkStatsTethering(int how, NetworkStats stats)
@@ -1080,7 +1088,8 @@
private void expectNetworkStatsUidDetail(NetworkStats detail, NetworkStats tetherStats)
throws Exception {
- when(mNetManager.getNetworkStatsUidDetail(UID_ALL, INTERFACES_ALL)).thenReturn(detail);
+ when(mStatsFactory.readNetworkStatsDetail(UID_ALL, INTERFACES_ALL, TAG_ALL))
+ .thenReturn(detail);
// also include tethering details, since they are folded into UID
when(mNetManager.getNetworkStatsTethering(STATS_PER_UID)).thenReturn(tetherStats);
diff --git a/tools/lock_agent/agent.cpp b/tools/lock_agent/agent.cpp
index c639427..40293b6 100644
--- a/tools/lock_agent/agent.cpp
+++ b/tools/lock_agent/agent.cpp
@@ -85,118 +85,143 @@
using namespace dex;
using namespace lir;
-bool transform(std::shared_ptr<ir::DexFile> dexIr) {
- bool modified = false;
+class Transformer {
+public:
+ explicit Transformer(std::shared_ptr<ir::DexFile> dexIr) : dexIr_(dexIr) {}
- std::unique_ptr<ir::Builder> builder;
+ bool transform() {
+ bool classModified = false;
- for (auto& method : dexIr->encoded_methods) {
- // Do not look into abstract/bridge/native/synthetic methods.
- if ((method->access_flags & (kAccAbstract | kAccBridge | kAccNative | kAccSynthetic))
- != 0) {
- continue;
+ std::unique_ptr<ir::Builder> builder;
+
+ for (auto& method : dexIr_->encoded_methods) {
+ // Do not look into abstract/bridge/native/synthetic methods.
+ if ((method->access_flags & (kAccAbstract | kAccBridge | kAccNative | kAccSynthetic))
+ != 0) {
+ continue;
+ }
+
+ struct HookVisitor: public Visitor {
+ HookVisitor(Transformer* transformer, CodeIr* c_ir)
+ : transformer(transformer), cIr(c_ir) {
+ }
+
+ bool Visit(Bytecode* bytecode) override {
+ if (bytecode->opcode == OP_MONITOR_ENTER) {
+ insertHook(bytecode, true,
+ reinterpret_cast<VReg*>(bytecode->operands[0])->reg);
+ return true;
+ }
+ if (bytecode->opcode == OP_MONITOR_EXIT) {
+ insertHook(bytecode, false,
+ reinterpret_cast<VReg*>(bytecode->operands[0])->reg);
+ return true;
+ }
+ return false;
+ }
+
+ void insertHook(lir::Instruction* before, bool pre, u4 reg) {
+ transformer->preparePrePost();
+ transformer->addCall(cIr, before, OP_INVOKE_STATIC_RANGE,
+ transformer->hookType_, pre ? "preLock" : "postLock",
+ transformer->voidType_, transformer->objectType_, reg);
+ myModified = true;
+ }
+
+ Transformer* transformer;
+ CodeIr* cIr;
+ bool myModified = false;
+ };
+
+ CodeIr c(method.get(), dexIr_);
+ bool methodModified = false;
+
+ HookVisitor visitor(this, &c);
+ for (auto it = c.instructions.begin(); it != c.instructions.end(); ++it) {
+ lir::Instruction* fi = *it;
+ fi->Accept(&visitor);
+ }
+ methodModified |= visitor.myModified;
+
+ if (methodModified) {
+ classModified = true;
+ c.Assemble();
+ }
}
- struct HookVisitor: public Visitor {
- HookVisitor(std::unique_ptr<ir::Builder>* b, std::shared_ptr<ir::DexFile> d_ir,
- CodeIr* c_ir) :
- b(b), dIr(d_ir), cIr(c_ir) {
- }
+ return classModified;
+ }
- bool Visit(Bytecode* bytecode) override {
- if (bytecode->opcode == OP_MONITOR_ENTER) {
- prepare();
- addCall(bytecode, OP_INVOKE_STATIC_RANGE, hookType, "preLock", voidType,
- objectType, reinterpret_cast<VReg*>(bytecode->operands[0])->reg);
- myModified = true;
- return true;
- }
- if (bytecode->opcode == OP_MONITOR_EXIT) {
- prepare();
- addCall(bytecode, OP_INVOKE_STATIC_RANGE, hookType, "postLock", voidType,
- objectType, reinterpret_cast<VReg*>(bytecode->operands[0])->reg);
- myModified = true;
- return true;
- }
- return false;
- }
+private:
+ void preparePrePost() {
+ // Insert "void LockHook.(pre|post)(Object o)."
- void prepare() {
- if (*b == nullptr) {
- *b = std::unique_ptr<ir::Builder>(new ir::Builder(dIr));
- }
- if (voidType == nullptr) {
- voidType = (*b)->GetType("V");
- hookType = (*b)->GetType("Lcom/android/lock_checker/LockHook;");
- objectType = (*b)->GetType("Ljava/lang/Object;");
- }
- }
+ prepareBuilder();
- void addInst(lir::Instruction* instructionAfter, Opcode opcode,
- const std::list<Operand*>& operands) {
- auto instruction = cIr->Alloc<Bytecode>();
-
- instruction->opcode = opcode;
-
- for (auto it = operands.begin(); it != operands.end(); it++) {
- instruction->operands.push_back(*it);
- }
-
- cIr->instructions.InsertBefore(instructionAfter, instruction);
- }
-
- void addCall(lir::Instruction* instructionAfter, Opcode opcode, ir::Type* type,
- const char* methodName, ir::Type* returnType,
- const std::vector<ir::Type*>& types, const std::list<int>& regs) {
- auto proto = (*b)->GetProto(returnType, (*b)->GetTypeList(types));
- auto method = (*b)->GetMethodDecl((*b)->GetAsciiString(methodName), proto, type);
-
- VRegList* paramRegs = cIr->Alloc<VRegList>();
- for (auto it = regs.begin(); it != regs.end(); it++) {
- paramRegs->registers.push_back(*it);
- }
-
- addInst(instructionAfter, opcode,
- { paramRegs, cIr->Alloc<Method>(method, method->orig_index) });
- }
-
- void addCall(lir::Instruction* instructionAfter, Opcode opcode, ir::Type* type,
- const char* methodName, ir::Type* returnType, ir::Type* paramType,
- u4 paramVReg) {
- auto proto = (*b)->GetProto(returnType, (*b)->GetTypeList( { paramType }));
- auto method = (*b)->GetMethodDecl((*b)->GetAsciiString(methodName), proto, type);
-
- VRegRange* args = cIr->Alloc<VRegRange>(paramVReg, 1);
-
- addInst(instructionAfter, opcode,
- { args, cIr->Alloc<Method>(method, method->orig_index) });
- }
-
- std::unique_ptr<ir::Builder>* b;
- std::shared_ptr<ir::DexFile> dIr;
- CodeIr* cIr;
- ir::Type* voidType = nullptr;
- ir::Type* hookType = nullptr;
- ir::Type* objectType = nullptr;
- bool myModified = false;
- };
-
- CodeIr c(method.get(), dexIr);
- HookVisitor visitor(&builder, dexIr, &c);
-
- for (auto it = c.instructions.begin(); it != c.instructions.end(); ++it) {
- lir::Instruction* fi = *it;
- fi->Accept(&visitor);
+ if (voidType_ == nullptr) {
+ voidType_ = builder_->GetType("V");
}
-
- if (visitor.myModified) {
- modified = true;
- c.Assemble();
+ if (hookType_ == nullptr) {
+ hookType_ = builder_->GetType("Lcom/android/lock_checker/LockHook;");
+ }
+ if (objectType_ == nullptr) {
+ objectType_ = builder_->GetType("Ljava/lang/Object;");
}
}
- return modified;
-}
+ void prepareBuilder() {
+ if (builder_ == nullptr) {
+ builder_ = std::unique_ptr<ir::Builder>(new ir::Builder(dexIr_));
+ }
+ }
+
+ static void addInst(CodeIr* cIr, lir::Instruction* instructionAfter, Opcode opcode,
+ const std::list<Operand*>& operands) {
+ auto instruction = cIr->Alloc<Bytecode>();
+
+ instruction->opcode = opcode;
+
+ for (auto it = operands.begin(); it != operands.end(); it++) {
+ instruction->operands.push_back(*it);
+ }
+
+ cIr->instructions.InsertBefore(instructionAfter, instruction);
+ }
+
+ void addCall(CodeIr* cIr, lir::Instruction* instructionAfter, Opcode opcode, ir::Type* type,
+ const char* methodName, ir::Type* returnType,
+ const std::vector<ir::Type*>& types, const std::list<int>& regs) {
+ auto proto = builder_->GetProto(returnType, builder_->GetTypeList(types));
+ auto method = builder_->GetMethodDecl(builder_->GetAsciiString(methodName), proto, type);
+
+ VRegList* paramRegs = cIr->Alloc<VRegList>();
+ for (auto it = regs.begin(); it != regs.end(); it++) {
+ paramRegs->registers.push_back(*it);
+ }
+
+ addInst(cIr, instructionAfter, opcode,
+ { paramRegs, cIr->Alloc<Method>(method, method->orig_index) });
+ }
+
+ void addCall(CodeIr* cIr, lir::Instruction* instructionAfter, Opcode opcode, ir::Type* type,
+ const char* methodName, ir::Type* returnType, ir::Type* paramType,
+ u4 paramVReg) {
+ auto proto = builder_->GetProto(returnType, builder_->GetTypeList( { paramType }));
+ auto method = builder_->GetMethodDecl(builder_->GetAsciiString(methodName), proto, type);
+
+ VRegRange* args = cIr->Alloc<VRegRange>(paramVReg, 1);
+
+ addInst(cIr, instructionAfter, opcode,
+ { args, cIr->Alloc<Method>(method, method->orig_index) });
+ }
+
+ std::shared_ptr<ir::DexFile> dexIr_;
+ std::unique_ptr<ir::Builder> builder_;
+
+ ir::Type* voidType_ = nullptr;
+ ir::Type* hookType_ = nullptr;
+ ir::Type* objectType_ = nullptr;
+};
std::pair<dex::u1*, size_t> maybeTransform(const char* name, size_t classDataLen,
const unsigned char* classData, dex::Writer::Allocator* allocator) {
@@ -209,8 +234,11 @@
reader.CreateClassIr(index);
std::shared_ptr<ir::DexFile> ir = reader.GetIr();
- if (!transform(ir)) {
- return std::make_pair(nullptr, 0);
+ {
+ Transformer transformer(ir);
+ if (!transformer.transform()) {
+ return std::make_pair(nullptr, 0);
+ }
}
size_t new_size;