1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/*
2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Copyright (C) 2010 The Android Open Source Project
3f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
4f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Licensed under the Apache License, Version 2.0 (the "License");
5f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * you may not use this file except in compliance with the License.
6f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * You may obtain a copy of the License at
7f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
8f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *      http://www.apache.org/licenses/LICENSE-2.0
9f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
10f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Unless required by applicable law or agreed to in writing, software
11f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * distributed under the License is distributed on an "AS IS" BASIS,
12f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * See the License for the specific language governing permissions and
14f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * limitations under the License.
15f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */
16f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
17f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpackage com.android.gallery3d.data;
18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
19f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.R;
20f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.app.GalleryApp;
21f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.common.BitmapUtils;
22f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.util.UpdateHelper;
23f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.util.GalleryUtils;
24f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.util.ThreadPool.Job;
25f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.util.ThreadPool.JobContext;
26f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
27f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.ContentResolver;
28f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.database.Cursor;
29f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.graphics.Bitmap;
30f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.graphics.BitmapFactory;
31f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.graphics.BitmapRegionDecoder;
32f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.graphics.Canvas;
33f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.graphics.Paint;
34f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.net.Uri;
35f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.provider.MediaStore.Video;
36f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.provider.MediaStore.Video.VideoColumns;
37f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.io.File;
39f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// LocalVideo represents a video in the local storage.
41f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpublic class LocalVideo extends LocalMediaItem {
42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    static final Path ITEM_PATH = Path.fromString("/local/video/item");
44f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    // Must preserve order between these indices and the order of the terms in
46f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    // the following PROJECTION array.
47f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int INDEX_ID = 0;
48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int INDEX_CAPTION = 1;
49f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int INDEX_MIME_TYPE = 2;
50f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int INDEX_LATITUDE = 3;
51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int INDEX_LONGITUDE = 4;
52f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int INDEX_DATE_TAKEN = 5;
53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int INDEX_DATE_ADDED = 6;
54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int INDEX_DATE_MODIFIED = 7;
55f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int INDEX_DATA = 8;
56f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int INDEX_DURATION = 9;
57f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int INDEX_BUCKET_ID = 10;
58f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int INDEX_SIZE_ID = 11;
59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    static final String[] PROJECTION = new String[] {
61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            VideoColumns._ID,
62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            VideoColumns.TITLE,
63f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            VideoColumns.MIME_TYPE,
64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            VideoColumns.LATITUDE,
65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            VideoColumns.LONGITUDE,
66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            VideoColumns.DATE_TAKEN,
67f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            VideoColumns.DATE_ADDED,
68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            VideoColumns.DATE_MODIFIED,
69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            VideoColumns.DATA,
70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            VideoColumns.DURATION,
71f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            VideoColumns.BUCKET_ID,
72f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            VideoColumns.SIZE
73f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    };
74f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private final GalleryApp mApplication;
76f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static Bitmap sOverlay;
77f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
78f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public int durationInSec;
79f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
80f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public LocalVideo(Path path, GalleryApp application, Cursor cursor) {
81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        super(path, nextVersionNumber());
82f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mApplication = application;
83f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        loadFromCursor(cursor);
84f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
85f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
86f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public LocalVideo(Path path, GalleryApp context, int id) {
87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        super(path, nextVersionNumber());
88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mApplication = context;
89f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        ContentResolver resolver = mApplication.getContentResolver();
90f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Uri uri = Video.Media.EXTERNAL_CONTENT_URI;
91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Cursor cursor = LocalAlbum.getItemCursor(resolver, uri, PROJECTION, id);
92f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (cursor == null) {
93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            throw new RuntimeException("cannot get cursor for: " + path);
94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        try {
96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (cursor.moveToNext()) {
97f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                loadFromCursor(cursor);
98f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            } else {
99f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                throw new RuntimeException("cannot find data for: " + path);
100f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
101f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } finally {
102f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            cursor.close();
103f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
104f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
105f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
106f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private void loadFromCursor(Cursor cursor) {
107f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        id = cursor.getInt(INDEX_ID);
108f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        caption = cursor.getString(INDEX_CAPTION);
109f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mimeType = cursor.getString(INDEX_MIME_TYPE);
110f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        latitude = cursor.getDouble(INDEX_LATITUDE);
111f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        longitude = cursor.getDouble(INDEX_LONGITUDE);
112f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        dateTakenInMs = cursor.getLong(INDEX_DATE_TAKEN);
113f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        filePath = cursor.getString(INDEX_DATA);
114f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        durationInSec = cursor.getInt(INDEX_DURATION) / 1000;
115f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        bucketId = cursor.getInt(INDEX_BUCKET_ID);
116f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        fileSize = cursor.getLong(INDEX_SIZE_ID);
117f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
118f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
119f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
120f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    protected boolean updateFromCursor(Cursor cursor) {
121f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        UpdateHelper uh = new UpdateHelper();
122f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        id = uh.update(id, cursor.getInt(INDEX_ID));
123f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        caption = uh.update(caption, cursor.getString(INDEX_CAPTION));
124f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mimeType = uh.update(mimeType, cursor.getString(INDEX_MIME_TYPE));
125f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        latitude = uh.update(latitude, cursor.getDouble(INDEX_LATITUDE));
126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        longitude = uh.update(longitude, cursor.getDouble(INDEX_LONGITUDE));
127f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        dateTakenInMs = uh.update(
128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                dateTakenInMs, cursor.getLong(INDEX_DATE_TAKEN));
129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        dateAddedInSec = uh.update(
130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                dateAddedInSec, cursor.getLong(INDEX_DATE_ADDED));
131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        dateModifiedInSec = uh.update(
132f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                dateModifiedInSec, cursor.getLong(INDEX_DATE_MODIFIED));
133f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        filePath = uh.update(filePath, cursor.getString(INDEX_DATA));
134f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        durationInSec = uh.update(
135f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                durationInSec, cursor.getInt(INDEX_DURATION) / 1000);
136f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        bucketId = uh.update(bucketId, cursor.getInt(INDEX_BUCKET_ID));
137f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        fileSize = uh.update(fileSize, cursor.getLong(INDEX_SIZE_ID));
138f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return uh.isUpdated();
139f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
140f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
141f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
142f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public Job<Bitmap> requestImage(int type) {
143f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return new LocalVideoRequest(mApplication, getPath(), type, filePath);
144f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
145f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
146f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public static class LocalVideoRequest extends ImageCacheRequest {
147f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        private String mLocalFilePath;
148f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
149f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        LocalVideoRequest(GalleryApp application, Path path, int type,
150f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                String localFilePath) {
151f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            super(application, path, type, LocalImage.getTargetSize(type));
152f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mLocalFilePath = localFilePath;
153f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
154f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
155f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
156f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public Bitmap onDecodeOriginal(JobContext jc, int type) {
157f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            Bitmap bitmap = BitmapUtils.createVideoThumbnail(mLocalFilePath);
158f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (bitmap == null || jc.isCancelled()) return null;
159f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            return bitmap;
160f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
161f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
162f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
163f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
164f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public Job<BitmapRegionDecoder> requestLargeImage() {
165f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        throw new UnsupportedOperationException("Cannot regquest a large image"
166f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                + " to a local video!");
167f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
168f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
169f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
170f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public int getSupportedOperations() {
171f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return SUPPORT_DELETE | SUPPORT_SHARE | SUPPORT_PLAY | SUPPORT_INFO;
172f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
173f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
174f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
175f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void delete() {
176f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        GalleryUtils.assertNotInRenderThread();
177f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Uri baseUri = Video.Media.EXTERNAL_CONTENT_URI;
178f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mApplication.getContentResolver().delete(baseUri, "_id=?",
179f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                new String[]{String.valueOf(id)});
180f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
181f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
182f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
183f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void rotate(int degrees) {
184f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        // TODO
185f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
186f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
187f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
188f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public Uri getContentUri() {
189f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Uri baseUri = Video.Media.EXTERNAL_CONTENT_URI;
190f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return baseUri.buildUpon().appendPath(String.valueOf(id)).build();
191f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
192f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
193f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
194f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public Uri getPlayUri() {
19525a329cfd7e055dd7c8ce69532aefe9a69ee4d75Chih-Chung Chang        return getContentUri();
196f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
197f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
198f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
199f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public int getMediaType() {
200f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return MEDIA_TYPE_VIDEO;
201f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
202f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
203f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
204f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public MediaDetails getDetails() {
205f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        MediaDetails details = super.getDetails();
206f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        int s = durationInSec;
207f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (s > 0) {
208f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            details.addDetail(MediaDetails.INDEX_DURATION, GalleryUtils.formatDuration(
209f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    mApplication.getAndroidContext(), durationInSec));
210f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
211f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return details;
212f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
213bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang
214bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang    @Override
215bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang    public int getWidth() {
216bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang        return 0;
217bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang    }
218bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang
219bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang    @Override
220bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang    public int getHeight() {
221bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang        return 0;
222bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang    }
223f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin}
224