upload android base code part4
This commit is contained in:
parent
b9e30e05b1
commit
78ea2404cd
23455 changed files with 5250148 additions and 0 deletions
45
android/cts/hostsidetests/theme/Android.mk
Normal file
45
android/cts/hostsidetests/theme/Android.mk
Normal file
|
@ -0,0 +1,45 @@
|
|||
# Copyright (C) 2014 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_SRC_FILES := $(call all-java-files-under, src)
|
||||
|
||||
# Special handling for pre-release builds where the SDK version has not been
|
||||
# updated, in which case we'll use the version codename (ex. "O").
|
||||
ifeq (REL,$(PLATFORM_VERSION_CODENAME))
|
||||
LOCAL_JAVA_RESOURCE_DIRS := assets/$(PLATFORM_SDK_VERSION)/
|
||||
else
|
||||
LOCAL_JAVA_RESOURCE_DIRS := assets/$(PLATFORM_VERSION_CODENAME)/
|
||||
endif
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
# Must match the package name in CtsTestCaseList.mk
|
||||
LOCAL_MODULE := CtsThemeHostTestCases
|
||||
|
||||
LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed compatibility-host-util
|
||||
|
||||
LOCAL_CTS_TEST_PACKAGE := android.host.theme
|
||||
|
||||
LOCAL_SDK_VERSION := current
|
||||
|
||||
# Tag this module as a cts test artifact
|
||||
LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
|
||||
|
||||
include $(BUILD_CTS_HOST_JAVA_LIBRARY)
|
||||
|
||||
include $(call all-makefiles-under,$(LOCAL_PATH))
|
26
android/cts/hostsidetests/theme/AndroidTest.xml
Normal file
26
android/cts/hostsidetests/theme/AndroidTest.xml
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2015 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<configuration description="Config for CTS Theme host test cases">
|
||||
<option name="config-descriptor:metadata" key="component" value="uitoolkit" />
|
||||
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
|
||||
<option name="cleanup-apks" value="true" />
|
||||
<option name="test-file-name" value="CtsThemeDeviceApp.apk" />
|
||||
</target_preparer>
|
||||
<test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
|
||||
<option name="jar" value="CtsThemeHostTestCases.jar" />
|
||||
<option name="runtime-hint" value="7m30s" />
|
||||
</test>
|
||||
</configuration>
|
119
android/cts/hostsidetests/theme/README
Normal file
119
android/cts/hostsidetests/theme/README
Normal file
|
@ -0,0 +1,119 @@
|
|||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
|
||||
|
||||
INTRODUCTION
|
||||
|
||||
The Android theme tests ensure that the Holo and Material themes have not been
|
||||
modified. They consist of API-specific sets of reference images representing
|
||||
specific themes and widgets that must be identical across devices. To pass the
|
||||
theme tests, a device must be able to generate images that are identical to the
|
||||
reference images.
|
||||
|
||||
NOTE: Reference images should only be updated by the CTS test maintainers. Any
|
||||
modifications to the reference images will invalidate the test results.
|
||||
|
||||
|
||||
INSTRUCTIONS
|
||||
|
||||
I. Generating reference images (CTS maintainers only)
|
||||
|
||||
Reference images are typically only generated for new API revisions. To
|
||||
generate a new set of reference images from an emulator, do the following:
|
||||
|
||||
1. Ensure the Android SDK is installed locally. Either a public or internal
|
||||
distribution is fine. From the console, set the ANDROID_SDK_ROOT env var:
|
||||
|
||||
export ANDROID_SDK_ROOT = /path/to/sdk
|
||||
|
||||
2. Obtain an x86_64 emulator image from the build server by using the script
|
||||
available internally at go/emu-dev. This script will install the image in
|
||||
your SDK.
|
||||
|
||||
3. Use the SDK's AVD Manager tool to create a single virtual device using the
|
||||
emulator image from step 2. The exact configuration doesn't really matter;
|
||||
you can use Nexus 5 as a template. Name the emulator "theme_emulator".
|
||||
|
||||
4. From the console, set up your build environment for x86_64 and build CTS:
|
||||
|
||||
lunch sdk_x86_64-eng && make cts -j32
|
||||
|
||||
5. Use the reference image script to generate the reference images. The script
|
||||
will automatically start the emulator in the required configurations and
|
||||
install the resulting reference images in assets/<platform>/<dpi>.zip,
|
||||
overwriting any existing images.
|
||||
|
||||
./cts/hostsidetests/theme/generate_images.py theme_emulator
|
||||
|
||||
You can also generate reference images using a real device. To generate a new set
|
||||
of reference images from a real device, do the following:
|
||||
|
||||
1. Connect the device. Verify the device is connected:
|
||||
|
||||
adb devices
|
||||
|
||||
2. Use the reference image script to generate the reference images:
|
||||
|
||||
./cts/hostsidetests/theme/generate_images.py
|
||||
|
||||
A complete collection of reference images for a given API revision must include
|
||||
a set for each possible DPI bucket (tvdpi, xxhdpi, etc.) that may be tested.
|
||||
|
||||
For a list of devices and their DPI buckets, see Device Metrics:
|
||||
|
||||
https://design.google.com/devices/
|
||||
|
||||
|
||||
II. Building theme tests
|
||||
|
||||
1. If you have not already built the CTS tests, run an initial make:
|
||||
|
||||
make cts -j32
|
||||
|
||||
2. Subsequent changes to the theme tests, including changes to the reference
|
||||
images, may be built using mmm:
|
||||
|
||||
mmm cts/hostsidetests/theme -j32
|
||||
|
||||
|
||||
III. Running theme tests
|
||||
|
||||
To obtain reliable results, theme tests should be run against the device's
|
||||
native density; however, many of the tests will also work in a scaled density.
|
||||
If you don't possess a device for a given density and would still like to run
|
||||
tests for that density, you can manually force scaling via:
|
||||
|
||||
adb shell wm density <dpi>
|
||||
|
||||
As of API 24, the results will NOT be 100% reliable due to scaling artifacts.
|
||||
To reset the device to its native density, run:
|
||||
|
||||
adb shell wm density reset
|
||||
|
||||
Once the device is in the desired state, do the following:
|
||||
|
||||
1. Connect the device that you wish to test. Confirm that is is connected with:
|
||||
|
||||
adb devices
|
||||
|
||||
2. Run the theme tests using cts-tradefed:
|
||||
|
||||
cts-tradefed run singleCommand cts-dev --module CtsThemeHostTestCases \
|
||||
--test android.theme.cts.ThemeHostTest
|
||||
|
||||
3. Wait for the tests to complete. This should take less than five minutes.
|
||||
|
||||
If any test failures are encountered, diff PNGs will be generated and collected
|
||||
in the "diffs" directory of the CTS results indicated by "Test Result:" in the
|
||||
test output.
|
135
android/cts/hostsidetests/theme/android_device.py
Normal file
135
android/cts/hostsidetests/theme/android_device.py
Normal file
|
@ -0,0 +1,135 @@
|
|||
#!/usr/bin/python3
|
||||
#
|
||||
# Copyright (C) 2015 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
|
||||
from subprocess import PIPE
|
||||
|
||||
|
||||
# class for running android device from python
|
||||
# it will fork the device processor
|
||||
class AndroidDevice(object):
|
||||
def __init__(self, serial):
|
||||
self._serial = serial
|
||||
|
||||
def run_adb_command(self, cmd, timeout=None):
|
||||
adb_cmd = "adb -s %s %s" % (self._serial, cmd)
|
||||
print(adb_cmd)
|
||||
|
||||
adb_process = subprocess.Popen(args=adb_cmd.split(), bufsize=-1, stderr=PIPE, stdout=PIPE)
|
||||
(out, err) = adb_process.communicate(timeout=timeout)
|
||||
return out.decode('utf-8').strip(), err.decode('utf-8').strip()
|
||||
|
||||
def run_shell_command(self, cmd):
|
||||
return self.run_adb_command("shell %s" % cmd)
|
||||
|
||||
def wait_for_device(self, timeout=30):
|
||||
return self.run_adb_command('wait-for-device', timeout)
|
||||
|
||||
def wait_for_prop(self, key, value, timeout=30):
|
||||
boot_complete = False
|
||||
attempts = 0
|
||||
wait_period = 1
|
||||
while not boot_complete and (attempts*wait_period) < timeout:
|
||||
(out, err) = self.run_shell_command("getprop %s" % key)
|
||||
if out == value:
|
||||
boot_complete = True
|
||||
else:
|
||||
time.sleep(wait_period)
|
||||
attempts += 1
|
||||
if not boot_complete:
|
||||
print("%s not set to %s within timeout!" % (key, value))
|
||||
return boot_complete
|
||||
|
||||
def wait_for_service(self, name, timeout=30):
|
||||
service_found = False
|
||||
attempts = 0
|
||||
wait_period = 1
|
||||
while not service_found and (attempts*wait_period) < timeout:
|
||||
(output, err) = self.run_shell_command("service check %s" % name)
|
||||
if 'not found' not in output:
|
||||
service_found = True
|
||||
else:
|
||||
time.sleep(wait_period)
|
||||
attempts += 1
|
||||
if not service_found:
|
||||
print("Service '%s' not found within timeout!" % name)
|
||||
return service_found
|
||||
|
||||
def wait_for_boot_complete(self, timeout=60):
|
||||
return self.wait_for_prop('dev.bootcomplete', '1', timeout)
|
||||
|
||||
def install_apk(self, apk_path):
|
||||
self.wait_for_service('package')
|
||||
(out, err) = self.run_adb_command("install -r -d -g %s" % apk_path)
|
||||
result = out.split()
|
||||
return out, err, "Success" in result
|
||||
|
||||
def uninstall_package(self, package):
|
||||
self.wait_for_service('package')
|
||||
(out, err) = self.run_adb_command("uninstall %s" % package)
|
||||
result = out.split()
|
||||
return "Success" in result
|
||||
|
||||
def run_instrumentation_test(self, option):
|
||||
self.wait_for_service('activity')
|
||||
return self.run_shell_command("am instrument -w --no-window-animation %s" % option)
|
||||
|
||||
def is_process_alive(self, process_name):
|
||||
(out, err) = self.run_shell_command("ps")
|
||||
names = out.split()
|
||||
# very lazy implementation as it does not filter out things like uid
|
||||
# should work mostly unless processName is too simple to overlap with
|
||||
# uid. So only use name like com.android.xyz
|
||||
return process_name in names
|
||||
|
||||
def get_version_sdk(self):
|
||||
return int(self.run_shell_command("getprop ro.build.version.sdk")[0])
|
||||
|
||||
def get_version_codename(self):
|
||||
return self.run_shell_command("getprop ro.build.version.codename")[0].strip()
|
||||
|
||||
def get_density(self):
|
||||
if "emulator" in self._serial:
|
||||
return int(self.run_shell_command("getprop qemu.sf.lcd_density")[0])
|
||||
else:
|
||||
return int(self.run_shell_command("getprop ro.sf.lcd_density")[0])
|
||||
|
||||
def get_orientation(self):
|
||||
return int(self.run_shell_command("dumpsys | grep SurfaceOrientation")[0].split()[1])
|
||||
|
||||
|
||||
def enumerate_android_devices(require_prefix=''):
|
||||
devices = subprocess.check_output(["adb", "devices"])
|
||||
if not devices:
|
||||
return []
|
||||
|
||||
devices = devices.decode('UTF-8').split('\n')[1:]
|
||||
device_list = []
|
||||
|
||||
for device in devices:
|
||||
if device is not "" and device.startswith(require_prefix):
|
||||
info = device.split('\t')
|
||||
if info[1] == "device":
|
||||
device_list.append(info[0])
|
||||
|
||||
return device_list
|
43
android/cts/hostsidetests/theme/app/Android.mk
Normal file
43
android/cts/hostsidetests/theme/app/Android.mk
Normal file
|
@ -0,0 +1,43 @@
|
|||
# Copyright (C) 2014 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)
|
||||
|
||||
# Don't include this package in any target.
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
# When built, explicitly put it in the data partition.
|
||||
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
|
||||
# and because it is in data, do not strip classes.dex
|
||||
LOCAL_DEX_PREOPT := false
|
||||
|
||||
LOCAL_PROGUARD_ENABLED := disabled
|
||||
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
|
||||
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||
|
||||
#Flag to tell the Android Asset Packaging Tool not to strip for some densities
|
||||
LOCAL_AAPT_INCLUDE_ALL_RESOURCES := true
|
||||
|
||||
LOCAL_PACKAGE_NAME := CtsThemeDeviceApp
|
||||
|
||||
# Tag this module as a cts test artifact
|
||||
LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
|
||||
|
||||
LOCAL_SDK_VERSION := 23
|
||||
|
||||
include $(BUILD_CTS_SUPPORT_PACKAGE)
|
46
android/cts/hostsidetests/theme/app/AndroidManifest.xml
Executable file
46
android/cts/hostsidetests/theme/app/AndroidManifest.xml
Executable file
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
* Copyright (C) 2014 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="android.theme.app">
|
||||
|
||||
<uses-sdk android:minSdkVersion="17" />
|
||||
|
||||
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
|
||||
<application>
|
||||
<uses-library android:name="android.test.runner" />
|
||||
<activity android:name=".ThemeDeviceActivity"
|
||||
android:screenOrientation="portrait">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".GenerateImagesActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
|
||||
android:exported="true" />
|
||||
</application>
|
||||
|
||||
<!-- self-instrumenting test package. -->
|
||||
<instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
|
||||
android:targetPackage="android.theme.app"
|
||||
android:label="Generates Theme reference images"/>
|
||||
|
||||
</manifest>
|
20
android/cts/hostsidetests/theme/app/res/layout/button.xml
Normal file
20
android/cts/hostsidetests/theme/app/res/layout/button.xml
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<Button xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/button"
|
||||
/>
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<CalendarView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
/>
|
21
android/cts/hostsidetests/theme/app/res/layout/checkbox.xml
Normal file
21
android/cts/hostsidetests/theme/app/res/layout/checkbox.xml
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:text="@string/checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<Chronometer xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/textview"
|
||||
android:textColor="@android:color/holo_blue_bright"
|
||||
/>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/textview"
|
||||
android:textColor="@android:color/holo_blue_dark"
|
||||
/>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/textview"
|
||||
android:textColor="@android:color/holo_blue_light"
|
||||
/>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/textview"
|
||||
android:textColor="@android:color/holo_green_dark"
|
||||
/>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/textview"
|
||||
android:textColor="@android:color/holo_green_light"
|
||||
/>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/textview"
|
||||
android:textColor="@android:color/holo_orange_dark"
|
||||
/>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/textview"
|
||||
android:textColor="@android:color/holo_orange_light"
|
||||
/>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/textview"
|
||||
android:textColor="@android:color/holo_purple"
|
||||
/>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/textview"
|
||||
android:textColor="@android:color/holo_red_dark"
|
||||
/>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/textview"
|
||||
android:textColor="@android:color/holo_red_light"
|
||||
/>
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<DatePicker xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
19
android/cts/hostsidetests/theme/app/res/layout/edittext.xml
Normal file
19
android/cts/hostsidetests/theme/app/res/layout/edittext.xml
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
19
android/cts/hostsidetests/theme/app/res/layout/empty.xml
Normal file
19
android/cts/hostsidetests/theme/app/res/layout/empty.xml
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="0dip"
|
||||
/>
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:progress="0"
|
||||
android:max="100"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
/>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:progress="100"
|
||||
android:max="100"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
/>
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/progressBar1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:progress="50"
|
||||
android:max="100"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
/>
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="?android:attr/progressBarStyleLarge"
|
||||
/>
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="?android:attr/progressBarStyleSmall"
|
||||
/>
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<RadioButton xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/radiobutton"
|
||||
/>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<RadioButton xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="@string/radiobutton_checked"
|
||||
/>
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<RadioGroup xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<RadioButton android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/radiobutton_1"
|
||||
/>
|
||||
<RadioButton android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/radiobutton_2"
|
||||
/>
|
||||
</RadioGroup>
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<RadioGroup xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<RadioButton android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/radiobutton_1"
|
||||
/>
|
||||
<RadioButton android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/radiobutton_2"
|
||||
/>
|
||||
</RadioGroup>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<RatingBar xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:rating="0"
|
||||
android:numStars="5"
|
||||
/>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<RatingBar xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:rating="2.5"
|
||||
android:numStars="5"
|
||||
/>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<RatingBar xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:rating="5"
|
||||
android:numStars="5"
|
||||
/>
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<SearchView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
21
android/cts/hostsidetests/theme/app/res/layout/seekbar_0.xml
Normal file
21
android/cts/hostsidetests/theme/app/res/layout/seekbar_0.xml
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<SeekBar xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:progress="0"
|
||||
android:max="100"
|
||||
/>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<SeekBar xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:progress="100"
|
||||
android:max="100"
|
||||
/>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<SeekBar xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:progress="50"
|
||||
android:max="100"
|
||||
/>
|
21
android/cts/hostsidetests/theme/app/res/layout/spinner.xml
Normal file
21
android/cts/hostsidetests/theme/app/res/layout/spinner.xml
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<Spinner xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:prompt="@string/spinner_prompt"
|
||||
android:entries="@array/spinner_entries"
|
||||
/>
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<Switch xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/switch_button"
|
||||
/>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<Switch xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="@string/switch_button"
|
||||
/>
|
20
android/cts/hostsidetests/theme/app/res/layout/textview.xml
Normal file
20
android/cts/hostsidetests/theme/app/res/layout/textview.xml
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/textview"
|
||||
/>
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:focusable="true"
|
||||
android:keepScreenOn="true"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<android.theme.app.ReferenceViewGroup
|
||||
android:id="@+id/reference_view_group"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
/>
|
||||
</LinearLayout>
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<TimePicker xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<ToggleButton xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<ToggleButton xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
/>
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<ZoomControls xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
22
android/cts/hostsidetests/theme/app/res/values/arrays.xml
Normal file
22
android/cts/hostsidetests/theme/app/res/values/arrays.xml
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<resources>
|
||||
<string-array name="spinner_entries">
|
||||
<item>Spinner 1</item>
|
||||
<item>Spinner 2</item>
|
||||
<item>Spinner 3</item>
|
||||
</string-array>
|
||||
</resources>
|
19
android/cts/hostsidetests/theme/app/res/values/dimens.xml
Normal file
19
android/cts/hostsidetests/theme/app/res/values/dimens.xml
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<resources>
|
||||
<dimen name="reference_width">320dp</dimen>
|
||||
<dimen name="reference_height">480dp</dimen>
|
||||
</resources>
|
82
android/cts/hostsidetests/theme/app/res/values/strings.xml
Normal file
82
android/cts/hostsidetests/theme/app/res/values/strings.xml
Normal file
|
@ -0,0 +1,82 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<resources>
|
||||
<string name="display_info">Display Info</string>
|
||||
<string name="display_info_text">Density DPI: %1$d\nDensity Bucket: %2$s\nWidth DP: %3$d\nHeight DP: %4$d</string>
|
||||
|
||||
<string name="button">Button</string>
|
||||
<string name="checkbox">CheckBox</string>
|
||||
<string name="chronometer">Chronometer</string>
|
||||
<string name="datepicker">DatePicker</string>
|
||||
<string name="edittext">EditText</string>
|
||||
<string name="progressbar">ProgressBar</string>
|
||||
<string name="progressbar_small">ProgressBar Small</string>
|
||||
<string name="progressbar_large">ProgressBar Large</string>
|
||||
<string name="progressbar_horizontal_0">ProgressBar Horizontal 0%</string>
|
||||
<string name="progressbar_horizontal_50">ProgressBar Horizontal 50%</string>
|
||||
<string name="progressbar_horizontal_100">ProgressBar Horizontal 100%</string>
|
||||
<string name="radiobutton">RadioButton</string>
|
||||
<string name="radiobutton_checked">RadioButton Checked</string>
|
||||
<string name="radiogroup_horizontal">RadioGroup Horizontal</string>
|
||||
<string name="radiogroup_vertical">RadioGroup Vertical</string>
|
||||
<string name="ratingbar_0">RatingBar 0 Stars</string>
|
||||
<string name="ratingbar_2point5">RatingBar 2.5 Stars</string>
|
||||
<string name="ratingbar_5">RatingBar 5 Stars</string>
|
||||
<string name="ratingbar_0_pressed">RatingBar 0 Stars Pressed</string>
|
||||
<string name="ratingbar_2point5_pressed">RatingBar 2.5 Stars Pressed</string>
|
||||
<string name="ratingbar_5_pressed">RatingBar 5 Stars Pressed</string>
|
||||
<string name="searchview">SearchView</string>
|
||||
<string name="searchview_query">SearchView Query</string>
|
||||
<string name="searchview_query_hint">SearchView Query Hint</string>
|
||||
<string name="seekbar_0">SeekBar 0%</string>
|
||||
<string name="seekbar_50">SeekBar 50%</string>
|
||||
<string name="seekbar_100">SeekBar 100%</string>
|
||||
<string name="spinner">Spinner</string>
|
||||
<string name="switch_button">Switch</string>
|
||||
<string name="switch_button_checked">Switch Checked</string>
|
||||
<string name="tabhost">TabHost</string>
|
||||
<string name="textview">TextView</string>
|
||||
<string name="timepicker">TimePicker</string>
|
||||
<string name="togglebutton">ToggleButton</string>
|
||||
<string name="togglebutton_checked">ToggleButton Checked</string>
|
||||
<string name="zoomcontrols">ZoomControls</string>
|
||||
|
||||
<string name="alertdialog_onebutton">AlertDialog One Button</string>
|
||||
<string name="alertdialog_twobuttons">AlertDialog Two Buttons</string>
|
||||
<string name="alertdialog_threebuttons">AlertDialog Three Buttons</string>
|
||||
<string name="alertdialog_list">AlertDialog List</string>
|
||||
<string name="alertdialog_singlechoice">AlertDialog Single Choice</string>
|
||||
<string name="alertdialog_multichoice">AlertDialog Multiple Choice</string>
|
||||
<string name="progressdialog_spinner">ProgressDialog Spinner</string>
|
||||
<string name="progressdialog_horizontal">ProgressDialog Horizontal</string>
|
||||
|
||||
<string name="color_blue_bright">Bright Blue Color</string>
|
||||
<string name="color_blue_dark">Dark Blue Color</string>
|
||||
<string name="color_blue_light">Light Blue Color</string>
|
||||
<string name="color_green_dark">Dark Green Color</string>
|
||||
<string name="color_green_light">Light Green Color</string>
|
||||
<string name="color_orange_dark">Dark Orange Color</string>
|
||||
<string name="color_orange_light">Light Orange Color</string>
|
||||
<string name="color_purple">Purple Color</string>
|
||||
<string name="color_red_dark">Dark Red Color</string>
|
||||
<string name="color_red_light">Light Red Color</string>
|
||||
|
||||
<string name="spinner_prompt">Spinner Prompt</string>
|
||||
<string name="radiobutton_1">Radio Button 1</string>
|
||||
<string name="radiobutton_2">Radio Button 2</string>
|
||||
<string name="loading">Loading...</string>
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.theme.app;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Bitmap.CompressFormat;
|
||||
import android.graphics.Canvas;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
/**
|
||||
* A task which gets the UI element to render to a bitmap and then saves that
|
||||
* as a PNG asynchronously.
|
||||
*/
|
||||
class GenerateBitmapTask extends AsyncTask<Void, Void, Boolean> {
|
||||
private static final String TAG = "GenerateBitmapTask";
|
||||
|
||||
private final View mView;
|
||||
private final File mOutDir;
|
||||
|
||||
private Bitmap mBitmap;
|
||||
|
||||
protected final String mName;
|
||||
|
||||
public GenerateBitmapTask(View view, File outDir, String name) {
|
||||
mView = view;
|
||||
mOutDir = outDir;
|
||||
mName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
if (mView.getWidth() == 0 || mView.getHeight() == 0) {
|
||||
Log.e(TAG, "Unable to draw view due to incorrect size: " + mName);
|
||||
return;
|
||||
}
|
||||
|
||||
mBitmap = Bitmap.createBitmap(mView.getWidth(), mView.getHeight(),
|
||||
Bitmap.Config.ARGB_8888);
|
||||
|
||||
final Canvas canvas = new Canvas(mBitmap);
|
||||
mView.draw(canvas);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... ignored) {
|
||||
final Bitmap bitmap = mBitmap;
|
||||
if (bitmap == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final File file = new File(mOutDir, mName + ".png");
|
||||
if (file.exists() && !file.canWrite()) {
|
||||
Log.e(TAG, "Unable to write file: " + file.getAbsolutePath());
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean success = false;
|
||||
try {
|
||||
FileOutputStream stream = null;
|
||||
try {
|
||||
stream = new FileOutputStream(file);
|
||||
success = bitmap.compress(CompressFormat.PNG, 100, stream);
|
||||
} finally {
|
||||
if (stream != null) {
|
||||
stream.flush();
|
||||
stream.close();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, e.getMessage());
|
||||
} finally {
|
||||
bitmap.recycle();
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,225 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.theme.app;
|
||||
|
||||
import android.Manifest.permission;
|
||||
import android.app.Activity;
|
||||
import android.app.KeyguardManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build.VERSION;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import android.view.WindowManager.LayoutParams;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Generates images by iterating through all themes and launching instances of
|
||||
* {@link ThemeDeviceActivity}.
|
||||
*/
|
||||
public class GenerateImagesActivity extends Activity {
|
||||
private static final String TAG = "GenerateImagesActivity";
|
||||
|
||||
private static final String OUT_DIR = "cts-theme-assets";
|
||||
private static final int REQUEST_CODE = 1;
|
||||
|
||||
public static final String EXTRA_REASON = "reason";
|
||||
|
||||
private final CountDownLatch mLatch = new CountDownLatch(1);
|
||||
|
||||
private File mOutputDir;
|
||||
private File mOutputZip;
|
||||
|
||||
private int mCurrentTheme;
|
||||
private String mFinishReason;
|
||||
private boolean mFinishSuccess;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON
|
||||
| LayoutParams.FLAG_TURN_SCREEN_ON
|
||||
| LayoutParams.FLAG_DISMISS_KEYGUARD);
|
||||
|
||||
mOutputDir = new File(Environment.getExternalStorageDirectory(), OUT_DIR);
|
||||
ThemeTestUtils.deleteDirectory(mOutputDir);
|
||||
mOutputDir.mkdirs();
|
||||
|
||||
if (!mOutputDir.exists()) {
|
||||
finish("Failed to create output directory " + mOutputDir.getAbsolutePath(), false);
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean canDisableKeyguard = checkCallingOrSelfPermission(
|
||||
permission.DISABLE_KEYGUARD) == PackageManager.PERMISSION_GRANTED;
|
||||
if (!canDisableKeyguard) {
|
||||
finish("Not granted permission to disable keyguard", false);
|
||||
return;
|
||||
}
|
||||
|
||||
new KeyguardCheck(this) {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
generateNextImage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure() {
|
||||
finish("Device is locked", false);
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
public boolean isFinishSuccess() {
|
||||
return mFinishSuccess;
|
||||
}
|
||||
|
||||
public String getFinishReason() {
|
||||
return mFinishReason;
|
||||
}
|
||||
|
||||
static abstract class KeyguardCheck implements Runnable {
|
||||
private static final int MAX_RETRIES = 3;
|
||||
private static final int RETRY_DELAY = 500;
|
||||
|
||||
private final Handler mHandler;
|
||||
private final KeyguardManager mKeyguard;
|
||||
|
||||
private int mRetries;
|
||||
|
||||
public KeyguardCheck(Context context) {
|
||||
mHandler = new Handler(context.getMainLooper());
|
||||
mKeyguard = (KeyguardManager) context.getSystemService(KEYGUARD_SERVICE);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
mRetries = 0;
|
||||
|
||||
mHandler.removeCallbacks(this);
|
||||
mHandler.post(this);
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
mHandler.removeCallbacks(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!mKeyguard.isKeyguardLocked()) {
|
||||
onSuccess();
|
||||
} else if (mRetries < MAX_RETRIES) {
|
||||
mRetries++;
|
||||
mHandler.postDelayed(this, RETRY_DELAY);
|
||||
} else {
|
||||
onFailure();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public abstract void onSuccess();
|
||||
public abstract void onFailure();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the activity to generate the next image.
|
||||
*/
|
||||
private boolean generateNextImage() {
|
||||
final ThemeDeviceActivity.Theme theme = ThemeDeviceActivity.THEMES[mCurrentTheme];
|
||||
if (theme.apiLevel > VERSION.SDK_INT) {
|
||||
Log.v(TAG, "Skipping theme \"" + theme.name
|
||||
+ "\" (requires API " + theme.apiLevel + ")");
|
||||
return false;
|
||||
}
|
||||
|
||||
Log.v(TAG, "Generating images for theme \"" + theme.name + "\"...");
|
||||
|
||||
final Intent intent = new Intent(this, ThemeDeviceActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
intent.putExtra(ThemeDeviceActivity.EXTRA_THEME, mCurrentTheme);
|
||||
intent.putExtra(ThemeDeviceActivity.EXTRA_OUTPUT_DIR, mOutputDir.getAbsolutePath());
|
||||
startActivityForResult(intent, REQUEST_CODE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (resultCode != RESULT_OK) {
|
||||
finish("Failed to generate images for theme " + mCurrentTheme + " ("
|
||||
+ data.getStringExtra(EXTRA_REASON) + ")", false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Keep trying themes until one works.
|
||||
boolean success = false;
|
||||
while (++mCurrentTheme < ThemeDeviceActivity.THEMES.length && !success) {
|
||||
success = generateNextImage();
|
||||
}
|
||||
|
||||
// If we ran out of themes, we're done.
|
||||
if (!success) {
|
||||
compressOutput();
|
||||
|
||||
finish("Image generation complete!", true);
|
||||
}
|
||||
}
|
||||
|
||||
private void compressOutput() {
|
||||
mOutputZip = new File(mOutputDir.getParentFile(), mOutputDir.getName() + ".zip");
|
||||
|
||||
if (mOutputZip.exists()) {
|
||||
// Remove any old test results.
|
||||
mOutputZip.delete();
|
||||
}
|
||||
|
||||
try {
|
||||
ThemeTestUtils.compressDirectory(mOutputDir, mOutputZip);
|
||||
ThemeTestUtils.deleteDirectory(mOutputDir);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void finish(String reason, boolean success) {
|
||||
mFinishSuccess = success;
|
||||
mFinishReason = reason;
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
mLatch.countDown();
|
||||
|
||||
super.finish();
|
||||
}
|
||||
|
||||
public File getOutputZip() {
|
||||
return mOutputZip;
|
||||
}
|
||||
|
||||
public boolean waitForCompletion(long timeoutMillis) throws InterruptedException {
|
||||
return mLatch.await(timeoutMillis, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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.theme.app;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* Interface used to do further setup on a view after it has been inflated.
|
||||
*/
|
||||
public interface LayoutModifier {
|
||||
|
||||
/** Actions to take before inflating the view. */
|
||||
void prepare();
|
||||
|
||||
/**
|
||||
* @param view inflated by the test activity
|
||||
* @return the same view or another view that will be snapshotted by the test
|
||||
*/
|
||||
View modifyView(View view);
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.theme.app;
|
||||
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Activity test case used to instrument generation of reference images.
|
||||
*/
|
||||
public class ReferenceImagesTest extends ActivityInstrumentationTestCase2<GenerateImagesActivity> {
|
||||
|
||||
/** Overall test timeout is 30 minutes. Should only take about 5. */
|
||||
private static final int TEST_RESULT_TIMEOUT = 30 * 60 * 1000;
|
||||
|
||||
public ReferenceImagesTest() {
|
||||
super(GenerateImagesActivity.class);
|
||||
}
|
||||
|
||||
public void testGenerateReferenceImages() throws Exception {
|
||||
setActivityInitialTouchMode(true);
|
||||
|
||||
final GenerateImagesActivity activity = getActivity();
|
||||
assertTrue("Activity failed to complete within " + TEST_RESULT_TIMEOUT + " ms",
|
||||
activity.waitForCompletion(TEST_RESULT_TIMEOUT));
|
||||
assertTrue(activity.getFinishReason(), activity.isFinishSuccess());
|
||||
|
||||
final File outputZip = activity.getOutputZip();
|
||||
assertTrue("Failed to generate reference image ZIP",
|
||||
outputZip != null && outputZip.exists());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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.theme.app;
|
||||
|
||||
import android.theme.app.R;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
/**
|
||||
* {@link ViewGroup} that inflates to a reference width and height.
|
||||
*/
|
||||
public class ReferenceViewGroup extends ViewGroup {
|
||||
|
||||
private final int mWidthDp;
|
||||
private final int mHeightDp;
|
||||
|
||||
public ReferenceViewGroup(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ReferenceViewGroup(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
Resources resources = context.getResources();
|
||||
mWidthDp = resources.getDimensionPixelSize(R.dimen.reference_width);
|
||||
mHeightDp = resources.getDimensionPixelSize(R.dimen.reference_height);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
widthMeasureSpec = getMeasureSpec(LayoutParams.MATCH_PARENT, mWidthDp);
|
||||
heightMeasureSpec = getMeasureSpec(LayoutParams.MATCH_PARENT, mHeightDp);
|
||||
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
|
||||
int childCount = getChildCount();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
View child = getChildAt(i);
|
||||
LayoutParams params = child.getLayoutParams();
|
||||
int width = getMeasureSpec(params.width, mWidthDp);
|
||||
int height = getMeasureSpec(params.height, mHeightDp);
|
||||
child.measure(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
private int getMeasureSpec(int value, int size) {
|
||||
if (value == LayoutParams.MATCH_PARENT) {
|
||||
return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
|
||||
} else if (value == LayoutParams.WRAP_CONTENT) {
|
||||
return MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST);
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
int childCount = getChildCount();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
View child = getChildAt(i);
|
||||
child.layout(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,420 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.theme.app;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.theme.app.modifiers.DatePickerModifier;
|
||||
import android.theme.app.modifiers.ProgressBarModifier;
|
||||
import android.theme.app.modifiers.SearchViewModifier;
|
||||
import android.theme.app.modifiers.TimePickerModifier;
|
||||
import android.theme.app.modifiers.ViewCheckedModifier;
|
||||
import android.theme.app.modifiers.ViewPressedModifier;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager.LayoutParams;
|
||||
import android.widget.DatePicker;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.Override;
|
||||
|
||||
/**
|
||||
* A activity which display various UI elements with non-modifiable themes.
|
||||
*/
|
||||
public class ThemeDeviceActivity extends Activity {
|
||||
public static final String EXTRA_THEME = "theme";
|
||||
public static final String EXTRA_OUTPUT_DIR = "outputDir";
|
||||
|
||||
private static final String TAG = "ThemeDeviceActivity";
|
||||
|
||||
/**
|
||||
* Delay that allows the Holo-style CalendarView to settle to its final
|
||||
* position.
|
||||
*/
|
||||
private static final long HOLO_CALENDAR_VIEW_ADJUSTMENT_DURATION = 540;
|
||||
|
||||
private Theme mTheme;
|
||||
private ReferenceViewGroup mViewGroup;
|
||||
private File mOutputDir;
|
||||
private int mLayoutIndex;
|
||||
private boolean mIsRunning;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
|
||||
final Intent intent = getIntent();
|
||||
final int themeIndex = intent.getIntExtra(EXTRA_THEME, -1);
|
||||
if (themeIndex < 0) {
|
||||
Log.e(TAG, "No theme specified");
|
||||
finish();
|
||||
}
|
||||
|
||||
final String outputDir = intent.getStringExtra(EXTRA_OUTPUT_DIR);
|
||||
if (outputDir == null) {
|
||||
Log.e(TAG, "No output directory specified");
|
||||
finish();
|
||||
}
|
||||
|
||||
mOutputDir = new File(outputDir);
|
||||
mTheme = THEMES[themeIndex];
|
||||
|
||||
setTheme(mTheme.id);
|
||||
setContentView(R.layout.theme_test);
|
||||
|
||||
mViewGroup = (ReferenceViewGroup) findViewById(R.id.reference_view_group);
|
||||
|
||||
getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON
|
||||
| LayoutParams.FLAG_TURN_SCREEN_ON
|
||||
| LayoutParams.FLAG_DISMISS_KEYGUARD );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
mIsRunning = true;
|
||||
|
||||
setNextLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
mIsRunning = false;
|
||||
|
||||
if (!isFinishing()) {
|
||||
// The activity paused for some reason, likely a system crash
|
||||
// dialog. Finish it so we can move to the next theme.
|
||||
Log.w(TAG, "onPause() called without a call to finish()", new RuntimeException());
|
||||
finish();
|
||||
}
|
||||
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
if (mLayoutIndex < LAYOUTS.length) {
|
||||
final Intent data = new Intent();
|
||||
data.putExtra(GenerateImagesActivity.EXTRA_REASON, "Only rendered "
|
||||
+ mLayoutIndex + "/" + LAYOUTS.length + " layouts");
|
||||
setResult(RESULT_CANCELED, data);
|
||||
}
|
||||
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the next layout in the UI.
|
||||
*/
|
||||
private void setNextLayout() {
|
||||
if (mLayoutIndex >= LAYOUTS.length) {
|
||||
setResult(RESULT_OK);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
mViewGroup.removeAllViews();
|
||||
|
||||
final Layout layout = LAYOUTS[mLayoutIndex++];
|
||||
final String layoutName = String.format("%s_%s", mTheme.name, layout.name);
|
||||
final View view = getLayoutInflater().inflate(layout.id, mViewGroup, false);
|
||||
if (layout.modifier != null) {
|
||||
layout.modifier.modifyView(view);
|
||||
}
|
||||
|
||||
mViewGroup.addView(view);
|
||||
view.setFocusable(false);
|
||||
|
||||
Log.v(TAG, "Rendering layout " + layoutName
|
||||
+ " (" + mLayoutIndex + "/" + LAYOUTS.length + ")");
|
||||
|
||||
final Runnable generateBitmapRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
new BitmapTask(view, layoutName).execute();
|
||||
}
|
||||
};
|
||||
|
||||
if (view instanceof DatePicker && mTheme.spec == Theme.HOLO) {
|
||||
// The Holo-styled DatePicker uses a CalendarView that has a
|
||||
// non-configurable adjustment duration of 540ms.
|
||||
view.postDelayed(generateBitmapRunnable, HOLO_CALENDAR_VIEW_ADJUSTMENT_DURATION);
|
||||
} else {
|
||||
view.post(generateBitmapRunnable);
|
||||
}
|
||||
}
|
||||
|
||||
private class BitmapTask extends GenerateBitmapTask {
|
||||
public BitmapTask(View view, String name) {
|
||||
super(view, mOutputDir, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean success) {
|
||||
if (success && mIsRunning) {
|
||||
setNextLayout();
|
||||
} else {
|
||||
Log.e(TAG, "Failed to render view to bitmap: " + mName + " (activity running? "
|
||||
+ mIsRunning + ")");
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A class to encapsulate information about a theme.
|
||||
*/
|
||||
static class Theme {
|
||||
public static final int HOLO = 0;
|
||||
public static final int MATERIAL = 1;
|
||||
|
||||
public final int spec;
|
||||
public final int id;
|
||||
public final int apiLevel;
|
||||
public final String name;
|
||||
|
||||
private Theme(int spec, int id, int apiLevel, String name) {
|
||||
this.spec = spec;
|
||||
this.id = id;
|
||||
this.apiLevel = apiLevel;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
// List of themes to verify.
|
||||
static final Theme[] THEMES = {
|
||||
// Holo
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo,
|
||||
Build.VERSION_CODES.HONEYCOMB, "holo"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_Dialog,
|
||||
Build.VERSION_CODES.HONEYCOMB, "holo_dialog"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_Dialog_MinWidth,
|
||||
Build.VERSION_CODES.HONEYCOMB, "holo_dialog_minwidth"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_Dialog_NoActionBar,
|
||||
Build.VERSION_CODES.HONEYCOMB, "holo_dialog_noactionbar"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_Dialog_NoActionBar_MinWidth,
|
||||
Build.VERSION_CODES.HONEYCOMB, "holo_dialog_noactionbar_minwidth"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_DialogWhenLarge,
|
||||
Build.VERSION_CODES.HONEYCOMB, "holo_dialogwhenlarge"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_DialogWhenLarge_NoActionBar,
|
||||
Build.VERSION_CODES.HONEYCOMB, "holo_dialogwhenlarge_noactionbar"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_InputMethod,
|
||||
Build.VERSION_CODES.HONEYCOMB, "holo_inputmethod"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_NoActionBar,
|
||||
Build.VERSION_CODES.HONEYCOMB, "holo_noactionbar"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_NoActionBar_Fullscreen,
|
||||
Build.VERSION_CODES.HONEYCOMB, "holo_noactionbar_fullscreen"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_NoActionBar_Overscan,
|
||||
Build.VERSION_CODES.JELLY_BEAN_MR2, "holo_noactionbar_overscan"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_NoActionBar_TranslucentDecor,
|
||||
Build.VERSION_CODES.KITKAT, "holo_noactionbar_translucentdecor"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_Panel,
|
||||
Build.VERSION_CODES.HONEYCOMB, "holo_panel"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_Wallpaper,
|
||||
Build.VERSION_CODES.HONEYCOMB, "holo_wallpaper"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_Wallpaper_NoTitleBar,
|
||||
Build.VERSION_CODES.HONEYCOMB, "holo_wallpaper_notitlebar"),
|
||||
|
||||
// Holo Light
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light,
|
||||
Build.VERSION_CODES.HONEYCOMB, "holo_light"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_DarkActionBar,
|
||||
Build.VERSION_CODES.ICE_CREAM_SANDWICH, "holo_light_darkactionbar"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_Dialog,
|
||||
Build.VERSION_CODES.HONEYCOMB, "holo_light_dialog"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_Dialog_MinWidth,
|
||||
Build.VERSION_CODES.HONEYCOMB, "holo_light_dialog_minwidth"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_Dialog_NoActionBar,
|
||||
Build.VERSION_CODES.HONEYCOMB, "holo_light_dialog_noactionbar"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_Dialog_NoActionBar_MinWidth,
|
||||
Build.VERSION_CODES.HONEYCOMB, "holo_light_dialog_noactionbar_minwidth"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_DialogWhenLarge,
|
||||
Build.VERSION_CODES.HONEYCOMB, "holo_light_dialogwhenlarge"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_DialogWhenLarge_NoActionBar,
|
||||
Build.VERSION_CODES.HONEYCOMB, "holo_light_dialogwhenlarge_noactionbar"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_NoActionBar,
|
||||
Build.VERSION_CODES.HONEYCOMB_MR2, "holo_light_noactionbar"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_NoActionBar_Fullscreen,
|
||||
Build.VERSION_CODES.HONEYCOMB_MR2, "holo_light_noactionbar_fullscreen"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_NoActionBar_Overscan,
|
||||
Build.VERSION_CODES.JELLY_BEAN_MR2, "holo_light_noactionbar_overscan"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_NoActionBar_TranslucentDecor,
|
||||
Build.VERSION_CODES.KITKAT, "holo_light_noactionbar_translucentdecor"),
|
||||
new Theme(Theme.HOLO, android.R.style.Theme_Holo_Light_Panel,
|
||||
Build.VERSION_CODES.HONEYCOMB, "holo_light_panel"),
|
||||
|
||||
// Material
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Dialog,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_dialog"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Dialog_Alert,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_dialog_alert"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Dialog_MinWidth,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_dialog_minwidth"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Dialog_NoActionBar,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_dialog_noactionbar"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Dialog_NoActionBar_MinWidth,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_dialog_noactionbar_minwidth"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Dialog_Presentation,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_dialog_presentation"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_DialogWhenLarge,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_dialogwhenlarge"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_DialogWhenLarge_NoActionBar,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_dialogwhenlarge_noactionbar"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_InputMethod,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_inputmethod"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_NoActionBar,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_noactionbar"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_NoActionBar_Fullscreen,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_noactionbar_fullscreen"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_NoActionBar_Overscan,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_noactionbar_overscan"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_NoActionBar_TranslucentDecor,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_noactionbar_translucentdecor"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Panel,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_panel"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Settings,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_settings"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Voice,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_voice"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Wallpaper,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_wallpaper"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Wallpaper_NoTitleBar,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_wallpaper_notitlebar"),
|
||||
|
||||
// Material Light
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_light"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_DarkActionBar,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_light_darkactionbar"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_Dialog,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_light_dialog"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_Dialog_Alert,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_light_dialog_alert"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_Dialog_MinWidth,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_light_dialog_minwidth"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_Dialog_NoActionBar,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_light_dialog_noactionbar"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_Dialog_NoActionBar_MinWidth,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_light_dialog_noactionbar_minwidth"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_Dialog_Presentation,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_light_dialog_presentation"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_DialogWhenLarge,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_light_dialogwhenlarge"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_DialogWhenLarge_NoActionBar,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_light_dialogwhenlarge_noactionbar"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_LightStatusBar,
|
||||
Build.VERSION_CODES.M, "material_light_lightstatusbar"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_NoActionBar,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_light_noactionbar"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_NoActionBar_Fullscreen,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_light_noactionbar_fullscreen"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_NoActionBar_Overscan,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_light_noactionbar_overscan"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_NoActionBar_TranslucentDecor,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_light_noactionbar_translucentdecor"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_Panel,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_light_panel"),
|
||||
new Theme(Theme.MATERIAL, android.R.style.Theme_Material_Light_Voice,
|
||||
Build.VERSION_CODES.LOLLIPOP, "material_light_voice")
|
||||
};
|
||||
|
||||
/**
|
||||
* A class to encapsulate information about a layout.
|
||||
*/
|
||||
private static class Layout {
|
||||
public final int id;
|
||||
public final String name;
|
||||
public final LayoutModifier modifier;
|
||||
|
||||
private Layout(int id, String name) {
|
||||
this(id, name, null);
|
||||
}
|
||||
|
||||
private Layout(int id, String name, LayoutModifier modifier) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.modifier = modifier;
|
||||
}
|
||||
}
|
||||
|
||||
// List of layouts to verify for each theme.
|
||||
private static final Layout[] LAYOUTS = {
|
||||
new Layout(R.layout.button, "button"),
|
||||
new Layout(R.layout.button, "button_pressed",
|
||||
new ViewPressedModifier()),
|
||||
new Layout(R.layout.checkbox, "checkbox"),
|
||||
new Layout(R.layout.checkbox, "checkbox_checked",
|
||||
new ViewCheckedModifier()),
|
||||
new Layout(R.layout.chronometer, "chronometer"),
|
||||
new Layout(R.layout.color_blue_bright, "color_blue_bright"),
|
||||
new Layout(R.layout.color_blue_dark, "color_blue_dark"),
|
||||
new Layout(R.layout.color_blue_light, "color_blue_light"),
|
||||
new Layout(R.layout.color_green_dark, "color_green_dark"),
|
||||
new Layout(R.layout.color_green_light, "color_green_light"),
|
||||
new Layout(R.layout.color_orange_dark, "color_orange_dark"),
|
||||
new Layout(R.layout.color_orange_light, "color_orange_light"),
|
||||
new Layout(R.layout.color_purple, "color_purple"),
|
||||
new Layout(R.layout.color_red_dark, "color_red_dark"),
|
||||
new Layout(R.layout.color_red_light, "color_red_light"),
|
||||
new Layout(R.layout.datepicker, "datepicker",
|
||||
new DatePickerModifier()),
|
||||
new Layout(R.layout.edittext, "edittext"),
|
||||
new Layout(R.layout.progressbar_horizontal_0, "progressbar_horizontal_0"),
|
||||
new Layout(R.layout.progressbar_horizontal_100, "progressbar_horizontal_100"),
|
||||
new Layout(R.layout.progressbar_horizontal_50, "progressbar_horizontal_50"),
|
||||
new Layout(R.layout.progressbar_large, "progressbar_large",
|
||||
new ProgressBarModifier()),
|
||||
new Layout(R.layout.progressbar_small, "progressbar_small",
|
||||
new ProgressBarModifier()),
|
||||
new Layout(R.layout.progressbar, "progressbar",
|
||||
new ProgressBarModifier()),
|
||||
new Layout(R.layout.radiobutton_checked, "radiobutton_checked"),
|
||||
new Layout(R.layout.radiobutton, "radiobutton"),
|
||||
new Layout(R.layout.radiogroup_horizontal, "radiogroup_horizontal"),
|
||||
new Layout(R.layout.radiogroup_vertical, "radiogroup_vertical"),
|
||||
new Layout(R.layout.ratingbar_0, "ratingbar_0"),
|
||||
new Layout(R.layout.ratingbar_2point5, "ratingbar_2point5"),
|
||||
new Layout(R.layout.ratingbar_5, "ratingbar_5"),
|
||||
new Layout(R.layout.ratingbar_0, "ratingbar_0_pressed",
|
||||
new ViewPressedModifier()),
|
||||
new Layout(R.layout.ratingbar_2point5, "ratingbar_2point5_pressed",
|
||||
new ViewPressedModifier()),
|
||||
new Layout(R.layout.ratingbar_5, "ratingbar_5_pressed",
|
||||
new ViewPressedModifier()),
|
||||
new Layout(R.layout.searchview, "searchview_query",
|
||||
new SearchViewModifier(SearchViewModifier.QUERY)),
|
||||
new Layout(R.layout.searchview, "searchview_query_hint",
|
||||
new SearchViewModifier(SearchViewModifier.QUERY_HINT)),
|
||||
new Layout(R.layout.seekbar_0, "seekbar_0"),
|
||||
new Layout(R.layout.seekbar_100, "seekbar_100"),
|
||||
new Layout(R.layout.seekbar_50, "seekbar_50"),
|
||||
new Layout(R.layout.spinner, "spinner"),
|
||||
new Layout(R.layout.switch_button_checked, "switch_button_checked"),
|
||||
new Layout(R.layout.switch_button, "switch_button"),
|
||||
new Layout(R.layout.textview, "textview"),
|
||||
new Layout(R.layout.timepicker, "timepicker",
|
||||
new TimePickerModifier()),
|
||||
new Layout(R.layout.togglebutton_checked, "togglebutton_checked"),
|
||||
new Layout(R.layout.togglebutton, "togglebutton"),
|
||||
new Layout(R.layout.zoomcontrols, "zoomcontrols"),
|
||||
};
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.theme.app;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
public class ThemeTestUtils {
|
||||
|
||||
/**
|
||||
* Compresses the contents of a directory to a ZIP file.
|
||||
*
|
||||
* @param dir the directory to compress
|
||||
* @return {@code true} on success, {@code false} on failure
|
||||
*/
|
||||
public static boolean compressDirectory(File dir, File file) throws IOException {
|
||||
if (dir == null || !dir.exists() || file == null || file.exists()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final File[] srcFiles = dir.listFiles();
|
||||
if (srcFiles.length == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(file));
|
||||
final byte[] data = new byte[8192];
|
||||
for (int i = 0; i < srcFiles.length; i++) {
|
||||
final FileInputStream fileIn = new FileInputStream(srcFiles[i]);
|
||||
final ZipEntry entry = new ZipEntry(srcFiles[i].getName());
|
||||
zipOut.putNextEntry(entry);
|
||||
|
||||
int count;
|
||||
while ((count = fileIn.read(data, 0, data.length)) != -1) {
|
||||
zipOut.write(data, 0, count);
|
||||
zipOut.flush();
|
||||
}
|
||||
|
||||
zipOut.closeEntry();
|
||||
fileIn.close();
|
||||
}
|
||||
|
||||
zipOut.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively deletes a directory and its contents.
|
||||
*
|
||||
* @param dir the directory to delete
|
||||
* @return {@code true} on success, {@code false} on failure
|
||||
*/
|
||||
public static boolean deleteDirectory(File dir) {
|
||||
final File files[] = dir.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
deleteDirectory(file);
|
||||
}
|
||||
}
|
||||
return dir.delete();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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.theme.app.modifiers;
|
||||
|
||||
import android.theme.app.LayoutModifier;
|
||||
|
||||
/**
|
||||
* {@link LayoutModifier} that does nothing in {@link #prepare()}.
|
||||
*/
|
||||
abstract class AbstractLayoutModifier implements LayoutModifier {
|
||||
|
||||
@Override
|
||||
public void prepare() {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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.theme.app.modifiers;
|
||||
|
||||
import android.theme.app.LayoutModifier;
|
||||
import android.view.View;
|
||||
import android.widget.DatePicker;
|
||||
|
||||
/**
|
||||
* {@link LayoutModifier} that sets a precise date on a {@link DatePicker}.
|
||||
*/
|
||||
public class DatePickerModifier extends AbstractLayoutModifier {
|
||||
|
||||
@Override
|
||||
public View modifyView(View view) {
|
||||
DatePicker tp = (DatePicker) view;
|
||||
tp.updateDate(2011, 4, 20);
|
||||
return view;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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.theme.app.modifiers;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
public class ProgressBarModifier extends AbstractLayoutModifier {
|
||||
|
||||
@Override
|
||||
public View modifyView(View view) {
|
||||
ProgressBar pb = (ProgressBar) view;
|
||||
pb.setInterpolator(new ZeroInterpolator());
|
||||
return pb;
|
||||
}
|
||||
|
||||
private static class ZeroInterpolator implements Interpolator {
|
||||
@Override
|
||||
public float getInterpolation(float input) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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.theme.app.modifiers;
|
||||
|
||||
import android.theme.app.R;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.widget.SearchView;
|
||||
|
||||
public class SearchViewModifier extends AbstractLayoutModifier {
|
||||
|
||||
public static final int QUERY_HINT = 0;
|
||||
public static final int QUERY = 1;
|
||||
|
||||
private int mSearchViewType;
|
||||
|
||||
public SearchViewModifier(int searchViewType) {
|
||||
mSearchViewType = searchViewType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View modifyView(View view) {
|
||||
SearchView searchView = (SearchView) view;
|
||||
Context context = view.getContext();
|
||||
|
||||
switch (mSearchViewType) {
|
||||
case QUERY_HINT:
|
||||
searchView.setQueryHint(context.getString(R.string.searchview_query_hint));
|
||||
break;
|
||||
|
||||
case QUERY:
|
||||
searchView.setQuery(context.getString(R.string.searchview_query), false);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("Bad search view type: " + mSearchViewType);
|
||||
}
|
||||
|
||||
searchView.setIconifiedByDefault(false);
|
||||
return searchView;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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.theme.app.modifiers;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.TimePicker;
|
||||
|
||||
public class TimePickerModifier extends AbstractLayoutModifier {
|
||||
|
||||
@Override
|
||||
public View modifyView(View view) {
|
||||
TimePicker timePicker = (TimePicker) view;
|
||||
timePicker.setIs24HourView(true);
|
||||
timePicker.setCurrentHour(13);
|
||||
timePicker.setCurrentMinute(37);
|
||||
return view;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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.theme.app.modifiers;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
|
||||
public class ViewCheckedModifier extends AbstractLayoutModifier {
|
||||
|
||||
@Override
|
||||
public View modifyView(View view) {
|
||||
((CheckBox) view).setChecked(true);
|
||||
return view;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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.theme.app.modifiers;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
public class ViewPressedModifier extends AbstractLayoutModifier {
|
||||
|
||||
@Override
|
||||
public View modifyView(View view) {
|
||||
view.setPressed(true);
|
||||
return view;
|
||||
}
|
||||
}
|
BIN
android/cts/hostsidetests/theme/assets/260dpi.zip
Normal file
BIN
android/cts/hostsidetests/theme/assets/260dpi.zip
Normal file
Binary file not shown.
BIN
android/cts/hostsidetests/theme/assets/27/260dpi.zip
Normal file
BIN
android/cts/hostsidetests/theme/assets/27/260dpi.zip
Normal file
Binary file not shown.
BIN
android/cts/hostsidetests/theme/assets/27/280dpi.zip
Normal file
BIN
android/cts/hostsidetests/theme/assets/27/280dpi.zip
Normal file
Binary file not shown.
BIN
android/cts/hostsidetests/theme/assets/27/300dpi.zip
Normal file
BIN
android/cts/hostsidetests/theme/assets/27/300dpi.zip
Normal file
Binary file not shown.
BIN
android/cts/hostsidetests/theme/assets/27/340dpi.zip
Normal file
BIN
android/cts/hostsidetests/theme/assets/27/340dpi.zip
Normal file
Binary file not shown.
BIN
android/cts/hostsidetests/theme/assets/27/360dpi.zip
Normal file
BIN
android/cts/hostsidetests/theme/assets/27/360dpi.zip
Normal file
Binary file not shown.
BIN
android/cts/hostsidetests/theme/assets/27/400dpi.zip
Normal file
BIN
android/cts/hostsidetests/theme/assets/27/400dpi.zip
Normal file
Binary file not shown.
BIN
android/cts/hostsidetests/theme/assets/27/420dpi.zip
Normal file
BIN
android/cts/hostsidetests/theme/assets/27/420dpi.zip
Normal file
Binary file not shown.
BIN
android/cts/hostsidetests/theme/assets/27/560dpi.zip
Normal file
BIN
android/cts/hostsidetests/theme/assets/27/560dpi.zip
Normal file
Binary file not shown.
BIN
android/cts/hostsidetests/theme/assets/27/hdpi.zip
Normal file
BIN
android/cts/hostsidetests/theme/assets/27/hdpi.zip
Normal file
Binary file not shown.
BIN
android/cts/hostsidetests/theme/assets/27/ldpi.zip
Normal file
BIN
android/cts/hostsidetests/theme/assets/27/ldpi.zip
Normal file
Binary file not shown.
BIN
android/cts/hostsidetests/theme/assets/27/mdpi.zip
Normal file
BIN
android/cts/hostsidetests/theme/assets/27/mdpi.zip
Normal file
Binary file not shown.
BIN
android/cts/hostsidetests/theme/assets/27/tvdpi.zip
Normal file
BIN
android/cts/hostsidetests/theme/assets/27/tvdpi.zip
Normal file
Binary file not shown.
BIN
android/cts/hostsidetests/theme/assets/27/xhdpi.zip
Normal file
BIN
android/cts/hostsidetests/theme/assets/27/xhdpi.zip
Normal file
Binary file not shown.
BIN
android/cts/hostsidetests/theme/assets/27/xxhdpi.zip
Normal file
BIN
android/cts/hostsidetests/theme/assets/27/xxhdpi.zip
Normal file
Binary file not shown.
BIN
android/cts/hostsidetests/theme/assets/27/xxxhdpi.zip
Normal file
BIN
android/cts/hostsidetests/theme/assets/27/xxxhdpi.zip
Normal file
Binary file not shown.
BIN
android/cts/hostsidetests/theme/assets/280dpi.zip
Normal file
BIN
android/cts/hostsidetests/theme/assets/280dpi.zip
Normal file
Binary file not shown.
81
android/cts/hostsidetests/theme/avd.py
Normal file
81
android/cts/hostsidetests/theme/avd.py
Normal file
|
@ -0,0 +1,81 @@
|
|||
#!/usr/bin/python3
|
||||
#
|
||||
# Copyright (C) 2017 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
import functools
|
||||
import math
|
||||
import socket
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
from android_device import *
|
||||
|
||||
|
||||
def find_free_port():
|
||||
s = socket.socket()
|
||||
s.bind(('', 0))
|
||||
return int(s.getsockname()[1])
|
||||
|
||||
|
||||
class AVD(object):
|
||||
def __init__(self, name, emu_path):
|
||||
self._name = name
|
||||
self._emu_path = emu_path
|
||||
self._opts = ''
|
||||
self._adb_name = None
|
||||
self._emu_proc = None
|
||||
|
||||
def start(self):
|
||||
if self._emu_proc:
|
||||
raise Exception('Emulator already running')
|
||||
|
||||
port_adb = find_free_port()
|
||||
port_tty = find_free_port()
|
||||
# -no-window might be useful here
|
||||
emu_cmd = "%s -avd %s %s-ports %d,%d" \
|
||||
% (self._emu_path, self._name, self._opts, port_adb, port_tty)
|
||||
print(emu_cmd)
|
||||
|
||||
emu_proc = subprocess.Popen(emu_cmd.split(" "), bufsize=-1, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
|
||||
# The emulator ought to be starting now.
|
||||
self._adb_name = "emulator-%d" % (port_tty - 1)
|
||||
self._emu_proc = emu_proc
|
||||
|
||||
def stop(self):
|
||||
if not self._emu_proc:
|
||||
raise Exception('Emulator not currently running')
|
||||
self._emu_proc.kill()
|
||||
(out, err) = self._emu_proc.communicate()
|
||||
self._emu_proc = None
|
||||
return out, err
|
||||
|
||||
def get_serial(self):
|
||||
if not self._emu_proc:
|
||||
raise Exception('Emulator not currently running')
|
||||
return self._adb_name
|
||||
|
||||
def get_device(self):
|
||||
if not self._emu_proc:
|
||||
raise Exception('Emulator not currently running')
|
||||
return AndroidDevice(self._adb_name)
|
||||
|
||||
def configure_screen(self, density, width_dp, height_dp):
|
||||
width_px = int(math.ceil(width_dp * density / 1600) * 10)
|
||||
height_px = int(math.ceil(height_dp * density / 1600) * 10)
|
||||
self._opts = "-prop qemu.sf.lcd_density=%d -skin %dx%d " % (density, width_px, height_px)
|
244
android/cts/hostsidetests/theme/generate_images.py
Executable file
244
android/cts/hostsidetests/theme/generate_images.py
Executable file
|
@ -0,0 +1,244 @@
|
|||
#!/usr/bin/python3
|
||||
#
|
||||
# Copyright (C) 2015 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import threading
|
||||
import time
|
||||
import traceback
|
||||
|
||||
from android_device import *
|
||||
from avd import *
|
||||
from queue import Queue, Empty
|
||||
|
||||
|
||||
# This dict should contain one entry for every density listed in CDD 7.1.1.3.
|
||||
CTS_THEME_dict = {
|
||||
120: "ldpi",
|
||||
160: "mdpi",
|
||||
213: "tvdpi",
|
||||
240: "hdpi",
|
||||
260: "260dpi",
|
||||
280: "280dpi",
|
||||
300: "300dpi",
|
||||
320: "xhdpi",
|
||||
340: "340dpi",
|
||||
360: "360dpi",
|
||||
400: "400dpi",
|
||||
420: "420dpi",
|
||||
480: "xxhdpi",
|
||||
560: "560dpi",
|
||||
640: "xxxhdpi",
|
||||
}
|
||||
|
||||
OUT_FILE = "/sdcard/cts-theme-assets.zip"
|
||||
|
||||
|
||||
class ParallelExecutor(threading.Thread):
|
||||
def __init__(self, tasks, q):
|
||||
threading.Thread.__init__(self)
|
||||
self._q = q
|
||||
self._tasks = tasks
|
||||
self._setup = setup
|
||||
self._result = 0
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
while True:
|
||||
config = q.get(block=True, timeout=2)
|
||||
for t in self._tasks:
|
||||
try:
|
||||
if t(self._setup, config):
|
||||
self._result += 1
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except:
|
||||
print("Failed to execute thread:", sys.exc_info()[0])
|
||||
traceback.print_exc()
|
||||
q.task_done()
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except Empty:
|
||||
pass
|
||||
|
||||
def get_result(self):
|
||||
return self._result
|
||||
|
||||
|
||||
# pass a function with number of instances to be executed in parallel
|
||||
# each thread continues until config q is empty.
|
||||
def execute_parallel(tasks, setup, q, num_threads):
|
||||
result = 0
|
||||
threads = []
|
||||
for i in range(num_threads):
|
||||
t = ParallelExecutor(tasks, q)
|
||||
t.start()
|
||||
threads.append(t)
|
||||
for t in threads:
|
||||
t.join()
|
||||
result += t.get_result()
|
||||
return result
|
||||
|
||||
|
||||
def print_adb_result(device, out, err):
|
||||
print("device: " + device)
|
||||
if out is not None:
|
||||
print("out:\n" + out)
|
||||
if err is not None:
|
||||
print("err:\n" + err)
|
||||
|
||||
|
||||
def do_capture(setup, device_serial):
|
||||
(themeApkPath, out_path) = setup
|
||||
|
||||
device = AndroidDevice(device_serial)
|
||||
|
||||
version = device.get_version_codename()
|
||||
if version == "REL":
|
||||
version = str(device.get_version_sdk())
|
||||
|
||||
density = device.get_density()
|
||||
|
||||
if CTS_THEME_dict[density]:
|
||||
density_bucket = CTS_THEME_dict[density]
|
||||
else:
|
||||
density_bucket = str(density) + "dpi"
|
||||
|
||||
out_file = os.path.join(out_path, os.path.join(version, "%s.zip" % density_bucket))
|
||||
|
||||
device.uninstall_package('android.theme.app')
|
||||
|
||||
(out, err, success) = device.install_apk(themeApkPath)
|
||||
if not success:
|
||||
print("Failed to install APK on " + device_serial)
|
||||
print_adb_result(device_serial, out, err)
|
||||
return False
|
||||
|
||||
print("Generating images on " + device_serial + "...")
|
||||
try:
|
||||
(out, err) = device.run_instrumentation_test(
|
||||
"android.theme.app/android.support.test.runner.AndroidJUnitRunner")
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except:
|
||||
(out, err) = device.run_instrumentation_test(
|
||||
"android.theme.app/android.test.InstrumentationTestRunner")
|
||||
|
||||
# Detect test failure and abort.
|
||||
if "FAILURES!!!" in out.split():
|
||||
print_adb_result(device_serial, out, err)
|
||||
return False
|
||||
|
||||
# Make sure that the run is complete by checking the process itself
|
||||
print("Waiting for " + device_serial + "...")
|
||||
wait_time = 0
|
||||
while device.is_process_alive("android.theme.app"):
|
||||
time.sleep(1)
|
||||
wait_time = wait_time + 1
|
||||
if wait_time > 180:
|
||||
print("Timed out")
|
||||
break
|
||||
|
||||
time.sleep(10)
|
||||
|
||||
print("Pulling images from " + device_serial + " to " + out_file)
|
||||
device.run_adb_command("pull " + OUT_FILE + " " + out_file)
|
||||
device.run_adb_command("shell rm -rf " + OUT_FILE)
|
||||
return True
|
||||
|
||||
|
||||
def get_emulator_path():
|
||||
if 'ANDROID_SDK_ROOT' not in os.environ:
|
||||
print('Environment variable ANDROID_SDK_ROOT must point to your Android SDK root.')
|
||||
sys.exit(1)
|
||||
|
||||
sdk_path = os.environ['ANDROID_SDK_ROOT']
|
||||
if not os.path.isdir(sdk_path):
|
||||
print("Failed to find Android SDK at ANDROID_SDK_ROOT: %s" % sdk_path)
|
||||
sys.exit(1)
|
||||
|
||||
emu_path = os.path.join(os.path.join(sdk_path, 'tools'), 'emulator')
|
||||
if not os.path.isfile(emu_path):
|
||||
print("Failed to find emulator within ANDROID_SDK_ROOT: %s" % sdk_path)
|
||||
sys.exit(1)
|
||||
|
||||
return emu_path
|
||||
|
||||
|
||||
def start_emulator(name, density):
|
||||
emu_path = get_emulator_path()
|
||||
|
||||
# Start emulator for 560dpi, normal screen size.
|
||||
test_avd = AVD(name, emu_path)
|
||||
test_avd.configure_screen(density, 360, 640)
|
||||
test_avd.start()
|
||||
try:
|
||||
test_avd_device = test_avd.get_device()
|
||||
test_avd_device.wait_for_device()
|
||||
test_avd_device.wait_for_boot_complete()
|
||||
return test_avd
|
||||
except:
|
||||
test_avd.stop()
|
||||
return None
|
||||
|
||||
|
||||
def main(argv):
|
||||
if 'ANDROID_BUILD_TOP' not in os.environ or 'ANDROID_HOST_OUT' not in os.environ:
|
||||
print('Missing environment variables. Did you run build/envsetup.sh and lunch?')
|
||||
sys.exit(1)
|
||||
|
||||
theme_apk = os.path.join(os.environ['ANDROID_HOST_OUT'],
|
||||
'cts/android-cts/testcases/CtsThemeDeviceApp.apk')
|
||||
if not os.path.isfile(theme_apk):
|
||||
print('Couldn\'t find test APK. Did you run make cts?')
|
||||
sys.exit(1)
|
||||
|
||||
out_path = os.path.join(os.environ['ANDROID_BUILD_TOP'],
|
||||
'cts/hostsidetests/theme/assets')
|
||||
os.system("mkdir -p %s" % out_path)
|
||||
|
||||
if len(argv) is 2:
|
||||
for density in CTS_THEME_dict.keys():
|
||||
emulator = start_emulator(argv[1], density)
|
||||
result = do_capture(setup=(theme_apk, out_path), device_serial=emulator.get_serial())
|
||||
emulator.stop()
|
||||
if result:
|
||||
print("Generated reference images for %ddpi" % density)
|
||||
else:
|
||||
print("Failed to generate reference images for %ddpi" % density)
|
||||
break
|
||||
else:
|
||||
tasks = [do_capture]
|
||||
setup = (theme_apk, out_path)
|
||||
|
||||
devices = enumerate_android_devices('emulator')
|
||||
|
||||
device_queue = Queue()
|
||||
for device in devices:
|
||||
device_queue.put(device)
|
||||
|
||||
result = execute_parallel(tasks, setup, device_queue, len(devices))
|
||||
|
||||
if result > 0:
|
||||
print('Generated reference images for %(count)d devices' % {"count": result})
|
||||
else:
|
||||
print('Failed to generate reference images')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
185
android/cts/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
Executable file
185
android/cts/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
Executable file
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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.theme.cts;
|
||||
|
||||
import com.android.ddmlib.Log;
|
||||
import com.android.ddmlib.Log.LogLevel;
|
||||
import com.android.tradefed.util.Pair;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.String;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
/**
|
||||
* Compares the images generated by the device with the reference images.
|
||||
*/
|
||||
public class ComparisonTask implements Callable<Pair<String, File>> {
|
||||
private static final String TAG = "ComparisonTask";
|
||||
|
||||
private static final int IMAGE_THRESHOLD = 8;
|
||||
|
||||
/** Neutral gray for blending colors. */
|
||||
private static final int GRAY = 0xFF808080;
|
||||
|
||||
/** Maximum allowable number of consecutive failed pixels. */
|
||||
private static final int MAX_CONSECUTIVE_FAILURES = 1;
|
||||
|
||||
private final String mName;
|
||||
private final File mExpected;
|
||||
private final File mActual;
|
||||
|
||||
public ComparisonTask(String name, File expected, File actual) {
|
||||
mName = name;
|
||||
mExpected = expected;
|
||||
mActual = actual;
|
||||
}
|
||||
|
||||
public Pair<String, File> call() {
|
||||
try {
|
||||
final BufferedImage expected = ImageIO.read(mExpected);
|
||||
final BufferedImage actual = ImageIO.read(mActual);
|
||||
if (!compare(expected, actual, IMAGE_THRESHOLD)) {
|
||||
final File diff = File.createTempFile("diff_" + mExpected.getName(), ".png");
|
||||
createDiff(expected, actual, diff);
|
||||
return new Pair<>(mName, diff);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.logAndDisplay(LogLevel.ERROR, TAG, e.toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int getAlphaScaledBlue(final int color) {
|
||||
return (color & 0x000000FF) * getAlpha(color) / 255;
|
||||
}
|
||||
|
||||
private static int getAlphaScaledGreen(final int color) {
|
||||
return ((color & 0x0000FF00) >> 8) * getAlpha(color) / 255;
|
||||
}
|
||||
|
||||
private static int getAlphaScaledRed(final int color) {
|
||||
return ((color & 0x00FF0000) >> 16) * getAlpha(color) / 255;
|
||||
}
|
||||
|
||||
private static int getAlpha(final int color) {
|
||||
// use logical shift for keeping an unsigned value
|
||||
return (color & 0xFF000000) >>> 24;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verifies that the pixels of reference and generated images are similar
|
||||
* within a specified threshold.
|
||||
*
|
||||
* @param reference expected image
|
||||
* @param generated actual image
|
||||
* @param threshold maximum difference per channel
|
||||
* @return {@code true} if the images are similar, false otherwise
|
||||
*/
|
||||
private static boolean compare(BufferedImage reference, BufferedImage generated,
|
||||
int threshold) {
|
||||
final int w = generated.getWidth();
|
||||
final int h = generated.getHeight();
|
||||
if (w != reference.getWidth() || h != reference.getHeight()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
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) {
|
||||
System.err.println("fail dr=" + dr+ " dg=" + dg+ " db=" + db);
|
||||
|
||||
consecutive++;
|
||||
|
||||
if (consecutive > MAX_CONSECUTIVE_FAILURES) {
|
||||
System.err.println("consecutive fail");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
consecutive = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void createDiff(BufferedImage expected, BufferedImage actual, File out)
|
||||
throws IOException {
|
||||
final int w1 = expected.getWidth();
|
||||
final int h1 = expected.getHeight();
|
||||
final int w2 = actual.getWidth();
|
||||
final int h2 = actual.getHeight();
|
||||
final int width = Math.max(w1, w2);
|
||||
final int height = Math.max(h1, h2);
|
||||
|
||||
// The diff will contain image1, image2 and the difference between the two.
|
||||
final BufferedImage diff = new BufferedImage(
|
||||
width * 3, height, BufferedImage.TYPE_INT_ARGB);
|
||||
|
||||
for (int i = 0; i < width; i++) {
|
||||
for (int j = 0; j < height; j++) {
|
||||
final boolean inBounds1 = i < w1 && j < h1;
|
||||
final boolean inBounds2 = i < w2 && j < h2;
|
||||
int colorExpected = Color.WHITE.getRGB();
|
||||
int colorActual = Color.WHITE.getRGB();
|
||||
int colorDiff;
|
||||
if (inBounds1 && inBounds2) {
|
||||
colorExpected = expected.getRGB(i, j);
|
||||
colorActual = actual.getRGB(i, j);
|
||||
colorDiff = colorExpected == colorActual ? colorExpected : Color.RED.getRGB();
|
||||
} else if (inBounds1 && !inBounds2) {
|
||||
colorExpected = expected.getRGB(i, j);
|
||||
colorDiff = Color.BLUE.getRGB();
|
||||
} else if (!inBounds1 && inBounds2) {
|
||||
colorActual = actual.getRGB(i, j);
|
||||
colorDiff = Color.GREEN.getRGB();
|
||||
} else {
|
||||
colorDiff = Color.MAGENTA.getRGB();
|
||||
}
|
||||
|
||||
int x = i;
|
||||
diff.setRGB(x, j, colorExpected);
|
||||
x += width;
|
||||
diff.setRGB(x, j, colorActual);
|
||||
x += width;
|
||||
diff.setRGB(x, j, colorDiff);
|
||||
}
|
||||
}
|
||||
|
||||
ImageIO.write(diff, "png", out);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,296 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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.theme.cts;
|
||||
|
||||
import com.android.ddmlib.Log;
|
||||
import com.android.ddmlib.Log.LogLevel;
|
||||
import com.android.tradefed.device.CollectingOutputReceiver;
|
||||
import com.android.tradefed.device.DeviceNotAvailableException;
|
||||
import com.android.tradefed.device.ITestDevice;
|
||||
import com.android.tradefed.result.FileInputStreamSource;
|
||||
import com.android.tradefed.result.InputStreamSource;
|
||||
import com.android.tradefed.result.LogDataType;
|
||||
import com.android.tradefed.testtype.DeviceTestCase;
|
||||
import com.android.tradefed.util.Pair;
|
||||
import com.android.tradefed.util.StreamUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutorCompletionService;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
/**
|
||||
* Test to check non-modifiable themes have not been changed.
|
||||
*/
|
||||
public class ThemeHostTest extends DeviceTestCase {
|
||||
|
||||
private static final String LOG_TAG = "ThemeHostTest";
|
||||
private static final String APP_PACKAGE_NAME = "android.theme.app";
|
||||
|
||||
private static final String GENERATED_ASSETS_ZIP = "/sdcard/cts-theme-assets.zip";
|
||||
|
||||
/** The class name of the main activity in the APK. */
|
||||
private static final String TEST_CLASS = "android.support.test.runner.AndroidJUnitRunner";
|
||||
|
||||
/** The command to launch the main instrumentation test. */
|
||||
private static final String START_CMD = String.format(
|
||||
"am instrument -w --no-window-animation %s/%s", APP_PACKAGE_NAME, TEST_CLASS);
|
||||
|
||||
private static final String CLEAR_GENERATED_CMD = "rm -rf %s/*.png";
|
||||
private static final String STOP_CMD = String.format("am force-stop %s", APP_PACKAGE_NAME);
|
||||
private static final String HARDWARE_TYPE_CMD = "dumpsys | grep android.hardware.type";
|
||||
private static final String DENSITY_PROP_DEVICE = "ro.sf.lcd_density";
|
||||
private static final String DENSITY_PROP_EMULATOR = "qemu.sf.lcd_density";
|
||||
|
||||
/** Shell command used to obtain current device density. */
|
||||
private static final String WM_DENSITY = "wm density";
|
||||
|
||||
/** Overall test timeout is 30 minutes. Should only take about 5. */
|
||||
private static final int TEST_RESULT_TIMEOUT = 30 * 60 * 1000;
|
||||
|
||||
/** Map of reference image names and files. */
|
||||
private Map<String, File> mReferences;
|
||||
|
||||
/** A reference to the device under test. */
|
||||
private ITestDevice mDevice;
|
||||
|
||||
private ExecutorService mExecutionService;
|
||||
|
||||
private ExecutorCompletionService<Pair<String, File>> mCompletionService;
|
||||
|
||||
/** the string identifying the hardware type. */
|
||||
private String mHardwareType;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
mDevice = getDevice();
|
||||
mHardwareType = mDevice.executeShellCommand(HARDWARE_TYPE_CMD).trim();
|
||||
|
||||
final String density = getDensityBucketForDevice(mDevice, mHardwareType);
|
||||
final String referenceZipAssetPath = String.format("/%s.zip", density);
|
||||
mReferences = extractReferenceImages(referenceZipAssetPath);
|
||||
|
||||
final int numCores = Runtime.getRuntime().availableProcessors();
|
||||
mExecutionService = Executors.newFixedThreadPool(numCores * 2);
|
||||
mCompletionService = new ExecutorCompletionService<>(mExecutionService);
|
||||
}
|
||||
|
||||
private Map<String, File> extractReferenceImages(String zipFile) throws Exception {
|
||||
final Map<String, File> references = new HashMap<>();
|
||||
final InputStream zipStream = ThemeHostTest.class.getResourceAsStream(zipFile);
|
||||
if (zipStream != null) {
|
||||
try (ZipInputStream in = new ZipInputStream(zipStream)) {
|
||||
final byte[] buffer = new byte[1024];
|
||||
for (ZipEntry ze; (ze = in.getNextEntry()) != null; ) {
|
||||
final String name = ze.getName();
|
||||
final File tmp = File.createTempFile("ref_" + name, ".png");
|
||||
tmp.deleteOnExit();
|
||||
try (FileOutputStream out = new FileOutputStream(tmp)) {
|
||||
for (int count; (count = in.read(buffer)) != -1; ) {
|
||||
out.write(buffer, 0, count);
|
||||
}
|
||||
}
|
||||
|
||||
references.put(name, tmp);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
fail("Failed to unzip assets: " + zipFile);
|
||||
}
|
||||
} else {
|
||||
if (checkHardwareTypeSkipTest(mHardwareType)) {
|
||||
Log.logAndDisplay(LogLevel.WARN, LOG_TAG,
|
||||
"Could not obtain resources for skipped themes test: " + zipFile);
|
||||
} else {
|
||||
fail("Failed to get resource: " + zipFile);
|
||||
}
|
||||
}
|
||||
|
||||
return references;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
mExecutionService.shutdown();
|
||||
|
||||
// Remove generated images.
|
||||
mDevice.executeShellCommand(CLEAR_GENERATED_CMD);
|
||||
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
public void testThemes() throws Exception {
|
||||
if (checkHardwareTypeSkipTest(mHardwareType)) {
|
||||
Log.logAndDisplay(LogLevel.INFO, LOG_TAG, "Skipped themes test for watch / TV");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mReferences.isEmpty()) {
|
||||
Log.logAndDisplay(LogLevel.INFO, LOG_TAG,
|
||||
"Skipped themes test due to missing reference images");
|
||||
return;
|
||||
}
|
||||
|
||||
assertTrue("Aborted image generation", generateDeviceImages());
|
||||
|
||||
// Pull ZIP file from remote device.
|
||||
final File localZip = File.createTempFile("generated", ".zip");
|
||||
assertTrue("Failed to pull generated assets from device",
|
||||
mDevice.pullFile(GENERATED_ASSETS_ZIP, localZip));
|
||||
|
||||
final int numTasks = extractGeneratedImages(localZip, mReferences);
|
||||
|
||||
int failureCount = 0;
|
||||
for (int i = numTasks; i > 0; i--) {
|
||||
final Pair<String, File> comparison = mCompletionService.take().get();
|
||||
if (comparison != null) {
|
||||
InputStreamSource inputStream = new FileInputStreamSource(comparison.second);
|
||||
try{
|
||||
// Log the diff file
|
||||
addTestLog(comparison.first, LogDataType.PNG, inputStream);
|
||||
} finally {
|
||||
StreamUtil.cancel(inputStream);
|
||||
}
|
||||
failureCount++;
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue(failureCount + " failures in theme test", failureCount == 0);
|
||||
}
|
||||
|
||||
private int extractGeneratedImages(File localZip, Map<String, File> references)
|
||||
throws IOException {
|
||||
int numTasks = 0;
|
||||
|
||||
// Extract generated images to temporary files.
|
||||
final byte[] data = new byte[8192];
|
||||
try (ZipInputStream zipInput = new ZipInputStream(new FileInputStream(localZip))) {
|
||||
for (ZipEntry entry; (entry = zipInput.getNextEntry()) != null; ) {
|
||||
final String name = entry.getName();
|
||||
final File expected = references.get(name);
|
||||
if (expected != null && expected.exists()) {
|
||||
final File actual = File.createTempFile("actual_" + name, ".png");
|
||||
actual.deleteOnExit();
|
||||
|
||||
try (FileOutputStream pngOutput = new FileOutputStream(actual)) {
|
||||
for (int count; (count = zipInput.read(data, 0, data.length)) != -1; ) {
|
||||
pngOutput.write(data, 0, count);
|
||||
}
|
||||
}
|
||||
|
||||
final String shortName = name.substring(0, name.indexOf('.'));
|
||||
mCompletionService.submit(new ComparisonTask(shortName, expected, actual));
|
||||
numTasks++;
|
||||
} else {
|
||||
Log.logAndDisplay(LogLevel.INFO, LOG_TAG,
|
||||
"Missing reference image for " + name);
|
||||
}
|
||||
|
||||
zipInput.closeEntry();
|
||||
}
|
||||
}
|
||||
|
||||
return numTasks;
|
||||
}
|
||||
|
||||
private boolean generateDeviceImages() throws Exception {
|
||||
// Stop any existing instances.
|
||||
mDevice.executeShellCommand(STOP_CMD);
|
||||
|
||||
// Start instrumentation test.
|
||||
final CollectingOutputReceiver receiver = new CollectingOutputReceiver();
|
||||
mDevice.executeShellCommand(START_CMD, receiver, TEST_RESULT_TIMEOUT,
|
||||
TimeUnit.MILLISECONDS, 0);
|
||||
|
||||
return receiver.getOutput().contains("OK ");
|
||||
}
|
||||
|
||||
private static String getDensityBucketForDevice(ITestDevice device, String hardwareType) {
|
||||
if (hardwareType.contains("android.hardware.type.television")) {
|
||||
// references images for tv are under bucket "tvdpi".
|
||||
return "tvdpi";
|
||||
}
|
||||
final int density;
|
||||
try {
|
||||
density = getDensityForDevice(device);
|
||||
} catch (DeviceNotAvailableException e) {
|
||||
throw new RuntimeException("Failed to detect device density", e);
|
||||
}
|
||||
final String bucket;
|
||||
switch (density) {
|
||||
case 120:
|
||||
bucket = "ldpi";
|
||||
break;
|
||||
case 160:
|
||||
bucket = "mdpi";
|
||||
break;
|
||||
case 240:
|
||||
bucket = "hdpi";
|
||||
break;
|
||||
case 320:
|
||||
bucket = "xhdpi";
|
||||
break;
|
||||
case 480:
|
||||
bucket = "xxhdpi";
|
||||
break;
|
||||
case 640:
|
||||
bucket = "xxxhdpi";
|
||||
break;
|
||||
default:
|
||||
bucket = density + "dpi";
|
||||
break;
|
||||
}
|
||||
|
||||
Log.logAndDisplay(LogLevel.INFO, LOG_TAG,
|
||||
"Device density detected as " + density + " (" + bucket + ")");
|
||||
return bucket;
|
||||
}
|
||||
|
||||
private static int getDensityForDevice(ITestDevice device) throws DeviceNotAvailableException {
|
||||
final String output = device.executeShellCommand(WM_DENSITY);
|
||||
final Pattern p = Pattern.compile("Override density: (\\d+)");
|
||||
final Matcher m = p.matcher(output);
|
||||
if (m.find()) {
|
||||
return Integer.parseInt(m.group(1));
|
||||
}
|
||||
|
||||
final String densityProp;
|
||||
if (device.getSerialNumber().startsWith("emulator-")) {
|
||||
densityProp = DENSITY_PROP_EMULATOR;
|
||||
} else {
|
||||
densityProp = DENSITY_PROP_DEVICE;
|
||||
}
|
||||
return Integer.parseInt(device.getProperty(densityProp));
|
||||
}
|
||||
|
||||
private static boolean checkHardwareTypeSkipTest(String hardwareTypeString) {
|
||||
return hardwareTypeString.contains("android.hardware.type.watch")
|
||||
|| hardwareTypeString.contains("android.hardware.type.television");
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue