blob: 6754274eaa9f256c21e75a1791ab89a2eb2b87ce [file] [log] [blame]
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.cts;
import com.android.ddmlib.RawImage;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferUShort;
import java.awt.image.Raster;
import java.awt.image.SampleModel;
import java.awt.image.SinglePixelPackedSampleModel;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Formatter;
import java.util.Locale;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* Utilities for CTS host.
*
*/
public class HostUtils {
private static SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy",
Locale.ENGLISH);
/**
* Check if the given file exists
*
* @param name the file name to be checked
* @return if the file exists, return true;
* else, return false
*/
public static boolean isFileExist(final String name) {
return new File(name).exists();
}
/**
* Convert a 16bpp RawImage into a BufferedImage.
*
* @param rawImage the image to convert.
* @return the BufferedImage.
*/
public static BufferedImage convertRawImageToBufferedImage(RawImage rawImage) {
assert rawImage.bpp == 16;
BufferedImage im = new BufferedImage(rawImage.width,
rawImage.height, BufferedImage.TYPE_USHORT_565_RGB);
SampleModel sampleModel = new SinglePixelPackedSampleModel(DataBuffer.TYPE_USHORT,
rawImage.width,
rawImage.height,
// RGB565
new int[] { 0xf800, 0x07e0, 0x001f });
// It would be more efficient to just subclass DataBuffer and provide a
// TYPE_USHORT interface to the byte array. But Raster.createRaster at
// some point uses instanceof(DataBufferUShort) to verify that the DataBuffer
// is of the right type (instead of just checking DataBuffer.getDataType).
// And since DataBufferUShort is final, it can't be subclassed to get around
// the check either. So copy the data into a short[] instead to work around the problem.
short shortData[] = new short[rawImage.size / 2];
for (int x = 0; x < shortData.length; x++) {
int rawImageOffset = x * 2;
int a = 0xff & rawImage.data[rawImageOffset];
int b = 0xff & rawImage.data[rawImageOffset + 1];
shortData[x] = (short)((b << 8) | a);
}
DataBuffer db = new DataBufferUShort(shortData, shortData.length);
Raster raster = Raster.createRaster(sampleModel,
db, null);
im.setData(raster);
return im;
}
/**
* Interface used with visitAllFilesUnder
*/
public interface FileVisitor {
/**
* Gets called on every file visited.
* @param f the File for the file being visited.
*/
void visitFile(File f);
}
/**
* Recursively visit all files under a given path.
*
* @param root the path to start at.
* @param filter the file filter to match. null means to visit all files.
* @param visitor the visitor to visit with.
*/
public static void visitAllFilesUnder(File root, FilenameFilter filter, FileVisitor visitor) {
File[] files = root.listFiles(filter);
// A null file may indicate not having enough permissions to view that directory
if (files != null) {
for (File f : files) {
visitor.visitFile(f);
if (f.isDirectory()) {
visitAllFilesUnder(f, filter, visitor);
}
}
}
}
/**
* Recursively visit all files under a given path.
*
* @param path the path to start at.
* @param filter the file filter to match. null means to visit all files.
* @param visitor the visitor to visit with.
*/
public static void visitAllFilesUnder(String path, FilenameFilter filter, FileVisitor visitor) {
visitAllFilesUnder(new File(path), filter, visitor);
}
// Private class to help zipUpDirectory
private static class ZipFileVisitor implements FileVisitor {
private final ZipOutputStream zipOutputStream;
private boolean ok = true;
private IOException caughtException;
private final ZipFilenameTransformer transformer;
public ZipFileVisitor(ZipOutputStream zipOutputStream,
ZipFilenameTransformer transformer) {
this.zipOutputStream = zipOutputStream;
this.transformer = transformer;
}
public void visitFile(File f) {
String path = f.getPath();
if (transformer != null) {
path = transformer.transform(path);
}
ZipEntry ze = new ZipEntry(path);
try {
zipOutputStream.putNextEntry(ze);
InputStream is = new BufferedInputStream(new FileInputStream(f));
byte[] buffer = new byte[4096];
int bytesRead = is.read(buffer);
while (bytesRead > 0) {
zipOutputStream.write(buffer, 0, bytesRead);
bytesRead = is.read(buffer);
}
zipOutputStream.closeEntry();
} catch (IOException e) {
ok = false;
caughtException = e;
}
}
/**
* Indicates that the visitor ran without errors
* @return true if everything ran OK.
*/
boolean isOk() {
return ok;
}
/**
* If an IOException was thrown while zipping, it gets kept here.
*
* @return the IOException that was caught, or null if none was.
*/
IOException getCaughtException() {
return caughtException;
}
}
/**
* Indicates some issue with zipping up the file.
*/
static class ZipFileException extends Exception {
ZipFileException(IOException ioException) {
super("Caught wrapped exception", ioException);
}
}
/**
* Interface provided to rename files before they get zipped.
*/
public interface ZipFilenameTransformer {
/**
* Transform a local filesystem filename into a zipfile filename.
*
* @param filename the input filename
* @return the filename to be saved to the zipfile as.
*/
String transform(String filename);
}
/**
* Recursively zip up a directory into a zip file.
*
* @param sourceDir the directory to zip up
* @param outputFilePath the zipfile to create.
* @param transformer filepath transformer. can be null.
* @throws IOException if there were issues writing the zipfile.
*/
public static void zipUpDirectory(String sourceDir,
String outputFilePath,
ZipFilenameTransformer transformer)
throws IOException, ZipFileException {
// I <3 abstractions
FileOutputStream fileOut = new FileOutputStream(outputFilePath);
BufferedOutputStream bufOut = new BufferedOutputStream(fileOut);
final ZipOutputStream zipOutputStream = new ZipOutputStream(bufOut);
ZipFileVisitor zfv = new ZipFileVisitor(zipOutputStream, transformer);
visitAllFilesUnder(sourceDir, null, zfv);
zipOutputStream.close();
if (!zfv.isOk()) {
throw new ZipFileException(zfv.getCaughtException());
}
}
/**
* Get the formatted time string.
*
* @param milliSec The time in milliseconds.
* @param separator The separator between the date information and time information.
* @param dateSeparator The date separator separating the date information nibbles.
* @param timeSeparator The time separator separating the time information nibbles.
* @return The formated time string.
*/
public static String getFormattedTimeString(long milliSec, String separator,
String dateSeparator, String timeSeparator) {
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(milliSec);
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH) + 1;
int date = cal.get(Calendar.DATE);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int min = cal.get(Calendar.MINUTE);
int sec = cal.get(Calendar.SECOND);
Formatter fmt = new Formatter();
if ((separator == null) || (separator.length() == 0)) {
separator = "_";
}
if ((dateSeparator == null) || (dateSeparator.length() == 0)) {
dateSeparator = ".";
}
if ((timeSeparator == null) || (timeSeparator.length() == 0)) {
timeSeparator = ".";
}
final String formatStr = "%4d" + dateSeparator + "%02d" + dateSeparator + "%02d"
+ separator + "%02d" + timeSeparator + "%02d" + timeSeparator + "%02d";
fmt.format(formatStr, year, month, date, hour, min, sec);
return fmt.toString();
}
/**
* Convert the given byte array into a lowercase hex string.
*
* @param arr The array to convert.
* @return The hex encoded string.
*/
public static String toHexString(byte[] arr) {
StringBuffer buf = new StringBuffer(arr.length * 2);
for (byte b : arr) {
buf.append(String.format("%02x", b & 0xFF));
}
return buf.toString();
}
/**
* Strip control characters from the given string.
*/
public static String replaceControlChars(String s) {
// Replace any character < 0x20, except for tab, lf and cr
return s.replaceAll("[\\x00-\\x1f&&[^\t\n\r]]", "?");
}
public static Date dateFromString(String s) throws ParseException {
return dateFormat.parse(s);
}
public static String dateToString(Date d) {
return dateFormat.format(d);
}
}