summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.xml22
-rw-r--r--core/java/android/webkit/WebView.java110
-rw-r--r--core/java/android/webkit/WebViewCore.java112
-rw-r--r--core/res/res/values/public.xml1
-rw-r--r--core/res/res/values/strings.xml2
-rw-r--r--include/media/MediaRecorderBase.h1
-rw-r--r--include/media/PVMediaRecorder.h1
-rw-r--r--media/java/android/media/MtpDatabase.java20
-rw-r--r--media/jni/android_media_MtpDatabase.cpp13
-rw-r--r--media/jni/android_media_MtpServer.cpp1
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp16
-rw-r--r--media/libmediaplayerservice/MediaRecorderClient.cpp7
-rw-r--r--media/libmediaplayerservice/MediaRecorderClient.h19
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.cpp60
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.h1
-rw-r--r--media/libstagefright/OMXCodec.cpp2
-rw-r--r--media/mtp/Android.mk43
-rw-r--r--media/mtp/MtpDatabase.h5
-rw-r--r--media/mtp/MtpMediaScanner.cpp233
-rw-r--r--media/mtp/MtpMediaScanner.h52
-rw-r--r--media/mtp/MtpServer.cpp9
-rw-r--r--media/mtp/MtpServer.h1
-rw-r--r--media/mtp/MtpSqliteDatabase.cpp453
-rw-r--r--media/mtp/MtpSqliteDatabase.h80
-rw-r--r--media/mtp/MtpStorage.cpp6
-rw-r--r--media/mtp/MtpStorage.h3
-rw-r--r--media/mtp/MtpTypes.h5
-rw-r--r--media/mtp/SqliteDatabase.cpp88
-rw-r--r--media/mtp/SqliteDatabase.h50
-rw-r--r--media/mtp/SqliteStatement.cpp83
-rw-r--r--media/mtp/SqliteStatement.h56
-rw-r--r--media/mtp/mtptest.cpp91
-rw-r--r--media/mtp/scantest.cpp38
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java4
-rw-r--r--tests/DumpRenderTree2/Android.mk4
-rw-r--r--tests/DumpRenderTree2/AndroidManifest.xml28
-rw-r--r--tests/DumpRenderTree2/res/drawable/folder.pngbin0 -> 4865 bytes
-rw-r--r--tests/DumpRenderTree2/res/drawable/runtest.pngbin0 -> 3146 bytes
-rw-r--r--tests/DumpRenderTree2/res/layout/dirlist_row.xml43
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/FileFilter.java7
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/ui/DirListActivity.java253
41 files changed, 514 insertions, 1509 deletions
diff --git a/api/current.xml b/api/current.xml
index d85282b558b4..16de702b6ec3 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -4893,6 +4893,17 @@
visibility="public"
>
</field>
+<field name="immersive"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843457"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="inAnimation"
type="int"
transient="false"
@@ -6092,17 +6103,6 @@
visibility="public"
>
</field>
-<field name="kraken_resource_pad64"
- type="int"
- transient="false"
- volatile="false"
- value="16843457"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="kraken_resource_pad7"
type="int"
transient="false"
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index d5136ae98c34..140dd5544e3b 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -22,14 +22,15 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnCancelListener;
-import android.content.pm.PackageManager;
import android.database.DataSetObserver;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
+import android.graphics.DrawFilter;
import android.graphics.Interpolator;
import android.graphics.Paint;
+import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Picture;
import android.graphics.Point;
import android.graphics.Rect;
@@ -454,10 +455,6 @@ public class WebView extends AbsoluteLayout
// true if onPause has been called (and not onResume)
private boolean mIsPaused;
- // true if, during a transition to a new page, we're delaying
- // deleting a root layer until there's something to draw of the new page.
- private boolean mDelayedDeleteRootLayer;
-
/**
* Customizable constant
*/
@@ -584,8 +581,8 @@ public class WebView extends AbsoluteLayout
static final int SHOW_FULLSCREEN = 120;
static final int HIDE_FULLSCREEN = 121;
static final int DOM_FOCUS_CHANGED = 122;
- static final int IMMEDIATE_REPAINT_MSG_ID = 123;
- static final int SET_ROOT_LAYER_MSG_ID = 124;
+ static final int REPLACE_BASE_CONTENT = 123;
+ // 124;
static final int RETURN_LABEL = 125;
static final int FIND_AGAIN = 126;
static final int CENTER_FIT_RECT = 127;
@@ -633,8 +630,8 @@ public class WebView extends AbsoluteLayout
"SHOW_FULLSCREEN", // = 120;
"HIDE_FULLSCREEN", // = 121;
"DOM_FOCUS_CHANGED", // = 122;
- "IMMEDIATE_REPAINT_MSG_ID", // = 123;
- "SET_ROOT_LAYER_MSG_ID", // = 124;
+ "REPLACE_BASE_CONTENT", // = 123;
+ "124", // = 124;
"RETURN_LABEL", // = 125;
"FIND_AGAIN", // = 126;
"CENTER_FIT_RECT", // = 127;
@@ -1691,6 +1688,7 @@ public class WebView extends AbsoluteLayout
public void clearView() {
mContentWidth = 0;
mContentHeight = 0;
+ nativeSetBaseLayer(0);
mWebViewCore.sendMessage(EventHub.CLEAR_CONTENT);
}
@@ -1704,8 +1702,9 @@ public class WebView extends AbsoluteLayout
* bounds of the view.
*/
public Picture capturePicture() {
- if (null == mWebViewCore) return null; // check for out of memory tab
- return mWebViewCore.copyContentPicture();
+ Picture result = new Picture();
+ nativeCopyBaseContentToPicture(result);
+ return result;
}
/**
@@ -3232,16 +3231,6 @@ public class WebView extends AbsoluteLayout
}
}
- private void drawExtras(Canvas canvas, int extras, boolean animationsRunning) {
- // If mNativeClass is 0, we should not reach here, so we do not
- // need to check it again.
- if (animationsRunning) {
- canvas.setDrawFilter(mWebViewCore.mZoomFilter);
- }
- nativeDrawExtras(canvas, extras);
- canvas.setDrawFilter(null);
- }
-
private void onZoomAnimationStart() {
// If it is in password mode, turn it off so it does not draw misplaced.
if (inEditingMode() && nativeFocusCandidateIsPassword()) {
@@ -3268,6 +3257,18 @@ public class WebView extends AbsoluteLayout
onZoomAnimationEnd();
}
+ private static final int ZOOM_BITS = Paint.FILTER_BITMAP_FLAG |
+ Paint.DITHER_FLAG |
+ Paint.SUBPIXEL_TEXT_FLAG;
+ private static final int SCROLL_BITS = Paint.FILTER_BITMAP_FLAG |
+ Paint.DITHER_FLAG;
+
+ private final DrawFilter mZoomFilter =
+ new PaintFlagsDrawFilter(ZOOM_BITS, Paint.LINEAR_TEXT_FLAG);
+ // If we need to trade better quality for speed, set mScrollFilter to null
+ private final DrawFilter mScrollFilter =
+ new PaintFlagsDrawFilter(SCROLL_BITS, 0);
+
private void drawCoreAndCursorRing(Canvas canvas, int color,
boolean drawCursorRing) {
if (mDrawHistory) {
@@ -3275,6 +3276,7 @@ public class WebView extends AbsoluteLayout
canvas.drawPicture(mHistoryPicture);
return;
}
+ if (mNativeClass == 0) return;
boolean animateZoom = mZoomManager.isFixedLengthAnimationInProgress();
boolean animateScroll = ((!mScroller.isFinished()
@@ -3309,10 +3311,7 @@ public class WebView extends AbsoluteLayout
// we ask for a repaint.
invalidate();
}
- mWebViewCore.drawContentPicture(canvas, color,
- (mZoomManager.isZoomAnimating() || UIAnimationsRunning),
- animateScroll);
- if (mNativeClass == 0) return;
+
// decide which adornments to draw
int extras = DRAW_EXTRAS_NONE;
if (DebugFlags.WEB_VIEW) {
@@ -3332,7 +3331,18 @@ public class WebView extends AbsoluteLayout
} else if (drawCursorRing) {
extras = DRAW_EXTRAS_CURSOR_RING;
}
- drawExtras(canvas, extras, UIAnimationsRunning);
+ DrawFilter df = null;
+ if (mZoomManager.isZoomAnimating() || UIAnimationsRunning) {
+ df = mZoomFilter;
+ } else if (animateScroll) {
+ df = mScrollFilter;
+ }
+ canvas.setDrawFilter(df);
+ int content = nativeDraw(canvas, color, extras, true);
+ canvas.setDrawFilter(null);
+ if (content != 0) {
+ mWebViewCore.sendMessage(EventHub.SPLIT_PICTURE_SET, content, 0);
+ }
if (extras == DRAW_EXTRAS_CURSOR_RING) {
if (mTouchMode == TOUCH_SHORTPRESS_START_MODE) {
@@ -3368,7 +3378,7 @@ public class WebView extends AbsoluteLayout
// Should only be called in UI thread
void switchOutDrawHistory() {
if (null == mWebViewCore) return; // CallbackProxy may trigger this
- if (mDrawHistory && mWebViewCore.pictureReady()) {
+ if (mDrawHistory && (getProgress() == 100 || nativeHasContent())) {
mDrawHistory = false;
mHistoryPicture = null;
invalidate();
@@ -6036,16 +6046,14 @@ public class WebView extends AbsoluteLayout
mZoomManager.updateZoomRange(viewState, getViewWidth(), viewState.mScrollX);
break;
}
+ case REPLACE_BASE_CONTENT: {
+ nativeReplaceBaseContent(msg.arg1);
+ break;
+ }
case NEW_PICTURE_MSG_ID: {
- // If we've previously delayed deleting a root
- // layer, do it now.
- if (mDelayedDeleteRootLayer) {
- mDelayedDeleteRootLayer = false;
- nativeSetRootLayer(0);
- }
// called for new content
final WebViewCore.DrawData draw = (WebViewCore.DrawData) msg.obj;
-
+ nativeSetBaseLayer(draw.mBaseLayer);
final Point viewSize = draw.mViewPoint;
WebViewCore.ViewState viewState = draw.mViewState;
boolean isPictureAfterFirstLayout = viewState != null;
@@ -6166,23 +6174,6 @@ public class WebView extends AbsoluteLayout
}
break;
}
- case IMMEDIATE_REPAINT_MSG_ID: {
- invalidate();
- break;
- }
- case SET_ROOT_LAYER_MSG_ID: {
- if (0 == msg.arg1) {
- // Null indicates deleting the old layer, but
- // don't actually do so until we've got the
- // new page to display.
- mDelayedDeleteRootLayer = true;
- } else {
- mDelayedDeleteRootLayer = false;
- nativeSetRootLayer(msg.arg1);
- invalidate();
- }
- break;
- }
case REQUEST_FORM_DATA:
AutoCompleteAdapter adapter = (AutoCompleteAdapter) msg.obj;
if (mWebTextView.isSameTextField(msg.arg1)) {
@@ -6944,7 +6935,7 @@ public class WebView extends AbsoluteLayout
* @hide only needs to be accessible to Browser and testing
*/
public void drawPage(Canvas canvas) {
- mWebViewCore.drawContentPicture(canvas, 0, false, false);
+ nativeDraw(canvas, 0, 0, false);
}
/**
@@ -6988,7 +6979,15 @@ public class WebView extends AbsoluteLayout
private native boolean nativeCursorWantsKeyEvents();
private native void nativeDebugDump();
private native void nativeDestroy();
- private native void nativeDrawExtras(Canvas canvas, int extra);
+
+ /**
+ * Draw the picture set with a background color and extra. If
+ * "splitIfNeeded" is true and the return value is not 0, the return value
+ * MUST be passed to WebViewCore with SPLIT_PICTURE_SET message so that the
+ * native allocation can be freed.
+ */
+ private native int nativeDraw(Canvas canvas, int color, int extra,
+ boolean splitIfNeeded);
private native void nativeDumpDisplayTree(String urlOrNull);
private native boolean nativeEvaluateLayersAnimations();
private native void nativeExtendSelection(int x, int y);
@@ -7053,7 +7052,10 @@ public class WebView extends AbsoluteLayout
private native void nativeSetFindIsUp(boolean isUp);
private native void nativeSetFollowedLink(boolean followed);
private native void nativeSetHeightCanMeasure(boolean measure);
- private native void nativeSetRootLayer(int layer);
+ private native void nativeSetBaseLayer(int layer);
+ private native void nativeReplaceBaseContent(int content);
+ private native void nativeCopyBaseContentToPicture(Picture pict);
+ private native boolean nativeHasContent();
private native void nativeSetSelectionPointer(boolean set,
float scale, int x, int y);
private native boolean nativeStartSelection(int x, int y);
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 54699d6493a8..db86a0bcb234 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -19,11 +19,6 @@ package android.webkit;
import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.Cursor;
-import android.graphics.Canvas;
-import android.graphics.DrawFilter;
-import android.graphics.Paint;
-import android.graphics.PaintFlagsDrawFilter;
-import android.graphics.Picture;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
@@ -33,7 +28,6 @@ import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.provider.MediaStore;
-import android.provider.MediaStore.Images.Media;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.KeyEvent;
@@ -443,35 +437,18 @@ final class WebViewCore {
private native void nativeClearContent();
/**
- * Create a flat picture from the set of pictures.
- */
- private native void nativeCopyContentToPicture(Picture picture);
-
- /**
- * Draw the picture set with a background color. Returns true
- * if some individual picture took too long to draw and can be
- * split into parts. Called from the UI thread.
- */
- private native boolean nativeDrawContent(Canvas canvas, int color);
-
- /**
- * check to see if picture is blank and in progress
- */
- private native boolean nativePictureReady();
-
- /**
* Redraw a portion of the picture set. The Point wh returns the
* width and height of the overall picture.
*/
- private native boolean nativeRecordContent(Region invalRegion, Point wh);
+ private native int nativeRecordContent(Region invalRegion, Point wh);
private native boolean nativeFocusBoundsChanged();
/**
- * Splits slow parts of the picture set. Called from the webkit
- * thread after nativeDrawContent returns true.
+ * Splits slow parts of the picture set. Called from the webkit thread after
+ * WebView.nativeDraw() returns content to be split.
*/
- private native void nativeSplitContent();
+ private native void nativeSplitContent(int content);
private native boolean nativeKey(int keyCode, int unichar,
int repeatCount, boolean isShift, boolean isAlt, boolean isSym,
@@ -1336,7 +1313,9 @@ final class WebViewCore {
break;
case SPLIT_PICTURE_SET:
- nativeSplitContent();
+ nativeSplitContent(msg.arg1);
+ mWebView.mPrivateHandler.obtainMessage(
+ WebView.REPLACE_BASE_CONTENT, msg.arg1, 0);
mSplitPictureIsScheduled = false;
break;
@@ -1736,6 +1715,14 @@ final class WebViewCore {
return usedQuota;
}
+ // called from UI thread
+ void splitContent(int content) {
+ if (!mSplitPictureIsScheduled) {
+ mSplitPictureIsScheduled = true;
+ sendMessage(EventHub.SPLIT_PICTURE_SET, content, 0);
+ }
+ }
+
// Used to avoid posting more than one draw message.
private boolean mDrawIsScheduled;
@@ -1762,9 +1749,11 @@ final class WebViewCore {
static class DrawData {
DrawData() {
+ mBaseLayer = 0;
mInvalRegion = new Region();
mWidthHeight = new Point();
}
+ int mBaseLayer;
Region mInvalRegion;
Point mViewPoint;
Point mWidthHeight;
@@ -1778,8 +1767,8 @@ final class WebViewCore {
mDrawIsScheduled = false;
DrawData draw = new DrawData();
if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw start");
- if (nativeRecordContent(draw.mInvalRegion, draw.mWidthHeight)
- == false) {
+ draw.mBaseLayer = nativeRecordContent(draw.mInvalRegion, draw.mWidthHeight);
+ if (draw.mBaseLayer == 0) {
if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw abort");
return;
}
@@ -1812,51 +1801,6 @@ final class WebViewCore {
}
}
- ///////////////////////////////////////////////////////////////////////////
- // These are called from the UI thread, not our thread
-
- static final int ZOOM_BITS = Paint.FILTER_BITMAP_FLAG |
- Paint.DITHER_FLAG |
- Paint.SUBPIXEL_TEXT_FLAG;
- static final int SCROLL_BITS = Paint.FILTER_BITMAP_FLAG |
- Paint.DITHER_FLAG;
-
- final DrawFilter mZoomFilter =
- new PaintFlagsDrawFilter(ZOOM_BITS, Paint.LINEAR_TEXT_FLAG);
- // If we need to trade better quality for speed, set mScrollFilter to null
- final DrawFilter mScrollFilter =
- new PaintFlagsDrawFilter(SCROLL_BITS, 0);
-
- /* package */ void drawContentPicture(Canvas canvas, int color,
- boolean animatingZoom,
- boolean animatingScroll) {
- DrawFilter df = null;
- if (animatingZoom) {
- df = mZoomFilter;
- } else if (animatingScroll) {
- df = mScrollFilter;
- }
- canvas.setDrawFilter(df);
- boolean tookTooLong = nativeDrawContent(canvas, color);
- canvas.setDrawFilter(null);
- if (tookTooLong && mSplitPictureIsScheduled == false) {
- mSplitPictureIsScheduled = true;
- sendMessage(EventHub.SPLIT_PICTURE_SET);
- }
- }
-
- /* package */ synchronized boolean pictureReady() {
- return 0 != mNativeClass ? nativePictureReady() : false;
- }
-
- /*package*/ synchronized Picture copyContentPicture() {
- Picture result = new Picture();
- if (0 != mNativeClass) {
- nativeCopyContentToPicture(result);
- }
- return result;
- }
-
static void reducePriority() {
// remove the pending REDUCE_PRIORITY and RESUME_PRIORITY messages
sWebCoreHandler.removeMessages(WebCoreThread.REDUCE_PRIORITY);
@@ -2038,24 +1982,6 @@ final class WebViewCore {
mRepaintScheduled = false;
}
- // called by JNI
- private void sendImmediateRepaint() {
- if (mWebView != null && !mRepaintScheduled) {
- mRepaintScheduled = true;
- Message.obtain(mWebView.mPrivateHandler,
- WebView.IMMEDIATE_REPAINT_MSG_ID).sendToTarget();
- }
- }
-
- // called by JNI
- private void setRootLayer(int layer) {
- if (mWebView != null) {
- Message.obtain(mWebView.mPrivateHandler,
- WebView.SET_ROOT_LAYER_MSG_ID,
- layer, 0).sendToTarget();
- }
- }
-
/* package */ WebView getWebView() {
return mWebView;
}
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index b9e5e8400aa1..8b9a4aef33a2 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1246,6 +1246,7 @@
<public type="attr" name="logo" id="0x010102be" />
<public type="attr" name="xlargeScreens" id="0x010102bf" />
<public type="attr" name="heavyWeight" id="0x010102c0" />
+ <public type="attr" name="immersive" id="0x010102c1" />
<public-padding type="attr" name="kraken_resource_pad" end="0x01010300" />
<public-padding type="id" name="kraken_resource_pad" end="0x01020040" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 289ec32e2a2c..7a80884a21e7 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1605,7 +1605,7 @@
<!-- Do not translate. WebView User Agent string -->
<string name="web_user_agent" translatable="false">Mozilla/5.0 (Linux; U; <xliff:g id="x">Android %s</xliff:g>)
- AppleWebKit/534.2 (KHTML, like Gecko) Version/4.0 <xliff:g id="mobile">%s</xliff:g>Safari/534.2</string>
+ AppleWebKit/534.3 (KHTML, like Gecko) Version/4.0 <xliff:g id="mobile">%s</xliff:g>Safari/534.3</string>
<!-- Title for a JavaScript dialog. "The page at <url of current page> says:" -->
<string name="js_dialog_title">The page at \'<xliff:g id="title">%s</xliff:g>\' says:</string>
diff --git a/include/media/MediaRecorderBase.h b/include/media/MediaRecorderBase.h
index 497965c9a6da..5e9e3681a672 100644
--- a/include/media/MediaRecorderBase.h
+++ b/include/media/MediaRecorderBase.h
@@ -48,6 +48,7 @@ struct MediaRecorderBase {
virtual status_t close() = 0;
virtual status_t reset() = 0;
virtual status_t getMaxAmplitude(int *max) = 0;
+ virtual status_t dump(int fd, const Vector<String16>& args) const = 0;
private:
MediaRecorderBase(const MediaRecorderBase &);
diff --git a/include/media/PVMediaRecorder.h b/include/media/PVMediaRecorder.h
index c04105eae55f..f75d80df7221 100644
--- a/include/media/PVMediaRecorder.h
+++ b/include/media/PVMediaRecorder.h
@@ -52,6 +52,7 @@ public:
virtual status_t close();
virtual status_t reset();
virtual status_t getMaxAmplitude(int *max);
+ virtual status_t dump(int fd, const Vector<String16>& args) const;
private:
status_t doStop();
diff --git a/media/java/android/media/MtpDatabase.java b/media/java/android/media/MtpDatabase.java
index 0869530a6928..e37ea930e6c2 100644
--- a/media/java/android/media/MtpDatabase.java
+++ b/media/java/android/media/MtpDatabase.java
@@ -74,26 +74,6 @@ public class MtpDatabase {
native_finalize();
}
- // called from native code
- private int getObjectHandle(String path) {
- Log.d(TAG, "getObjectHandle " + path);
- Cursor c = null;
- try {
- c = mMediaProvider.query(mObjectsUri, ID_PROJECTION,
- PATH_WHERE, new String[] { path }, null);
- if (c != null && c.moveToNext()) {
- return c.getInt(0);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getObjectHandle", e);
- } finally {
- if (c != null) {
- c.close();
- }
- }
- return 0;
- }
-
private int addFile(String path, int format, int parent,
int storage, long size, long modified) {
Log.d(TAG, "addFile " + path);
diff --git a/media/jni/android_media_MtpDatabase.cpp b/media/jni/android_media_MtpDatabase.cpp
index 86d1fc45b0c7..6bdd8f028e34 100644
--- a/media/jni/android_media_MtpDatabase.cpp
+++ b/media/jni/android_media_MtpDatabase.cpp
@@ -36,7 +36,6 @@ using namespace android;
// ----------------------------------------------------------------------------
-static jmethodID method_getObjectHandle;
static jmethodID method_addFile;
static jmethodID method_getObjectList;
static jmethodID method_getObjectProperty;
@@ -63,8 +62,6 @@ public:
virtual ~MyMtpDatabase();
void cleanup(JNIEnv *env);
- virtual MtpObjectHandle getObjectHandle(const char* path);
-
virtual MtpObjectHandle addFile(const char* path,
MtpObjectFormat format,
MtpObjectHandle parent,
@@ -138,11 +135,6 @@ void MyMtpDatabase::cleanup(JNIEnv *env) {
MyMtpDatabase::~MyMtpDatabase() {
}
-MtpObjectHandle MyMtpDatabase::getObjectHandle(const char* path) {
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- return env->CallIntMethod(mDatabase, method_getObjectHandle, env->NewStringUTF(path));
-}
-
MtpObjectHandle MyMtpDatabase::addFile(const char* path,
MtpObjectFormat format,
MtpObjectHandle parent,
@@ -405,11 +397,6 @@ int register_android_media_MtpDatabase(JNIEnv *env)
LOGE("Can't find android/media/MtpDatabase");
return -1;
}
- method_getObjectHandle = env->GetMethodID(clazz, "getObjectHandle", "(Ljava/lang/String;)I");
- if (method_getObjectHandle == NULL) {
- LOGE("Can't find getObjectHandle");
- return -1;
- }
method_addFile = env->GetMethodID(clazz, "addFile", "(Ljava/lang/String;IIIJJ)I");
if (method_addFile == NULL) {
LOGE("Can't find addFile");
diff --git a/media/jni/android_media_MtpServer.cpp b/media/jni/android_media_MtpServer.cpp
index 6a1c64b0dca9..17e85f8ad43e 100644
--- a/media/jni/android_media_MtpServer.cpp
+++ b/media/jni/android_media_MtpServer.cpp
@@ -30,7 +30,6 @@
#include "private/android_filesystem_config.h"
#include "MtpServer.h"
-#include "MtpSqliteDatabase.h" // REMOVE
using namespace android;
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 4872047cd8a0..5401ec07c038 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -511,11 +511,17 @@ status_t MediaPlayerService::dump(int fd, const Vector<String16>& args)
sp<Client> c = mClients[i].promote();
if (c != 0) c->dump(fd, args);
}
- for (int i = 0, n = mMediaRecorderClients.size(); i < n; ++i) {
- result.append(" MediaRecorderClient\n");
- sp<MediaRecorderClient> c = mMediaRecorderClients[i].promote();
- snprintf(buffer, 255, " pid(%d)\n\n", c->mPid);
- result.append(buffer);
+ if (mMediaRecorderClients.size() == 0) {
+ result.append(" No media recorder client\n\n");
+ } else {
+ for (int i = 0, n = mMediaRecorderClients.size(); i < n; ++i) {
+ sp<MediaRecorderClient> c = mMediaRecorderClients[i].promote();
+ snprintf(buffer, 255, " MediaRecorderClient pid(%d)\n", c->mPid);
+ result.append(buffer);
+ write(fd, result.string(), result.size());
+ result = "\n";
+ c->dump(fd, args);
+ }
}
result.append(" Files opened and/or mapped:\n");
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index 80b1cfd00e2e..fef3e6e6ce4d 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -329,5 +329,12 @@ status_t MediaRecorderClient::setListener(const sp<IMediaRecorderClient>& listen
return mRecorder->setListener(listener);
}
+status_t MediaRecorderClient::dump(int fd, const Vector<String16>& args) const {
+ if (mRecorder != NULL) {
+ return mRecorder->dump(fd, args);
+ }
+ return OK;
+}
+
}; // namespace android
diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h
index b53d950ab6f2..d12e558da431 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.h
+++ b/media/libmediaplayerservice/MediaRecorderClient.h
@@ -28,7 +28,7 @@ class MediaPlayerService;
class MediaRecorderClient : public BnMediaRecorder
{
public:
- virtual status_t setCamera(const sp<ICamera>& camera);
+ virtual status_t setCamera(const sp<ICamera>& camera);
virtual status_t setPreviewSurface(const sp<ISurface>& surface);
virtual status_t setVideoSource(int vs);
virtual status_t setAudioSource(int as);
@@ -45,21 +45,22 @@ public:
virtual status_t getMaxAmplitude(int* max);
virtual status_t start();
virtual status_t stop();
- virtual status_t reset();
+ virtual status_t reset();
virtual status_t init();
virtual status_t close();
virtual status_t release();
+ virtual status_t dump(int fd, const Vector<String16>& args) const;
private:
- friend class MediaPlayerService; // for accessing private constructor
+ friend class MediaPlayerService; // for accessing private constructor
- MediaRecorderClient(const sp<MediaPlayerService>& service, pid_t pid);
- virtual ~MediaRecorderClient();
+ MediaRecorderClient(const sp<MediaPlayerService>& service, pid_t pid);
+ virtual ~MediaRecorderClient();
- pid_t mPid;
- Mutex mLock;
- MediaRecorderBase *mRecorder;
- sp<MediaPlayerService> mMediaPlayerService;
+ pid_t mPid;
+ Mutex mLock;
+ MediaRecorderBase *mRecorder;
+ sp<MediaPlayerService> mMediaPlayerService;
};
}; // namespace android
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 509c6fd2cbe8..139992a2bf0c 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -1061,4 +1061,64 @@ status_t StagefrightRecorder::getMaxAmplitude(int *max) {
return OK;
}
+status_t StagefrightRecorder::dump(int fd, const Vector<String16>& args) const {
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+ snprintf(buffer, SIZE, " Recorder: %p", this);
+ snprintf(buffer, SIZE, " Output file (fd %d):\n", mOutputFd);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " File format: %d\n", mOutputFormat);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Max file size (bytes): %lld\n", mMaxFileSizeBytes);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Max file duration (us): %lld\n", mMaxFileDurationUs);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " File offset length (bits): %d\n", mUse64BitFileOffset? 64: 32);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Interleave duration (us): %d\n", mInterleaveDurationUs);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Progress notification: %d frames\n", mTrackEveryNumberOfFrames);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Progress notification: %lld us\n", mTrackEveryTimeDurationUs);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Audio\n");
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Source: %d\n", mAudioSource);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Encoder: %d\n", mAudioEncoder);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Bit rate (bps): %d\n", mAudioBitRate);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Sampling rate (hz): %d\n", mSampleRate);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Number of channels: %d\n", mAudioChannels);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Max amplitude: %d\n", mAudioSourceNode == 0? 0: mAudioSourceNode->getMaxAmplitude());
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Video\n");
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Source: %d\n", mVideoSource);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Camera Id: %d\n", mCameraId);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Camera flags: %d\n", mFlags);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Encoder: %d\n", mVideoEncoder);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Encoder profile: %d\n", mVideoEncoderProfile);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Encoder level: %d\n", mVideoEncoderLevel);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " I frames interval (s): %d\n", mIFramesInterval);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Frame size (pixels): %dx%d\n", mVideoWidth, mVideoHeight);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Frame rate (fps): %d\n", mFrameRate);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Bit rate (bps): %d\n", mVideoBitRate);
+ result.append(buffer);
+ ::write(fd, result.string(), result.size());
+ return OK;
+}
} // namespace android
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index 20906664748b..58f0031a68d0 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -54,6 +54,7 @@ struct StagefrightRecorder : public MediaRecorderBase {
virtual status_t close();
virtual status_t reset();
virtual status_t getMaxAmplitude(int *max);
+ virtual status_t dump(int fd, const Vector<String16>& args) const;
private:
enum CameraFlags {
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 83f7040200dc..efaab5b4cf72 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -948,7 +948,7 @@ status_t OMXCodec::getVideoProfileLevel(
int32_t supportedProfile = static_cast<int32_t>(param.eProfile);
int32_t supportedLevel = static_cast<int32_t>(param.eLevel);
- CODEC_LOGV("Supported profile: %ld, level %ld",
+ CODEC_LOGV("Supported profile: %d, level %d",
supportedProfile, supportedLevel);
if (profile == supportedProfile &&
diff --git a/media/mtp/Android.mk b/media/mtp/Android.mk
index e5238159aa10..174ea3695bf1 100644
--- a/media/mtp/Android.mk
+++ b/media/mtp/Android.mk
@@ -24,62 +24,19 @@ LOCAL_SRC_FILES:= \
MtpDebug.cpp \
MtpDevice.cpp \
MtpDeviceInfo.cpp \
- MtpMediaScanner.cpp \
MtpObjectInfo.cpp \
MtpPacket.cpp \
MtpProperty.cpp \
MtpRequestPacket.cpp \
MtpResponsePacket.cpp \
MtpServer.cpp \
- MtpSqliteDatabase.cpp \
MtpStorageInfo.cpp \
MtpStringBuffer.cpp \
MtpStorage.cpp \
MtpUtils.cpp \
- SqliteDatabase.cpp \
- SqliteStatement.cpp \
LOCAL_MODULE:= libmtp
-LOCAL_C_INCLUDES := external/sqlite/dist
-
LOCAL_CFLAGS := -DMTP_DEVICE -DMTP_HOST
include $(BUILD_STATIC_LIBRARY)
-
-ifneq ($(TARGET_SIMULATOR),true)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- mtptest.cpp \
-
-LOCAL_MODULE:= mtptest
-
-LOCAL_CFLAGS := -DMTP_DEVICE
-
-LOCAL_SHARED_LIBRARIES := libutils libsqlite libcutils \
- libmedia
-
-LOCAL_STATIC_LIBRARIES := libmtp
-
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := scantest
-LOCAL_SRC_FILES:= \
- scantest.cpp \
-
-
-LOCAL_STATIC_LIBRARIES := libmtp
-
-LOCAL_C_INCLUDES := external/sqlite/dist
-LOCAL_SHARED_LIBRARIES := libutils libsqlite libmedia
-
-LOCAL_CFLAGS := -g
-LOCAL_LDFLAGS := -g
-
-include $(BUILD_EXECUTABLE)
-
-endif
diff --git a/media/mtp/MtpDatabase.h b/media/mtp/MtpDatabase.h
index a6aaf0f6987e..1566a111e62a 100644
--- a/media/mtp/MtpDatabase.h
+++ b/media/mtp/MtpDatabase.h
@@ -18,7 +18,6 @@
#define _MTP_DATABASE_H
#include "MtpTypes.h"
-#include "SqliteDatabase.h"
namespace android {
@@ -28,7 +27,6 @@ class MtpDatabase {
public:
virtual ~MtpDatabase() {}
- virtual MtpObjectHandle getObjectHandle(const char* path) = 0;
virtual MtpObjectHandle addFile(const char* path,
MtpObjectFormat format,
MtpObjectHandle parent,
@@ -52,9 +50,6 @@ public:
int64_t& fileLength) = 0;
virtual bool deleteFile(MtpObjectHandle handle) = 0;
- // helper for media scanner
- virtual MtpObjectHandle* getFileList(int& outCount) = 0;
-
virtual void beginTransaction() = 0;
virtual void commitTransaction() = 0;
virtual void rollbackTransaction() = 0;
diff --git a/media/mtp/MtpMediaScanner.cpp b/media/mtp/MtpMediaScanner.cpp
deleted file mode 100644
index a9adf01f51f4..000000000000
--- a/media/mtp/MtpMediaScanner.cpp
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "MtpMediaScanner"
-
-#include "MtpDebug.h"
-#include "MtpDatabase.h"
-#include "MtpMediaScanner.h"
-#include "mtp.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/statfs.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <limits.h>
-
-namespace android {
-
-MtpMediaScanner::MtpMediaScanner(MtpStorageID id, const char* filePath, MtpDatabase* db)
- : mStorageID(id),
- mFilePath(filePath),
- mDatabase(db),
- mFileList(NULL),
- mFileCount(0)
-{
-}
-
-MtpMediaScanner::~MtpMediaScanner() {
-}
-
-bool MtpMediaScanner::scanFiles() {
- mDatabase->beginTransaction();
- mFileCount = 0;
- mFileList = mDatabase->getFileList(mFileCount);
-
- int ret = scanDirectory(mFilePath, MTP_PARENT_ROOT);
-
- for (int i = 0; i < mFileCount; i++) {
- MtpObjectHandle test = mFileList[i];
- if (! (test & kObjectHandleMarkBit)) {
- LOGV("delete missing file %08X", test);
- mDatabase->deleteFile(test);
- }
- }
-
- delete[] mFileList;
- mFileCount = 0;
- mDatabase->commitTransaction();
- return (ret == 0);
-}
-
-
-static const struct MediaFileTypeEntry
-{
- const char* extension;
- MtpObjectFormat format;
-} sFileTypes[] =
-{
- { "MP3", MTP_FORMAT_MP3, },
- { "M4A", MTP_FORMAT_UNDEFINED_AUDIO, },
- { "WAV", MTP_FORMAT_WAV, },
- { "AMR", MTP_FORMAT_UNDEFINED_AUDIO, },
- { "AWB", MTP_FORMAT_UNDEFINED_AUDIO, },
- { "WMA", MTP_FORMAT_WMA, },
- { "OGG", MTP_FORMAT_OGG, },
- { "OGA", MTP_FORMAT_UNDEFINED_AUDIO, },
- { "AAC", MTP_FORMAT_AAC, },
- { "MID", MTP_FORMAT_UNDEFINED_AUDIO, },
- { "MIDI", MTP_FORMAT_UNDEFINED_AUDIO, },
- { "XMF", MTP_FORMAT_UNDEFINED_AUDIO, },
- { "RTTTL", MTP_FORMAT_UNDEFINED_AUDIO, },
- { "SMF", MTP_FORMAT_UNDEFINED_AUDIO, },
- { "IMY", MTP_FORMAT_UNDEFINED_AUDIO, },
- { "RTX", MTP_FORMAT_UNDEFINED_AUDIO, },
- { "OTA", MTP_FORMAT_UNDEFINED_AUDIO, },
- { "MPEG", MTP_FORMAT_UNDEFINED_VIDEO, },
- { "MP4", MTP_FORMAT_UNDEFINED_VIDEO, },
- { "M4V", MTP_FORMAT_UNDEFINED_VIDEO, },
- { "3GP", MTP_FORMAT_UNDEFINED_VIDEO, },
- { "3GPP", MTP_FORMAT_UNDEFINED_VIDEO, },
- { "3G2", MTP_FORMAT_UNDEFINED_VIDEO, },
- { "3GPP2", MTP_FORMAT_UNDEFINED_VIDEO, },
- { "WMV", MTP_FORMAT_UNDEFINED_VIDEO, },
- { "ASF", MTP_FORMAT_UNDEFINED_VIDEO, },
- { "JPG", MTP_FORMAT_EXIF_JPEG, },
- { "JPEG", MTP_FORMAT_EXIF_JPEG, },
- { "GIF", MTP_FORMAT_GIF, },
- { "PNG", MTP_FORMAT_PNG, },
- { "BMP", MTP_FORMAT_BMP, },
- { "WBMP", MTP_FORMAT_BMP, },
- { "M3U", MTP_FORMAT_M3U_PLAYLIST, },
- { "PLS", MTP_FORMAT_PLS_PLAYLIST, },
- { "WPL", MTP_FORMAT_WPL_PLAYLIST, },
-};
-
-MtpObjectFormat MtpMediaScanner::getFileFormat(const char* path)
-{
- const char* extension = strrchr(path, '.');
- if (!extension)
- return MTP_FORMAT_UNDEFINED;
- extension++; // skip the dot
-
- for (unsigned i = 0; i < sizeof(sFileTypes) / sizeof(sFileTypes[0]); i++) {
- if (!strcasecmp(extension, sFileTypes[i].extension)) {
- return sFileTypes[i].format;
- }
- }
- return MTP_FORMAT_UNDEFINED;
-}
-
-int MtpMediaScanner::scanDirectory(const char* path, MtpObjectHandle parent)
-{
- char buffer[PATH_MAX];
- struct dirent* entry;
-
- unsigned length = strlen(path);
- if (length > sizeof(buffer) + 2) {
- LOGE("path too long: %s", path);
- }
-
- DIR* dir = opendir(path);
- if (!dir) {
- LOGE("opendir %s failed, errno: %d", path, errno);
- return -1;
- }
-
- strncpy(buffer, path, sizeof(buffer));
- char* fileStart = buffer + length;
- // make sure we have a trailing slash
- if (fileStart[-1] != '/') {
- *(fileStart++) = '/';
- }
- int fileNameLength = sizeof(buffer) + fileStart - buffer;
-
- while ((entry = readdir(dir))) {
- const char* name = entry->d_name;
-
- // ignore "." and "..", as well as any files or directories staring with dot
- if (name[0] == '.') {
- continue;
- }
- if (strlen(name) + 1 > fileNameLength) {
- LOGE("path too long for %s", name);
- continue;
- }
- strcpy(fileStart, name);
-
- struct stat statbuf;
- memset(&statbuf, 0, sizeof(statbuf));
- stat(buffer, &statbuf);
-
- if (S_ISDIR(statbuf.st_mode)) {
- MtpObjectHandle handle = mDatabase->getObjectHandle(buffer);
- if (handle) {
- markFile(handle);
- } else {
- handle = mDatabase->addFile(buffer, MTP_FORMAT_ASSOCIATION,
- parent, mStorageID, 0, statbuf.st_mtime);
- }
- scanDirectory(buffer, handle);
- } else if (S_ISREG(statbuf.st_mode)) {
- scanFile(buffer, parent, statbuf);
- }
- }
-
- closedir(dir);
- return 0;
-}
-
-void MtpMediaScanner::scanFile(const char* path, MtpObjectHandle parent, struct stat& statbuf) {
- MtpObjectFormat format = getFileFormat(path);
- // don't scan unknown file types
- if (format == MTP_FORMAT_UNDEFINED)
- return;
- MtpObjectHandle handle = mDatabase->getObjectHandle(path);
- // fixme - rescan if mod date changed
- if (handle) {
- markFile(handle);
- } else {
- mDatabase->beginTransaction();
- handle = mDatabase->addFile(path, format, parent, mStorageID,
- statbuf.st_size, statbuf.st_mtime);
- if (handle <= 0) {
- LOGE("addFile failed in MtpMediaScanner::scanFile()");
- mDatabase->rollbackTransaction();
- return;
- }
- mDatabase->commitTransaction();
- }
-}
-
-void MtpMediaScanner::markFile(MtpObjectHandle handle) {
- if (mFileList) {
- handle &= kObjectHandleIndexMask;
- // binary search for the file in mFileList
- int low = 0;
- int high = mFileCount;
- int index;
-
- while (low < high) {
- index = (low + high) >> 1;
- MtpObjectHandle test = (mFileList[index] & kObjectHandleIndexMask);
- if (handle < test)
- high = index; // item is less than index
- else if (handle > test)
- low = index + 1; // item is greater than index
- else {
- mFileList[index] |= kObjectHandleMarkBit;
- return;
- }
- }
- LOGE("file %d not found in mFileList", handle);
- }
-}
-
-} // namespace android
diff --git a/media/mtp/MtpMediaScanner.h b/media/mtp/MtpMediaScanner.h
deleted file mode 100644
index 9cf10c56fd20..000000000000
--- a/media/mtp/MtpMediaScanner.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#ifndef _MTP_MEDIA_SCANNER_H
-#define _MTP_MEDIA_SCANNER_H
-
-struct stat;
-
-namespace android {
-
-class MtpDatabase;
-class SqliteStatement;
-
-class MtpMediaScanner {
-private:
- MtpStorageID mStorageID;
- const char* mFilePath;
- MtpDatabase* mDatabase;
-
- // for garbage collecting missing files
- MtpObjectHandle* mFileList;
- int mFileCount;
-
-public:
- MtpMediaScanner(MtpStorageID id, const char* filePath, MtpDatabase* db);
- virtual ~MtpMediaScanner();
-
- bool scanFiles();
-
-private:
- MtpObjectFormat getFileFormat(const char* path);
- int scanDirectory(const char* path, MtpObjectHandle parent);
- void scanFile(const char* path, MtpObjectHandle parent, struct stat& statbuf);
- void markFile(MtpObjectHandle handle);
-};
-
-}; // namespace android
-
-#endif // _MTP_MEDIA_SCANNER_H
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index 967ebc9c02bd..5a16a0385d8b 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -25,9 +25,9 @@
#include <cutils/properties.h>
#include "MtpDebug.h"
+#include "MtpDatabase.h"
#include "MtpProperty.h"
#include "MtpServer.h"
-#include "MtpSqliteDatabase.h"
#include "MtpStorage.h"
#include "MtpStringBuffer.h"
@@ -147,13 +147,6 @@ MtpStorage* MtpServer::getStorage(MtpStorageID id) {
return NULL;
}
-void MtpServer::scanStorage() {
- for (int i = 0; i < mStorages.size(); i++) {
- MtpStorage* storage = mStorages[i];
- storage->scanFiles();
- }
-}
-
void MtpServer::run() {
int fd = mFD;
diff --git a/media/mtp/MtpServer.h b/media/mtp/MtpServer.h
index 09556b37452f..afba8460b477 100644
--- a/media/mtp/MtpServer.h
+++ b/media/mtp/MtpServer.h
@@ -71,7 +71,6 @@ public:
void addStorage(const char* filePath);
inline void addStorage(MtpStorage* storage) { mStorages.push(storage); }
MtpStorage* getStorage(MtpStorageID id);
- void scanStorage();
void run();
MtpProperty* getObjectProperty(MtpPropertyCode propCode);
diff --git a/media/mtp/MtpSqliteDatabase.cpp b/media/mtp/MtpSqliteDatabase.cpp
deleted file mode 100644
index eae9cb8d9a64..000000000000
--- a/media/mtp/MtpSqliteDatabase.cpp
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "MtpSqliteDatabase"
-
-#include "MtpDebug.h"
-#include "MtpSqliteDatabase.h"
-#include "MtpDataPacket.h"
-#include "MtpUtils.h"
-#include "SqliteDatabase.h"
-#include "SqliteStatement.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sqlite3.h>
-
-namespace android {
-
-#define FILE_ID_COLUMN 1
-#define FILE_PATH_COLUMN 2
-#define FILE_FORMAT_COLUMN 3
-#define FILE_PARENT_COLUMN 4
-#define FILE_STORAGE_COLUMN 5
-#define FILE_SIZE_COLUMN 6
-#define FILE_MODIFIED_COLUMN 7
-
-#define FILE_TABLE_CREATE "CREATE TABLE IF NOT EXISTS files (" \
- "_id INTEGER PRIMARY KEY," \
- "path TEXT," \
- "format INTEGER," \
- "parent INTEGER," \
- "storage INTEGER," \
- "size INTEGER," \
- "date_modified INTEGER" \
- ");"
-
-#define PATH_INDEX_CREATE "CREATE INDEX IF NOT EXISTS path_index on files(path);"
-
-#define FILE_ID_QUERY "SELECT _id,format FROM files WHERE path = ?;"
-#define FILE_PATH_QUERY "SELECT path,size FROM files WHERE _id = ?"
-
-#define GET_OBJECT_INFO_QUERY "SELECT storage,format,parent,path,size,date_modified FROM files WHERE _id = ?;"
-#define FILE_INSERT "INSERT INTO files VALUES(?,?,?,?,?,?,?);"
-#define FILE_DELETE "DELETE FROM files WHERE _id = ?;"
-
-struct PropertyTableEntry {
- MtpObjectProperty property;
- int type;
- const char* columnName;
-};
-
-static const PropertyTableEntry kPropertyTable[] = {
- { MTP_PROPERTY_PARENT_OBJECT, MTP_TYPE_UINT32, "parent" },
- { MTP_PROPERTY_STORAGE_ID, MTP_TYPE_UINT32, "storage" },
- { MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT32, "format" },
- { MTP_PROPERTY_OBJECT_FILE_NAME, MTP_TYPE_STR, "path" },
- { MTP_PROPERTY_OBJECT_SIZE, MTP_TYPE_UINT64, "size" },
- { MTP_PROPERTY_DATE_MODIFIED, MTP_TYPE_STR, "date_modified" },
-};
-
-static bool getPropertyInfo(MtpObjectProperty property, int& type, const char*& columnName) {
- int count = sizeof(kPropertyTable) / sizeof(kPropertyTable[0]);
- const PropertyTableEntry* entry = kPropertyTable;
- for (int i = 0; i < count; i++, entry++) {
- if (entry->property == property) {
- type = entry->type;
- columnName = entry->columnName;
- return true;
- }
- }
- return false;
-}
-
-MtpSqliteDatabase::MtpSqliteDatabase()
- : mDatabase(NULL),
- mFileIdQuery(NULL),
- mFilePathQuery(NULL),
- mObjectInfoQuery(NULL),
- mFileInserter(NULL),
- mFileDeleter(NULL)
-{
-}
-
-MtpSqliteDatabase::~MtpSqliteDatabase() {
- delete mDatabase;
- delete mFileIdQuery;
- delete mFilePathQuery;
- delete mObjectInfoQuery;
- delete mFileInserter;
- delete mFileDeleter;
-}
-
-bool MtpSqliteDatabase::open(const char* path, bool create) {
- mDatabase = new SqliteDatabase;
-
- if (!mDatabase->open(path, create))
- goto fail;
-
- // create tables and indices if necessary
- if (!mDatabase->exec(FILE_TABLE_CREATE)) {
- LOGE("could not create file table");
- goto fail;
- }
- if (!mDatabase->exec(PATH_INDEX_CREATE)) {
- LOGE("could not path index on file table");
- goto fail;
- }
-
- if (!mFileIdQuery) {
- mFileIdQuery = new SqliteStatement(mDatabase);
- if (!mFileIdQuery->prepare(FILE_ID_QUERY)) {
- LOGE("could not compile FILE_ID_QUERY");
- goto fail;
- }
- }
- if (!mFilePathQuery) {
- mFilePathQuery = new SqliteStatement(mDatabase);
- if (!mFilePathQuery->prepare(FILE_PATH_QUERY)) {
- LOGE("could not compile FILE_PATH_QUERY");
- goto fail;
- }
- }
- if (!mObjectInfoQuery) {
- mObjectInfoQuery = new SqliteStatement(mDatabase);
- if (!mObjectInfoQuery->prepare(GET_OBJECT_INFO_QUERY)) {
- LOGE("could not compile GET_OBJECT_INFO_QUERY");
- goto fail;
- }
- }
- if (!mFileInserter) {
- mFileInserter = new SqliteStatement(mDatabase);
- if (!mFileInserter->prepare(FILE_INSERT)) {
- LOGE("could not compile FILE_INSERT\n");
- goto fail;
- }
- }
- if (!mFileDeleter) {
- mFileDeleter = new SqliteStatement(mDatabase);
- if (!mFileDeleter->prepare(FILE_DELETE)) {
- LOGE("could not compile FILE_DELETE\n");
- goto fail;
- }
- }
-
- return true;
-
-fail:
- delete mDatabase;
- delete mFileIdQuery;
- delete mFilePathQuery;
- delete mObjectInfoQuery;
- delete mFileInserter;
- delete mFileDeleter;
- mDatabase = NULL;
- mFileIdQuery = NULL;
- mFilePathQuery = NULL;
- mObjectInfoQuery = NULL;
- mFileInserter = NULL;
- mFileDeleter = NULL;
- return false;
-}
-
-void MtpSqliteDatabase::close() {
- if (mDatabase) {
- mDatabase->close();
- mDatabase = NULL;
- }
-}
-
-MtpObjectHandle MtpSqliteDatabase::getObjectHandle(const char* path) {
- mFileIdQuery->reset();
- mFileIdQuery->bind(1, path);
- if (mFileIdQuery->step()) {
- int row = mFileIdQuery->getColumnInt(0);
- if (row > 0) {
- MtpObjectFormat format = mFileIdQuery->getColumnInt(1);
- return row;
- }
- }
-
- return 0;
-}
-
-MtpObjectHandle MtpSqliteDatabase::addFile(const char* path,
- MtpObjectFormat format,
- MtpObjectHandle parent,
- MtpStorageID storage,
- uint64_t size,
- time_t modified) {
- mFileInserter->bind(FILE_PATH_COLUMN, path);
- mFileInserter->bind(FILE_FORMAT_COLUMN, format);
- mFileInserter->bind(FILE_PARENT_COLUMN, parent);
- mFileInserter->bind(FILE_STORAGE_COLUMN, storage);
- mFileInserter->bind(FILE_SIZE_COLUMN, size);
- mFileInserter->bind(FILE_MODIFIED_COLUMN, modified);
- mFileInserter->step();
- mFileInserter->reset();
- int result = mDatabase->lastInsertedRow();
- return (result <= 0 ? kInvalidObjectHandle : result);
-}
-
-MtpObjectHandleList* MtpSqliteDatabase::getObjectList(MtpStorageID storageID,
- MtpObjectFormat format,
- MtpObjectHandle parent) {
- bool whereStorage = (storageID != 0xFFFFFFFF);
- bool whereFormat = (format != 0);
- bool whereParent = (parent != 0);
- char intBuffer[20];
-
- MtpString query("SELECT _id,format FROM files");
- if (whereStorage || whereFormat || whereParent)
- query += " WHERE";
- if (whereStorage) {
- snprintf(intBuffer, sizeof(intBuffer), "%d", storageID);
- query += " storage = ";
- query += intBuffer;
- }
- if (whereFormat) {
- snprintf(intBuffer, sizeof(intBuffer), "%d", format);
- if (whereStorage)
- query += " AND";
- query += " format = ";
- query += intBuffer;
- }
- if (whereParent) {
- if (parent != MTP_PARENT_ROOT)
- parent &= kObjectHandleIndexMask;
- snprintf(intBuffer, sizeof(intBuffer), "%d", parent);
- if (whereStorage || whereFormat)
- query += " AND";
- query += " parent = ";
- query += intBuffer;
- }
- query += ";";
-
- SqliteStatement stmt(mDatabase);
- LOGV("%s", (const char *)query);
- stmt.prepare(query);
-
- MtpObjectHandleList* list = new MtpObjectHandleList();
- while (!stmt.isDone()) {
- if (stmt.step()) {
- int index = stmt.getColumnInt(0);
- LOGV("stmt.getColumnInt returned %d", index);
- if (index > 0) {
- MtpObjectFormat format = stmt.getColumnInt(1);
- list->push(index);
- }
- }
- }
- LOGV("list size: %d", list->size());
- return list;
-}
-
-
-MtpResponseCode MtpSqliteDatabase::getObjectProperty(MtpObjectHandle handle,
- MtpObjectProperty property,
- MtpDataPacket& packet) {
- int type;
- const char* columnName;
- char intBuffer[20];
-
- if (handle != MTP_PARENT_ROOT)
- handle &= kObjectHandleIndexMask;
-
- if (!getPropertyInfo(property, type, columnName))
- return MTP_RESPONSE_INVALID_OBJECT_PROP_CODE;
- snprintf(intBuffer, sizeof(intBuffer), "%d", handle);
-
- MtpString query("SELECT ");
- query += columnName;
- query += " FROM files WHERE _id = ";
- query += intBuffer;
- query += ";";
-
- SqliteStatement stmt(mDatabase);
- LOGV("%s", (const char *)query);
- stmt.prepare(query);
-
- if (!stmt.step())
- return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
-
- switch (type) {
- case MTP_TYPE_INT8:
- packet.putInt8(stmt.getColumnInt(0));
- break;
- case MTP_TYPE_UINT8:
- packet.putUInt8(stmt.getColumnInt(0));
- break;
- case MTP_TYPE_INT16:
- packet.putInt16(stmt.getColumnInt(0));
- break;
- case MTP_TYPE_UINT16:
- packet.putUInt16(stmt.getColumnInt(0));
- break;
- case MTP_TYPE_INT32:
- packet.putInt32(stmt.getColumnInt(0));
- break;
- case MTP_TYPE_UINT32:
- packet.putUInt32(stmt.getColumnInt(0));
- break;
- case MTP_TYPE_INT64:
- packet.putInt64(stmt.getColumnInt64(0));
- break;
- case MTP_TYPE_UINT64:
- packet.putUInt64(stmt.getColumnInt64(0));
- break;
- case MTP_TYPE_STR:
- packet.putString(stmt.getColumnString(0));
- break;
- default:
- LOGE("unsupported object type\n");
- return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
- }
- return MTP_RESPONSE_OK;
-}
-
-MtpResponseCode MtpSqliteDatabase::getObjectInfo(MtpObjectHandle handle,
- MtpDataPacket& packet) {
- char date[20];
-
- if (handle != MTP_PARENT_ROOT)
- handle &= kObjectHandleIndexMask;
-
- mObjectInfoQuery->reset();
- mObjectInfoQuery->bind(1, handle);
- if (!mObjectInfoQuery->step())
- return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
-
- MtpStorageID storageID = mObjectInfoQuery->getColumnInt(0);
- MtpObjectFormat format = mObjectInfoQuery->getColumnInt(1);
- MtpObjectHandle parent = mObjectInfoQuery->getColumnInt(2);
- // extract name from path. do we want a separate database entry for this?
- const char* name = mObjectInfoQuery->getColumnString(3);
- const char* lastSlash = strrchr(name, '/');
- if (lastSlash)
- name = lastSlash + 1;
- int64_t size = mObjectInfoQuery->getColumnInt64(4);
- time_t modified = mObjectInfoQuery->getColumnInt(5);
- int associationType = (format == MTP_FORMAT_ASSOCIATION ?
- MTP_ASSOCIATION_TYPE_GENERIC_FOLDER :
- MTP_ASSOCIATION_TYPE_UNDEFINED);
-
- LOGV("storageID: %d, format: %d, parent: %d", storageID, format, parent);
-
- packet.putUInt32(storageID);
- packet.putUInt16(format);
- packet.putUInt16(0); // protection status
- packet.putUInt32((size > 0xFFFFFFFFLL ? 0xFFFFFFFF : size));
- packet.putUInt16(0); // thumb format
- packet.putUInt32(0); // thumb compressed size
- packet.putUInt32(0); // thumb pix width
- packet.putUInt32(0); // thumb pix height
- packet.putUInt32(0); // image pix width
- packet.putUInt32(0); // image pix height
- packet.putUInt32(0); // image bit depth
- packet.putUInt32(parent);
- packet.putUInt16(associationType);
- packet.putUInt32(0); // association desc
- packet.putUInt32(0); // sequence number
- packet.putString(name); // file name
- packet.putEmptyString();
- formatDateTime(modified, date, sizeof(date));
- packet.putString(date); // date modified
- packet.putEmptyString(); // keywords
-
- return MTP_RESPONSE_OK;
-}
-
-bool MtpSqliteDatabase::getObjectFilePath(MtpObjectHandle handle,
- MtpString& filePath,
- int64_t& fileLength) {
- if (handle != MTP_PARENT_ROOT)
- handle &= kObjectHandleIndexMask;
- mFilePathQuery->reset();
- mFilePathQuery->bind(1, handle);
- if (!mFilePathQuery->step())
- return false;
-
- const char* path = mFilePathQuery->getColumnString(0);
- if (!path)
- return false;
- filePath = path;
- fileLength = mFilePathQuery->getColumnInt64(1);
- return true;
-}
-
-bool MtpSqliteDatabase::deleteFile(MtpObjectHandle handle) {
- uint32_t table = handle & kObjectHandleTableMask;
- handle &= kObjectHandleIndexMask;
- mFileDeleter->bind(1, handle);
- mFileDeleter->step();
- mFileDeleter->reset();
-
- return true;
-}
-
-MtpObjectHandle* MtpSqliteDatabase::getFileList(int& outCount) {
- MtpObjectHandle* result = NULL;
- int count = 0;
- SqliteStatement stmt(mDatabase);
- stmt.prepare("SELECT count(*) FROM files;");
-
- if (stmt.step())
- count = stmt.getColumnInt(0);
-
- if (count > 0) {
- result = new MtpObjectHandle[count];
- memset(result, 0, count * sizeof(*result));
- SqliteStatement stmt2(mDatabase);
- stmt2.prepare("SELECT _id,format FROM files;");
-
- for (int i = 0; i < count; i++) {
- if (!stmt2.step()) {
- LOGW("getFileList ended early");
- count = i;
- break;
- }
- MtpObjectHandle handle = stmt2.getColumnInt(0);
- MtpObjectFormat format = stmt2.getColumnInt(1);
- result[i] = handle;
- }
- }
- outCount = count;
- return result;
-}
-
-void MtpSqliteDatabase::beginTransaction() {
- mDatabase->beginTransaction();
-}
-
-void MtpSqliteDatabase::commitTransaction() {
- mDatabase->commitTransaction();
-}
-
-void MtpSqliteDatabase::rollbackTransaction() {
- mDatabase->rollbackTransaction();
-}
-
-} // namespace android
diff --git a/media/mtp/MtpSqliteDatabase.h b/media/mtp/MtpSqliteDatabase.h
deleted file mode 100644
index 14ed281a5d02..000000000000
--- a/media/mtp/MtpSqliteDatabase.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#ifndef _MTP_SQLITE_DATABASE_H
-#define _MTP_SQLITE_DATABASE_H
-
-#include "MtpTypes.h"
-#include "MtpDatabase.h"
-
-class SqliteDatabase;
-
-namespace android {
-
-class MtpDataPacket;
-class SqliteStatement;
-
-class MtpSqliteDatabase : public MtpDatabase {
-private:
- SqliteDatabase* mDatabase;
- SqliteStatement* mFileIdQuery;
- SqliteStatement* mFilePathQuery;
- SqliteStatement* mObjectInfoQuery;
- SqliteStatement* mFileInserter;
- SqliteStatement* mFileDeleter;
-
-public:
- MtpSqliteDatabase();
- virtual ~MtpSqliteDatabase();
-
- bool open(const char* path, bool create);
- void close();
-
- virtual MtpObjectHandle getObjectHandle(const char* path);
- virtual MtpObjectHandle addFile(const char* path,
- MtpObjectFormat format,
- MtpObjectHandle parent,
- MtpStorageID storage,
- uint64_t size,
- time_t modified);
-
- virtual MtpObjectHandleList* getObjectList(MtpStorageID storageID,
- MtpObjectFormat format,
- MtpObjectHandle parent);
-
- virtual MtpResponseCode getObjectProperty(MtpObjectHandle handle,
- MtpObjectProperty property,
- MtpDataPacket& packet);
-
- virtual MtpResponseCode getObjectInfo(MtpObjectHandle handle,
- MtpDataPacket& packet);
-
- virtual bool getObjectFilePath(MtpObjectHandle handle,
- MtpString& filePath,
- int64_t& fileLength);
- virtual bool deleteFile(MtpObjectHandle handle);
-
- // helper for media scanner
- virtual MtpObjectHandle* getFileList(int& outCount);
-
- virtual void beginTransaction();
- virtual void commitTransaction();
- virtual void rollbackTransaction();
-};
-
-}; // namespace android
-
-#endif // _MTP_SQLITE_DATABASE_H
diff --git a/media/mtp/MtpStorage.cpp b/media/mtp/MtpStorage.cpp
index 7e89a906ceb2..eccf186e0b91 100644
--- a/media/mtp/MtpStorage.cpp
+++ b/media/mtp/MtpStorage.cpp
@@ -19,7 +19,6 @@
#include "MtpDebug.h"
#include "MtpDatabase.h"
#include "MtpStorage.h"
-#include "MtpMediaScanner.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -78,9 +77,4 @@ const char* MtpStorage::getDescription() const {
return "Device Storage";
}
-bool MtpStorage::scanFiles() {
- MtpMediaScanner scanner(mStorageID, mFilePath, mDatabase);
- return scanner.scanFiles();
-}
-
} // namespace android
diff --git a/media/mtp/MtpStorage.h b/media/mtp/MtpStorage.h
index 6097272851d8..b13b9263713c 100644
--- a/media/mtp/MtpStorage.h
+++ b/media/mtp/MtpStorage.h
@@ -22,7 +22,6 @@
namespace android {
class MtpDatabase;
-class SqliteStatement;
class MtpStorage {
@@ -44,8 +43,6 @@ public:
uint64_t getFreeSpace();
const char* getDescription() const;
inline const char* getPath() const { return mFilePath; }
-
- bool scanFiles();
};
}; // namespace android
diff --git a/media/mtp/MtpTypes.h b/media/mtp/MtpTypes.h
index 33cd369aaf25..ec0f86780ca9 100644
--- a/media/mtp/MtpTypes.h
+++ b/media/mtp/MtpTypes.h
@@ -60,11 +60,6 @@ union MtpPropertyValue {
#define MTP_PARENT_ROOT 0xFFFFFFFF // parent is root of the storage
#define kInvalidObjectHandle 0xFFFFFFFF
-// MtpObjectHandle bits and masks
-#define kObjectHandleMarkBit 0x80000000 // used for mark & sweep by MtpMediaScanner
-#define kObjectHandleTableMask 0x70000000 // mask for object table
-#define kObjectHandleIndexMask 0x0FFFFFFF // mask for object index in file table
-
class MtpStorage;
class MtpDevice;
class MtpProperty;
diff --git a/media/mtp/SqliteDatabase.cpp b/media/mtp/SqliteDatabase.cpp
deleted file mode 100644
index 1de3a4118992..000000000000
--- a/media/mtp/SqliteDatabase.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "SqliteDatabase"
-
-#include "MtpDebug.h"
-#include "SqliteDatabase.h"
-#include "SqliteStatement.h"
-
-#include <stdio.h>
-#include <sqlite3.h>
-
-namespace android {
-
-SqliteDatabase::SqliteDatabase()
- : mDatabaseHandle(NULL)
-{
-}
-
-SqliteDatabase::~SqliteDatabase() {
- close();
-}
-
-bool SqliteDatabase::open(const char* path, bool create) {
- int flags = SQLITE_OPEN_READWRITE;
- if (create) flags |= SQLITE_OPEN_CREATE;
- // SQLITE_OPEN_NOMUTEX?
- int ret = sqlite3_open_v2(path, &mDatabaseHandle, flags, NULL);
- if (ret) {
- LOGE("could not open database\n");
- return false;
- }
- return true;
-}
-
-void SqliteDatabase::close() {
- if (mDatabaseHandle) {
- sqlite3_close(mDatabaseHandle);
- mDatabaseHandle = NULL;
- }
-}
-
-bool SqliteDatabase::exec(const char* sql) {
- return (sqlite3_exec(mDatabaseHandle, sql, NULL, NULL, NULL) == 0);
-}
-
-int SqliteDatabase::lastInsertedRow() {
- return sqlite3_last_insert_rowid(mDatabaseHandle);
-}
-
-void SqliteDatabase::beginTransaction() {
- exec("BEGIN TRANSACTION");
-}
-
-void SqliteDatabase::commitTransaction() {
- exec("COMMIT TRANSACTION");
-}
-
-void SqliteDatabase::rollbackTransaction() {
- exec("ROLLBACK TRANSACTION");
-}
-
-int SqliteDatabase::getVersion() {
- SqliteStatement stmt(this);
- stmt.prepare("PRAGMA user_version;");
- stmt.step();
- return stmt.getColumnInt(0);
-}
-void SqliteDatabase::setVersion(int version) {
- char buffer[40];
- snprintf(buffer, sizeof(buffer), "PRAGMA user_version = %d", version);
- exec(buffer);
-}
-
-} // namespace android
diff --git a/media/mtp/SqliteDatabase.h b/media/mtp/SqliteDatabase.h
deleted file mode 100644
index 7d008f9104a9..000000000000
--- a/media/mtp/SqliteDatabase.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#ifndef _SQLITE_DATABASE_H
-#define _SQLITE_DATABASE_H
-
-typedef struct sqlite3 sqlite3;
-
-namespace android {
-
-class SqliteDatabase {
-private:
- sqlite3* mDatabaseHandle;
-
-public:
- SqliteDatabase();
- virtual ~SqliteDatabase();
-
- bool open(const char* path, bool create);
- void close();
-
- bool exec(const char* sql);
- int lastInsertedRow();
-
- void beginTransaction();
- void commitTransaction();
- void rollbackTransaction();
-
- int getVersion();
- void setVersion(int version);
-
- inline sqlite3* getDatabaseHandle() const { return mDatabaseHandle; }
-};
-
-}; // namespace android
-
-#endif // _SQLITE_DATABASE_H
diff --git a/media/mtp/SqliteStatement.cpp b/media/mtp/SqliteStatement.cpp
deleted file mode 100644
index adef7aed41ef..000000000000
--- a/media/mtp/SqliteStatement.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "SqliteStatement"
-
-#include "SqliteStatement.h"
-#include "SqliteDatabase.h"
-
-#include <stdio.h>
-#include <sqlite3.h>
-
-namespace android {
-
-SqliteStatement::SqliteStatement(SqliteDatabase* db)
- : mDatabaseHandle(db->getDatabaseHandle()),
- mStatement(NULL),
- mDone(false)
-{
-}
-
-SqliteStatement::~SqliteStatement() {
- finalize();
-}
-
-bool SqliteStatement::prepare(const char* sql) {
- return (sqlite3_prepare_v2(mDatabaseHandle, sql, -1, &mStatement, NULL) == 0);
-}
-
-bool SqliteStatement::step() {
- int ret = sqlite3_step(mStatement);
- if (ret == SQLITE_DONE) {
- mDone = true;
- return true;
- }
- return (ret == SQLITE_OK || ret == SQLITE_ROW);
-}
-
-void SqliteStatement::reset() {
- sqlite3_reset(mStatement);
- mDone = false;
-}
-
-void SqliteStatement::finalize() {
- if (mStatement) {
- sqlite3_finalize(mStatement);
- mStatement = NULL;
- }
-}
-
-void SqliteStatement::bind(int column, int value) {
- sqlite3_bind_int(mStatement, column, value);
-}
-
-void SqliteStatement::bind(int column, const char* value) {
- sqlite3_bind_text(mStatement, column, value, -1, SQLITE_TRANSIENT);
-}
-
-int SqliteStatement::getColumnInt(int column) {
- return sqlite3_column_int(mStatement, column);
-}
-
-int64_t SqliteStatement::getColumnInt64(int column) {
- return sqlite3_column_int64(mStatement, column);
-}
-
-const char* SqliteStatement::getColumnString(int column) {
- return (const char *)sqlite3_column_text(mStatement, column);
-}
-
-} // namespace android
diff --git a/media/mtp/SqliteStatement.h b/media/mtp/SqliteStatement.h
deleted file mode 100644
index c0ebfff2ec4d..000000000000
--- a/media/mtp/SqliteStatement.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#ifndef _SQLITE_STATEMENT_H
-#define _SQLITE_STATEMENT_H
-
-#include <stdint.h>
-
-typedef struct sqlite3 sqlite3;
-typedef struct sqlite3_stmt sqlite3_stmt;
-
-namespace android {
-
-class SqliteDatabase;
-
-class SqliteStatement {
-private:
- sqlite3* mDatabaseHandle;
- sqlite3_stmt* mStatement;
- bool mDone;
-
-public:
- SqliteStatement(SqliteDatabase* db);
- virtual ~SqliteStatement();
-
- bool prepare(const char* sql);
- bool step();
- void reset();
- void finalize();
-
- void bind(int column, int value);
- void bind(int column, const char* value);
-
- int getColumnInt(int column);
- int64_t getColumnInt64(int column);
- const char* getColumnString(int column);
-
- inline bool isDone() const { return mDone; }
-};
-
-}; // namespace android
-
-#endif // _SQLITE_STATEMENT_H
diff --git a/media/mtp/mtptest.cpp b/media/mtp/mtptest.cpp
deleted file mode 100644
index a2cb8263040f..000000000000
--- a/media/mtp/mtptest.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "mtp_usb"
-
-#include "MtpDebug.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-
-#include "MtpServer.h"
-#include "MtpSqliteDatabase.h"
-#include "MtpStorage.h"
-#include "f_mtp.h"
-#include "private/android_filesystem_config.h"
-
-using namespace android;
-
-static bool enable_usb_function(const char* name, bool enable) {
- char path[PATH_MAX];
-
- snprintf(path, sizeof(path), "/sys/class/usb_composite/%s/enable", name);
- int fd = open(path, O_RDWR);
- if (fd < 0) {
- fprintf(stderr, "could not open %s in enable_usb_function\n", path);
- return false;
- }
- write(fd, enable ? "1" : "0", 2);
- close(fd);
- return true;
-}
-
-int main(int argc, char* argv[]) {
- bool usePTP = false;
- const char* storagePath = "/sdcard";
-
- for (int i = 1; i < argc; i++) {
- const char* arg = argv[i];
- if (!strcmp(arg, "-p"))
- usePTP = true;
- else if (arg[0] == '/')
- storagePath = arg;
- }
-
- int fd = open("/dev/mtp_usb", O_RDWR);
- printf("open returned %d\n", fd);
- if (fd < 0) {
- fprintf(stderr, "could not open MTP driver\n");
- return -1;
- }
-
- if (usePTP) {
- // set driver mode to PTP
- int ret = ioctl(fd, MTP_SET_INTERFACE_MODE, MTP_INTERFACE_MODE_PTP);
- if (ret) {
- fprintf(stderr, "MTP_SET_INTERFACE_MODE failed\n");
- return -1;
- }
- }
-
- // disable UMS and enable MTP USB functions
- enable_usb_function("usb_mass_storage", false);
- enable_usb_function("mtp", true);
-
- MtpSqliteDatabase* database = new MtpSqliteDatabase();
- database->open("/data/data/mtp/mtp.db", true);
- MtpServer server(fd, database, AID_SDCARD_RW, 0664, 0775);
- server.addStorage(storagePath);
- server.scanStorage();
- server.run();
-
- close(fd);
- return 0;
-}
-
diff --git a/media/mtp/scantest.cpp b/media/mtp/scantest.cpp
deleted file mode 100644
index 3702a5d06e6a..000000000000
--- a/media/mtp/scantest.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-
-#include "MtpSqliteDatabase.h"
-#include "MtpMediaScanner.h"
-
-using namespace android;
-
-int main(int argc, char* argv[]) {
- if (argc != 2) {
- fprintf(stderr, "usage: %s <storage path>\n", argv[0]);
- return -1;
- }
-
- MtpSqliteDatabase* database = new MtpSqliteDatabase();
- database->open("scantest.db", true);
-
- MtpMediaScanner scanner(1, argv[1], database);
- scanner.scanFiles();
- database->close();
-
- return 0;
-}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java
index 0883387fc5fd..4475e925fd0c 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java
@@ -77,7 +77,9 @@ public class FsUtils {
continue;
}
- if ((s.toLowerCase().endsWith(".html") || s.toLowerCase().endsWith(".xml"))
+ if ((s.toLowerCase().endsWith(".html")
+ || s.toLowerCase().endsWith(".xml")
+ || s.toLowerCase().endsWith(".xhtml"))
&& !s.endsWith("TEMPLATE.html")) {
Log.v(LOGTAG, "Recording " + s);
bos.write(s.getBytes());
diff --git a/tests/DumpRenderTree2/Android.mk b/tests/DumpRenderTree2/Android.mk
index f3d2e9c8712a..2aa6799e1552 100644
--- a/tests/DumpRenderTree2/Android.mk
+++ b/tests/DumpRenderTree2/Android.mk
@@ -5,6 +5,6 @@ LOCAL_MODULE_TAGS := tests
LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_MODULE := DumpRenderTree2
+LOCAL_PACKAGE_NAME := DumpRenderTree2
-include $(BUILD_JAVA_LIBRARY)
+include $(BUILD_PACKAGE) \ No newline at end of file
diff --git a/tests/DumpRenderTree2/AndroidManifest.xml b/tests/DumpRenderTree2/AndroidManifest.xml
new file mode 100644
index 000000000000..baa365c97647
--- /dev/null
+++ b/tests/DumpRenderTree2/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2010 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.dumprendertree2">
+ <application>
+ <activity android:name=".ui.DirListActivity"
+ android:label="Dump Render Tree 2"
+ android:configChanges="orientation">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest> \ No newline at end of file
diff --git a/tests/DumpRenderTree2/res/drawable/folder.png b/tests/DumpRenderTree2/res/drawable/folder.png
new file mode 100644
index 000000000000..5b3fcecb3e79
--- /dev/null
+++ b/tests/DumpRenderTree2/res/drawable/folder.png
Binary files differ
diff --git a/tests/DumpRenderTree2/res/drawable/runtest.png b/tests/DumpRenderTree2/res/drawable/runtest.png
new file mode 100644
index 000000000000..910c654d3735
--- /dev/null
+++ b/tests/DumpRenderTree2/res/drawable/runtest.png
Binary files differ
diff --git a/tests/DumpRenderTree2/res/layout/dirlist_row.xml b/tests/DumpRenderTree2/res/layout/dirlist_row.xml
new file mode 100644
index 000000000000..e5578a6c2691
--- /dev/null
+++ b/tests/DumpRenderTree2/res/layout/dirlist_row.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2010 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="horizontal"
+ android:gravity="center_vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+ <ImageView
+ android:id="@+id/icon"
+ android:layout_width="80px"
+ android:adjustViewBounds="true"
+ android:paddingLeft="15px"
+ android:paddingRight="15px"
+ android:paddingTop="15px"
+ android:paddingBottom="15px"
+ android:layout_height="wrap_content"
+ />
+
+ <TextView
+ android:id="@+id/label"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="60px"
+ android:gravity="center_vertical"
+ android:textSize="14sp"
+ />
+
+</LinearLayout> \ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/FileFilter.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/FileFilter.java
index 98801d35da39..64ef8a4ad49f 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/FileFilter.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/FileFilter.java
@@ -227,13 +227,14 @@ public class FileFilter {
}
/**
- * Checks if the file is a test or something else.
+ * Checks if the file is a test.
+ * Currently we run .html and .xhtml tests.
*
* @param testName
* @return
* if the file is a test
*/
public static boolean isTestFile(String testName) {
- return testName.endsWith(".html");
+ return testName.endsWith(".html") || testName.endsWith(".xhtml");
}
-} \ No newline at end of file
+}
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/ui/DirListActivity.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/ui/DirListActivity.java
new file mode 100644
index 000000000000..97a81ce6e08a
--- /dev/null
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/ui/DirListActivity.java
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2010 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.dumprendertree2.ui;
+
+import com.android.dumprendertree2.FileFilter;
+import com.android.dumprendertree2.R;
+
+import android.app.Activity;
+import android.app.ListActivity;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.Environment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * An Activity that allows navigating through tests folders and choosing folders or tests to run.
+ */
+public class DirListActivity extends ListActivity {
+
+ private static final String LOG_TAG = "DirListActivity";
+ private static final String ROOT_DIR_PATH =
+ Environment.getExternalStorageDirectory() +
+ File.separator + "android" +
+ File.separator + "LayoutTests";
+
+ /** TODO: This is just a guess - think of a better way to achieve it */
+ private static final int MEAN_TITLE_CHAR_SIZE = 12;
+
+ private ListView mListView;
+
+ /** This is a relative path! */
+ private String mCurrentDirPath;
+
+ /**
+ * TODO: This should not be a constant, but rather be configurable from somewhere.
+ */
+ private String mRootDirPath = ROOT_DIR_PATH;
+
+ /**
+ * Very simple object to use inside ListView as an item.
+ */
+ private static class ListItem implements Comparable<ListItem> {
+ private String mRelativePath;
+ private String mName;
+ private boolean mIsDirectory;
+
+ public ListItem(String relativePath, boolean isDirectory) {
+ mRelativePath = relativePath;
+ mName = new File(relativePath).getName();
+ mIsDirectory = isDirectory;
+ }
+
+ public boolean isDirectory() {
+ return mIsDirectory;
+ }
+
+ public String getRelativePath() {
+ return mRelativePath;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ @Override
+ public int compareTo(ListItem another) {
+ return mRelativePath.compareTo(another.getRelativePath());
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof ListItem)) {
+ return false;
+ }
+
+ return mRelativePath.equals(((ListItem) o).getRelativePath());
+ }
+
+ @Override
+ public int hashCode() {
+ return mRelativePath.hashCode();
+ }
+
+ }
+
+ /**
+ * A custom adapter that sets the proper icon and label in the list view.
+ */
+ private static class DirListAdapter extends ArrayAdapter<ListItem> {
+ private Activity mContext;
+ private ListItem[] mItems;
+
+ public DirListAdapter(Activity context, ListItem[] items) {
+ super(context, R.layout.dirlist_row, items);
+
+ mContext = context;
+ mItems = items;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ LayoutInflater inflater = mContext.getLayoutInflater();
+ View row = inflater.inflate(R.layout.dirlist_row, null);
+
+ TextView label = (TextView) row.findViewById(R.id.label);
+ label.setText(mItems[position].getName());
+
+ ImageView icon = (ImageView) row.findViewById(R.id.icon);
+ if (mItems[position].isDirectory()) {
+ icon.setImageResource(R.drawable.folder);
+ } else {
+ icon.setImageResource(R.drawable.runtest);
+ }
+
+ return row;
+ }
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mListView = getListView();
+
+ mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
+ ListItem item = (ListItem) adapterView.getItemAtPosition(position);
+
+ if (item.isDirectory()) {
+ showDir(item.getRelativePath());
+ } else {
+ /** TODO: run the test */
+ }
+ }
+ });
+
+ /** All the paths are relative to test root dir where possible */
+ showDir("");
+ }
+
+ @Override
+ /**
+ * Moves to the parent directory if one exists. Does not allow to move above
+ * the test 'root' directory.
+ */
+ public void onBackPressed() {
+ File currentDirParent = new File(mCurrentDirPath).getParentFile();
+ if (currentDirParent != null) {
+ showDir(currentDirParent.getPath());
+ } else {
+ showDir("");
+ }
+ }
+
+ /**
+ * Prevents the activity from recreating on change of orientation. The title needs to
+ * be recalculated.
+ */
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+
+ setTitle(shortenTitle(mCurrentDirPath));
+ }
+
+ /**
+ * Loads the contents of dir into the list view.
+ *
+ * @param dirPath
+ * directory to load into list view
+ */
+ private void showDir(String dirPath) {
+ mCurrentDirPath = dirPath;
+ setTitle(shortenTitle(dirPath));
+ setListAdapter(new DirListAdapter(this, getDirList(dirPath)));
+ }
+
+ /**
+ * TODO: find a neat way to determine number of characters that fit in the title
+ * bar.
+ * */
+ private String shortenTitle(String title) {
+ if (title.equals("")) {
+ return "Tests' root dir:";
+ }
+ int charCount = mListView.getWidth() / MEAN_TITLE_CHAR_SIZE;
+
+ if (title.length() > charCount) {
+ return "..." + title.substring(title.length() - charCount);
+ } else {
+ return title;
+ }
+ }
+
+ /**
+ * Return the array with contents of the given directory.
+ * First it contains the subfolders, then the files. Both sorted
+ * alphabetically.
+ */
+ private ListItem[] getDirList(String dirPath) {
+ File dir = new File(mRootDirPath, dirPath);
+
+ List<ListItem> subDirs = new ArrayList<ListItem>();
+ List<ListItem> subFiles = new ArrayList<ListItem>();
+
+ for (File item : dir.listFiles()) {
+ if (item.isDirectory() && FileFilter.isTestDir(item.getName())) {
+ subDirs.add(new ListItem(getRelativePath(item), true));
+ } else if (FileFilter.isTestFile(item.getName())) {
+ subFiles.add(new ListItem(getRelativePath(item), false));
+ }
+ }
+
+ Collections.sort(subDirs);
+ Collections.sort(subFiles);
+
+ /** Concatenate the two lists */
+ subDirs.addAll(subFiles);
+
+ return subDirs.toArray(new ListItem[subDirs.size()]);
+ }
+
+ private String getRelativePath(File file) {
+ File rootDir = new File(mRootDirPath);
+ return file.getAbsolutePath().replaceFirst(rootDir.getPath() + File.separator, "");
+ }
+} \ No newline at end of file