Merge "Log null returns from Camera.getParameters" into lmp-dev
diff --git a/camera2/Android.mk b/camera2/Android.mk
index 9ac4a8a..3719578 100644
--- a/camera2/Android.mk
+++ b/camera2/Android.mk
@@ -12,4 +12,5 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+# Build all subprojects
include $(call all-subdir-makefiles)
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2AgentImpl.java b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2AgentImpl.java
index e675796..62cb700 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2AgentImpl.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2AgentImpl.java
@@ -35,6 +35,7 @@
import android.hardware.camera2.params.MeteringRectangle;
import android.media.Image;
import android.media.ImageReader;
+import android.media.MediaActionSound;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
@@ -63,6 +64,7 @@
private final CameraStateHolder mCameraState;
private final DispatchThread mDispatchThread;
private final CameraManager mCameraManager;
+ private final MediaActionSound mNoisemaker;
/**
* Number of camera devices. The length of {@code mCameraDevices} does not reveal this
@@ -88,6 +90,8 @@
mDispatchThread = new DispatchThread(mCameraHandler, mCameraHandlerThread);
mDispatchThread.start();
mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
+ mNoisemaker = new MediaActionSound();
+ mNoisemaker.load(MediaActionSound.SHUTTER_CLICK);
mNumCameraDevices = 0;
mCameraDevices = new ArrayList<String>();
@@ -156,7 +160,7 @@
}
private static abstract class CaptureAvailableListener
- extends CameraCaptureSession.CaptureListener
+ extends CameraCaptureSession.CaptureCallback
implements ImageReader.OnImageAvailableListener {};
private class Camera2Handler extends HistoryHandler {
@@ -194,6 +198,9 @@
// Available whenever setAutoFocusMoveCallback() was last invoked with a non-null argument:
private CameraAFMoveCallback mPassiveAfCallback;
+ // Gets reset on every state change
+ private int mCurrentAeState = CaptureResult.CONTROL_AE_STATE_INACTIVE;
+
Camera2Handler(Looper looper) {
super(looper);
}
@@ -208,7 +215,7 @@
CameraOpenCallback openCallback = (CameraOpenCallback) msg.obj;
int cameraIndex = msg.arg1;
- if (mCameraState.getState() != AndroidCamera2StateHolder.CAMERA_UNOPENED) {
+ if (mCameraState.getState() > AndroidCamera2StateHolder.CAMERA_UNOPENED) {
openCallback.onDeviceOpenedAlready(cameraIndex,
generateHistoryString(cameraIndex));
break;
@@ -224,7 +231,7 @@
mOpenCallback.onCameraDisabled(msg.arg1);
break;
}
- mCameraManager.openCamera(mCameraId, mCameraDeviceStateListener, this);
+ mCameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, this);
break;
}
@@ -259,7 +266,7 @@
mPhotoSize = null;
mCameraIndex = 0;
mCameraId = null;
- mCameraState.setState(AndroidCamera2StateHolder.CAMERA_UNOPENED);
+ changeState(AndroidCamera2StateHolder.CAMERA_UNOPENED);
break;
}
@@ -285,19 +292,23 @@
}
mOneshotPreviewingCallback = (CameraStartPreviewCallback) msg.obj;
- mCameraState.setState(AndroidCamera2StateHolder.CAMERA_PREVIEW_ACTIVE);
+ changeState(AndroidCamera2StateHolder.CAMERA_PREVIEW_ACTIVE);
try {
mSession.setRepeatingRequest(
mPersistentSettings.createRequest(mCamera,
CameraDevice.TEMPLATE_PREVIEW, mPreviewSurface),
- /*listener*/mCameraFocusStateListener, /*handler*/this);
+ /*listener*/mCameraResultStateCallback, /*handler*/this);
} catch(CameraAccessException ex) {
Log.w(TAG, "Unable to start preview", ex);
- mCameraState.setState(AndroidCamera2StateHolder.CAMERA_PREVIEW_READY);
+ changeState(AndroidCamera2StateHolder.CAMERA_PREVIEW_READY);
}
break;
}
+ // FIXME: We need to tear down the CameraCaptureSession here
+ // (and unlock the CameraSettings object from our
+ // CameraProxy) so that the preview/photo sizes can be
+ // changed again while no preview is running.
case CameraActions.STOP_PREVIEW: {
if (mCameraState.getState() <
AndroidCamera2StateHolder.CAMERA_PREVIEW_ACTIVE) {
@@ -306,7 +317,7 @@
}
mSession.stopRepeating();
- mCameraState.setState(AndroidCamera2StateHolder.CAMERA_PREVIEW_READY);
+ changeState(AndroidCamera2StateHolder.CAMERA_PREVIEW_READY);
break;
}
@@ -364,19 +375,39 @@
}
// The earliest we can reliably tell whether the autofocus has locked in
- // response to our latest request is when our one-time capture completes.
+ // response to our latest request is when our one-time capture progresses.
// However, it will probably take longer than that, so once that happens,
// just start checking the repeating preview requests as they complete.
final CameraAFCallback callback = (CameraAFCallback) msg.obj;
- CameraCaptureSession.CaptureListener deferredCallbackSetter =
- new CameraCaptureSession.CaptureListener() {
+ CameraCaptureSession.CaptureCallback deferredCallbackSetter =
+ new CameraCaptureSession.CaptureCallback() {
+ private boolean mAlreadyDispatched = false;
+
+ @Override
+ public void onCaptureProgressed(CameraCaptureSession session,
+ CaptureRequest request,
+ CaptureResult result) {
+ checkAfState(result);
+ }
+
@Override
public void onCaptureCompleted(CameraCaptureSession session,
CaptureRequest request,
TotalCaptureResult result) {
- // Now our mCameraFocusStateListener will invoke the callback the
- // first time it finds the focus motor to be locked.
- mOneshotAfCallback = callback;
+ checkAfState(result);
+ }
+
+ private void checkAfState(CaptureResult result) {
+ if (result.get(CaptureResult.CONTROL_AF_STATE) != null &&
+ !mAlreadyDispatched) {
+ // Now our mCameraResultStateCallback will invoke the callback
+ // the first time it finds the focus motor to be locked.
+ mAlreadyDispatched = true;
+ mOneshotAfCallback = callback;
+ // This is an optimization: check the AF state of this frame
+ // instead of simply waiting for the next.
+ mCameraResultStateCallback.monitorControlStates(result);
+ }
}
@Override
@@ -388,7 +419,7 @@
}};
// Send a one-time capture to trigger the camera driver to lock focus.
- mCameraState.setState(AndroidCamera2StateHolder.CAMERA_FOCUS_LOCKED);
+ changeState(AndroidCamera2StateHolder.CAMERA_FOCUS_LOCKED);
Camera2RequestSettingsSet trigger =
new Camera2RequestSettingsSet(mPersistentSettings);
trigger.set(CaptureRequest.CONTROL_AF_TRIGGER,
@@ -400,7 +431,7 @@
/*listener*/deferredCallbackSetter, /*handler*/ this);
} catch(CameraAccessException ex) {
Log.e(TAG, "Unable to lock autofocus", ex);
- mCameraState.setState(AndroidCamera2StateHolder.CAMERA_PREVIEW_ACTIVE);
+ changeState(AndroidCamera2StateHolder.CAMERA_PREVIEW_ACTIVE);
}
break;
}
@@ -414,7 +445,7 @@
}
// Send a one-time capture to trigger the camera driver to resume scanning.
- mCameraState.setState(AndroidCamera2StateHolder.CAMERA_PREVIEW_ACTIVE);
+ changeState(AndroidCamera2StateHolder.CAMERA_PREVIEW_ACTIVE);
Camera2RequestSettingsSet cancel =
new Camera2RequestSettingsSet(mPersistentSettings);
cancel.set(CaptureRequest.CONTROL_AF_TRIGGER,
@@ -426,8 +457,7 @@
/*listener*/null, /*handler*/this);
} catch(CameraAccessException ex) {
Log.e(TAG, "Unable to cancel autofocus", ex);
- mCameraState.setState(
- AndroidCamera2StateHolder.CAMERA_FOCUS_LOCKED);
+ changeState(AndroidCamera2StateHolder.CAMERA_FOCUS_LOCKED);
}
break;
}
@@ -482,8 +512,21 @@
final CaptureAvailableListener listener =
(CaptureAvailableListener) msg.obj;
- if (mLegacyDevice) {
- // Just snap the shot
+ if (mLegacyDevice ||
+ (mCurrentAeState == CaptureResult.CONTROL_AE_STATE_CONVERGED &&
+ !mPersistentSettings.matches(CaptureRequest.CONTROL_AE_MODE,
+ CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH) &&
+ !mPersistentSettings.matches(CaptureRequest.FLASH_MODE,
+ CaptureRequest.FLASH_MODE_SINGLE)))
+ {
+ // Legacy devices don't support the precapture state keys and instead
+ // perform autoexposure convergence automatically upon capture.
+
+ // On other devices, as long as it has already converged, it determined
+ // that flash was not required, and we're not going to invalidate the
+ // current exposure levels by forcing the force on, we can save
+ // significant capture time by not forcing a recalculation.
+ Log.i(TAG, "Skipping pre-capture autoexposure convergence");
mCaptureReader.setOnImageAvailableListener(listener, /*handler*/this);
try {
mSession.capture(
@@ -492,17 +535,42 @@
mCaptureReader.getSurface()),
listener, /*handler*/this);
} catch (CameraAccessException ex) {
- Log.e(TAG, "Unable to initiate legacy capture", ex);
+ Log.e(TAG, "Unable to initiate immediate capture", ex);
}
} else {
- // Not a legacy device, so we need to let AE converge before capturing
- CameraCaptureSession.CaptureListener deferredCallbackSetter =
- new CameraCaptureSession.CaptureListener() {
+ // We need to let AE converge before capturing. Once our one-time
+ // trigger capture has made it into the pipeline, we'll start checking
+ // for the completion of that convergence, capturing when that happens.
+ Log.i(TAG, "Forcing pre-capture autoexposure convergence");
+ CameraCaptureSession.CaptureCallback deferredCallbackSetter =
+ new CameraCaptureSession.CaptureCallback() {
+ private boolean mAlreadyDispatched = false;
+
+ @Override
+ public void onCaptureProgressed(CameraCaptureSession session,
+ CaptureRequest request,
+ CaptureResult result) {
+ checkAeState(result);
+ }
+
@Override
public void onCaptureCompleted(CameraCaptureSession session,
CaptureRequest request,
TotalCaptureResult result) {
- mOneshotCaptureCallback = listener;
+ checkAeState(result);
+ }
+
+ private void checkAeState(CaptureResult result) {
+ if (result.get(CaptureResult.CONTROL_AE_STATE) != null &&
+ !mAlreadyDispatched) {
+ // Now our mCameraResultStateCallback will invoke the
+ // callback once the autoexposure routine has converged.
+ mAlreadyDispatched = true;
+ mOneshotCaptureCallback = listener;
+ // This is an optimization: check the AE state of this frame
+ // instead of simply waiting for the next.
+ mCameraResultStateCallback.monitorControlStates(result);
+ }
}
@Override
@@ -595,13 +663,13 @@
mSession.setRepeatingRequest(
mPersistentSettings.createRequest(mCamera,
CameraDevice.TEMPLATE_PREVIEW, mPreviewSurface),
- /*listener*/mCameraFocusStateListener, /*handler*/this);
+ /*listener*/mCameraResultStateCallback, /*handler*/this);
} catch (CameraAccessException ex) {
Log.e(TAG, "Failed to apply updated request settings", ex);
}
} else if (mCameraState.getState() < AndroidCamera2StateHolder.CAMERA_PREVIEW_READY) {
// If we're already ready to preview, this doesn't regress our state
- mCameraState.setState(AndroidCamera2StateHolder.CAMERA_CONFIGURED);
+ changeState(AndroidCamera2StateHolder.CAMERA_CONFIGURED);
}
}
@@ -642,7 +710,7 @@
try {
mCamera.createCaptureSession(
Arrays.asList(mPreviewSurface, mCaptureReader.getSurface()),
- mCameraPreviewStateListener, this);
+ mCameraPreviewStateCallback, this);
} catch (CameraAccessException ex) {
Log.e(TAG, "Failed to create camera capture session", ex);
}
@@ -655,12 +723,22 @@
} catch (CameraAccessException ex) {
Log.e(TAG, "Failed to close existing camera capture session", ex);
}
- mCameraState.setState(AndroidCamera2StateHolder.CAMERA_CONFIGURED);
+ changeState(AndroidCamera2StateHolder.CAMERA_CONFIGURED);
}
- // This listener monitors our connection to and disconnection from camera devices.
- private CameraDevice.StateListener mCameraDeviceStateListener =
- new CameraDevice.StateListener() {
+ private void changeState(int newState) {
+ if (mCameraState.getState() != newState) {
+ mCameraState.setState(newState);
+ if (newState < AndroidCamera2StateHolder.CAMERA_PREVIEW_ACTIVE) {
+ mCurrentAeState = CaptureResult.CONTROL_AE_STATE_INACTIVE;
+ mCameraResultStateCallback.resetState();
+ }
+ }
+ }
+
+ // This callback monitors our connection to and disconnection from camera devices.
+ private CameraDevice.StateCallback mCameraDeviceStateCallback =
+ new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera) {
mCamera = camera;
@@ -676,7 +754,7 @@
mLegacyDevice =
props.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL) ==
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY;
- mCameraState.setState(AndroidCamera2StateHolder.CAMERA_UNCONFIGURED);
+ changeState(AndroidCamera2StateHolder.CAMERA_UNCONFIGURED);
mOpenCallback.onCameraOpened(mCameraProxy);
} catch (CameraAccessException ex) {
mOpenCallback.onDeviceOpenFailure(mCameraIndex,
@@ -700,13 +778,13 @@
}
}};
- // This listener monitors our camera session (i.e. our transition into and out of preview).
- private CameraCaptureSession.StateListener mCameraPreviewStateListener =
- new CameraCaptureSession.StateListener() {
+ // This callback monitors our camera session (i.e. our transition into and out of preview).
+ private CameraCaptureSession.StateCallback mCameraPreviewStateCallback =
+ new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
mSession = session;
- mCameraState.setState(AndroidCamera2StateHolder.CAMERA_PREVIEW_READY);
+ changeState(AndroidCamera2StateHolder.CAMERA_PREVIEW_READY);
}
@Override
@@ -724,49 +802,76 @@
}
}};
- // This listener monitors requested captures and notifies any relevant callbacks.
- private CameraCaptureSession.CaptureListener mCameraFocusStateListener =
- new CameraCaptureSession.CaptureListener() {
+ private abstract class CameraResultStateCallback
+ extends CameraCaptureSession.CaptureCallback {
+ public abstract void monitorControlStates(CaptureResult result);
+
+ public abstract void resetState();
+ }
+
+ // This callback monitors requested captures and notifies any relevant callbacks.
+ private CameraResultStateCallback mCameraResultStateCallback =
+ new CameraResultStateCallback() {
private int mLastAfState = -1;
+ private long mLastAfFrameNumber = -1;
+ private long mLastAeFrameNumber = -1;
+
+ @Override
+ public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request,
+ CaptureResult result) {
+ monitorControlStates(result);
+ }
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
TotalCaptureResult result) {
+ monitorControlStates(result);
+ }
+
+ @Override
+ public void monitorControlStates(CaptureResult result) {
Integer afStateMaybe = result.get(CaptureResult.CONTROL_AF_STATE);
if (afStateMaybe != null) {
int afState = afStateMaybe;
- boolean afStateChanged = false;
- if (afState != mLastAfState) {
+ // Since we handle both partial and total results for multiple frames here, we
+ // might get the final callbacks for an earlier frame after receiving one or
+ // more that correspond to the next one. To prevent our data from oscillating,
+ // we never consider AF states that are older than the last one we've seen.
+ if (result.getFrameNumber() > mLastAfFrameNumber) {
+ boolean afStateChanged = afState != mLastAfState;
mLastAfState = afState;
- afStateChanged = true;
- }
+ mLastAfFrameNumber = result.getFrameNumber();
- switch (afState) {
- case CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN:
- case CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED:
- case CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED: {
- if (afStateChanged && mPassiveAfCallback != null) {
- // A CameraAFMoveCallback is attached. If we just started to scan,
- // the motor is moving; otherwise, it has settled.
- mPassiveAfCallback.onAutoFocusMoving(
- afState == CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN,
- mCameraProxy);
+ switch (afState) {
+ case CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN:
+ case CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED:
+ case CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED: {
+ if (afStateChanged && mPassiveAfCallback != null) {
+ // A CameraAFMoveCallback is attached. If we just started to
+ // scan, the motor is moving; otherwise, it has settled.
+ mPassiveAfCallback.onAutoFocusMoving(
+ afState == CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN,
+ mCameraProxy);
+ }
+ break;
}
- break;
- }
- case CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED:
- case CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED: {
- if (mOneshotAfCallback != null) {
- // A call to autoFocus() was just made to request a focus lock.
- // Notify the caller that the lens is now indefinitely fixed, and
- // report whether the image we're now stuck with is in focus.
- mOneshotAfCallback.onAutoFocus(
- afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED,
- mCameraProxy);
- mOneshotAfCallback = null;
+ case CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED:
+ case CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED: {
+ // This check must be made regardless of whether the focus state has
+ // changed recently to avoid infinite waiting during autoFocus()
+ // when the algorithm has already either converged or failed to.
+ if (mOneshotAfCallback != null) {
+ // A call to autoFocus() was just made to request a focus lock.
+ // Notify the caller that the lens is now indefinitely fixed,
+ // and report whether the image we're stuck with is in focus.
+ mOneshotAfCallback.onAutoFocus(
+ afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED,
+ mCameraProxy);
+ mOneshotAfCallback = null;
+ }
+ break;
}
- break;
}
}
}
@@ -774,36 +879,55 @@
Integer aeStateMaybe = result.get(CaptureResult.CONTROL_AE_STATE);
if (aeStateMaybe != null) {
int aeState = aeStateMaybe;
+ // Since we handle both partial and total results for multiple frames here, we
+ // might get the final callbacks for an earlier frame after receiving one or
+ // more that correspond to the next one. To prevent our data from oscillating,
+ // we never consider AE states that are older than the last one we've seen.
+ if (result.getFrameNumber() > mLastAeFrameNumber) {
+ mCurrentAeState = aeStateMaybe;
+ mLastAeFrameNumber = result.getFrameNumber();
- switch (aeState) {
- case CaptureResult.CONTROL_AE_STATE_CONVERGED:
- case CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED:
- case CaptureResult.CONTROL_AE_STATE_LOCKED: {
- if (mOneshotCaptureCallback != null) {
- // A call to takePicture() was just made, and autoexposure converged
- // so it's time to initiate the capture!
- mCaptureReader.setOnImageAvailableListener(mOneshotCaptureCallback,
- /*handler*/Camera2Handler.this);
- try {
- mSession.capture(
- mPersistentSettings.createRequest(mCamera,
- CameraDevice.TEMPLATE_STILL_CAPTURE,
- mCaptureReader.getSurface()),
+ switch (aeState) {
+ case CaptureResult.CONTROL_AE_STATE_CONVERGED:
+ case CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED:
+ case CaptureResult.CONTROL_AE_STATE_LOCKED: {
+ // This check must be made regardless of whether the exposure state
+ // has changed recently to avoid infinite waiting during
+ // takePicture() when the algorithm has already converged.
+ if (mOneshotCaptureCallback != null) {
+ // A call to takePicture() was just made, and autoexposure
+ // converged so it's time to initiate the capture!
+ mCaptureReader.setOnImageAvailableListener(
/*listener*/mOneshotCaptureCallback,
/*handler*/Camera2Handler.this);
- } catch (CameraAccessException ex) {
- Log.e(TAG, "Unable to initiate capture", ex);
- } finally {
- mOneshotCaptureCallback = null;
+ try {
+ mSession.capture(
+ mPersistentSettings.createRequest(mCamera,
+ CameraDevice.TEMPLATE_STILL_CAPTURE,
+ mCaptureReader.getSurface()),
+ /*callback*/mOneshotCaptureCallback,
+ /*handler*/Camera2Handler.this);
+ } catch (CameraAccessException ex) {
+ Log.e(TAG, "Unable to initiate capture", ex);
+ } finally {
+ mOneshotCaptureCallback = null;
+ }
}
+ break;
}
- break;
}
}
}
}
@Override
+ public void resetState() {
+ mLastAfState = -1;
+ mLastAfFrameNumber = -1;
+ mLastAeFrameNumber = -1;
+ }
+
+ @Override
public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request,
CaptureFailure failure) {
Log.e(TAG, "Capture attempt failed with reason " + failure.getReason());
@@ -815,6 +939,8 @@
private final CameraDevice mCamera;
private final CameraDeviceInfo.Characteristics mCharacteristics;
private final AndroidCamera2Capabilities mCapabilities;
+ private CameraSettings mLastSettings;
+ private boolean mShutterSoundEnabled;
public AndroidCamera2ProxyImpl(int cameraIndex, CameraDevice camera,
CameraDeviceInfo.Characteristics characteristics,
@@ -823,6 +949,8 @@
mCamera = camera;
mCharacteristics = characteristics;
mCapabilities = new AndroidCamera2Capabilities(properties);
+ mLastSettings = null;
+ mShutterSoundEnabled = true;
}
// TODO: Implement
@@ -848,6 +976,26 @@
return mCapabilities;
}
+ // FIXME: Unlock the sizes in stopPreview(), as per the corresponding
+ // explanation on the STOP_PREVIEW case in the handler.
+ @Override
+ public void setPreviewTexture(SurfaceTexture surfaceTexture) {
+ // Once the Surface has been selected, we configure the session and
+ // are no longer able to change the sizes.
+ getSettings().setSizesLocked(true);
+ super.setPreviewTexture(surfaceTexture);
+ }
+
+ // FIXME: Unlock the sizes in stopPreview(), as per the corresponding
+ // explanation on the STOP_PREVIEW case in the handler.
+ @Override
+ public void setPreviewTextureSync(SurfaceTexture surfaceTexture) {
+ // Once the Surface has been selected, we configure the session and
+ // are no longer able to change the sizes.
+ getSettings().setSizesLocked(true);
+ super.setPreviewTexture(surfaceTexture);
+ }
+
// TODO: Implement
@Override
public void setPreviewDataCallback(Handler handler, CameraPreviewDataCallback cb) {}
@@ -915,7 +1063,6 @@
}});
}
- // TODO: Implement
@Override
public void takePicture(final Handler handler,
final CameraShutterCallback shutter,
@@ -932,6 +1079,9 @@
handler.post(new Runnable() {
@Override
public void run() {
+ if (mShutterSoundEnabled) {
+ mNoisemaker.play(MediaActionSound.SHUTTER_CLICK);
+ }
shutter.onShutter(AndroidCamera2ProxyImpl.this);
}});
}
@@ -955,8 +1105,9 @@
mDispatchThread.runJob(new Runnable() {
@Override
public void run() {
- mCameraState.waitForStates(AndroidCamera2StateHolder.CAMERA_PREVIEW_ACTIVE |
- AndroidCamera2StateHolder.CAMERA_FOCUS_LOCKED);
+ // Wait until PREVIEW_ACTIVE or better
+ mCameraState.waitForStates(
+ ~(AndroidCamera2StateHolder.CAMERA_PREVIEW_ACTIVE - 1));
mCameraHandler.obtainMessage(CameraActions.CAPTURE_PHOTO, picListener)
.sendToTarget();
}});
@@ -993,7 +1144,10 @@
@Override
public CameraSettings getSettings() {
- return mCameraHandler.buildSettings(mCapabilities);
+ if (mLastSettings == null) {
+ mLastSettings = mCameraHandler.buildSettings(mCapabilities);
+ }
+ return mLastSettings;
}
@Override
@@ -1007,9 +1161,17 @@
return false;
}
- return applySettingsHelper(settings, AndroidCamera2StateHolder.CAMERA_UNCONFIGURED |
- AndroidCamera2StateHolder.CAMERA_CONFIGURED |
- AndroidCamera2StateHolder.CAMERA_PREVIEW_READY);
+ // Wait for any state that isn't OPENED
+ if (applySettingsHelper(settings, ~AndroidCamera2StateHolder.CAMERA_UNOPENED)) {
+ mLastSettings = settings;
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void enableShutterSound(boolean enable) {
+ mShutterSoundEnabled = enable;
}
// TODO: Implement
@@ -1036,19 +1198,22 @@
private static class AndroidCamera2StateHolder extends CameraStateHolder {
// Usage flow: openCamera() -> applySettings() -> setPreviewTexture() -> startPreview() ->
// autoFocus() -> takePicture()
+ // States are mutually exclusive, but must be separate bits so that they can be used with
+ // the StateHolder#waitForStates() and StateHolder#waitToAvoidStates() methods.
+ // Do not set the state to be a combination of these values!
/* Camera states */
/** No camera device is opened. */
- public static final int CAMERA_UNOPENED = 1;
+ public static final int CAMERA_UNOPENED = 1 << 0;
/** A camera is opened, but no settings have been provided. */
- public static final int CAMERA_UNCONFIGURED = 2;
+ public static final int CAMERA_UNCONFIGURED = 1 << 1;
/** The open camera has been configured by providing it with settings. */
- public static final int CAMERA_CONFIGURED = 3;
+ public static final int CAMERA_CONFIGURED = 1 << 2;
/** A capture session is ready to stream a preview, but still has no repeating request. */
- public static final int CAMERA_PREVIEW_READY = 4;
+ public static final int CAMERA_PREVIEW_READY = 1 << 3;
/** A preview is currently being streamed. */
- public static final int CAMERA_PREVIEW_ACTIVE = 5;
+ public static final int CAMERA_PREVIEW_ACTIVE = 1 << 4;
/** The lens is locked on a particular region. */
- public static final int CAMERA_FOCUS_LOCKED = 6;
+ public static final int CAMERA_FOCUS_LOCKED = 1 << 5;
public AndroidCamera2StateHolder() {
this(CAMERA_UNOPENED);
@@ -1169,9 +1334,7 @@
@Override
public boolean canDisableShutterSound() {
- // The new API doesn't support this operation, so don't encourage people to try it.
- // TODO: What kind of assumptions have callers made about this result's meaning?
- return false;
+ return true;
}
private static float[] convertRectToPoly(RectF rf) {
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2Capabilities.java b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2Capabilities.java
index 51c1422..8001a37 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2Capabilities.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2Capabilities.java
@@ -81,7 +81,7 @@
mMaxNumOfFacesSupported = p.get(STATISTICS_INFO_MAX_FACE_COUNT);
mMaxNumOfMeteringArea = p.get(CONTROL_MAX_REGIONS_AE);
- // TODO: Populate mMaxZoomRatio
+ mMaxZoomRatio = p.get(SCALER_AVAILABLE_MAX_DIGITAL_ZOOM);
// TODO: Populate mHorizontalViewAngle
// TODO: Populate mVerticalViewAngle
// TODO: Populate mZoomRatioList
@@ -97,6 +97,10 @@
mSupportedFeatures.add(Feature.METERING_AREA);
}
+ if (mMaxZoomRatio > CameraCapabilities.ZOOM_RATIO_UNZOOMED) {
+ mSupportedFeatures.add(Feature.ZOOM);
+ }
+
// TODO: Detect other features
}
@@ -200,7 +204,6 @@
return SceneMode.CANDLELIGHT;
case CONTROL_SCENE_MODE_FIREWORKS:
return SceneMode.FIREWORKS;
- // TODO: We cannot support HDR
case CONTROL_SCENE_MODE_LANDSCAPE:
return SceneMode.LANDSCAPE;
case CONTROL_SCENE_MODE_NIGHT:
@@ -222,6 +225,11 @@
return SceneMode.THEATRE;
// TODO: We cannot expose FACE_PRIORITY, or HIGH_SPEED_VIDEO
}
+
+ if (sm == LegacyVendorTags.CONTROL_SCENE_MODE_HDR) {
+ return SceneMode.HDR;
+ }
+
Log.w(TAG, "Unable to convert from API 2 scene mode: " + sm);
return null;
}
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2Settings.java b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2Settings.java
index efa68e8..540d8df 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2Settings.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2Settings.java
@@ -18,10 +18,13 @@
import static android.hardware.camera2.CaptureRequest.*;
+import android.graphics.Matrix;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.params.MeteringRectangle;
+import android.location.Location;
import android.util.Range;
import com.android.ex.camera2.portability.CameraCapabilities.FlashMode;
@@ -41,8 +44,13 @@
private static final Log.Tag TAG = new Log.Tag("AndCam2Set");
private final Builder mTemplateSettings;
- private final Rect mActiveArray;
private final Camera2RequestSettingsSet mRequestSettings;
+ /** Sensor's active array bounds. */
+ private final Rect mActiveArray;
+ /** Crop rectangle for digital zoom (measured WRT the active array). */
+ private final Rect mCropRectangle;
+ /** Bounds of visible preview portion (measured WRT the active array). */
+ private Rect mVisiblePreviewRectangle;
/**
* Create a settings representation that answers queries of unspecified
@@ -56,19 +64,33 @@
* their effective values when submitting a capture request will be those of
* the template that is provided to the camera framework at that time.</p>
*
- * @param camera Device from which to draw default settings.
+ * @param camera Device from which to draw default settings
+ * (non-{@code null}).
* @param template Specific template to use for the defaults.
- * @param activeArray Boundary coordinates of the sensor's active array.
+ * @param activeArray Boundary coordinates of the sensor's active array
+ * (non-{@code null}).
* @param preview Dimensions of preview streams.
* @param photo Dimensions of captured images.
*
+ * @throws IllegalArgumentException If {@code camera} or {@code activeArray}
+ * is {@code null}.
* @throws CameraAccessException Upon internal framework/driver failure.
*/
public AndroidCamera2Settings(CameraDevice camera, int template, Rect activeArray,
Size preview, Size photo) throws CameraAccessException {
+ if (camera == null) {
+ throw new NullPointerException("camera must not be null");
+ }
+ if (activeArray == null) {
+ throw new NullPointerException("activeArray must not be null");
+ }
+
mTemplateSettings = camera.createCaptureRequest(template);
- mActiveArray = activeArray;
mRequestSettings = new Camera2RequestSettingsSet();
+ mActiveArray = activeArray;
+ mCropRectangle = new Rect(0, 0, activeArray.width(), activeArray.height());
+
+ mSizesLocked = false;
Range<Integer> previewFpsRange = mTemplateSettings.get(CONTROL_AE_TARGET_FPS_RANGE);
if (previewFpsRange != null) {
@@ -79,8 +101,8 @@
setPhotoSize(photo);
mJpegCompressQuality = queryTemplateDefaultOrMakeOneUp(JPEG_QUALITY, (byte) 0);
// TODO: mCurrentPhotoFormat
- // TODO: mCurrentZoomRatio
- mCurrentZoomRatio = 1.0f;
+ // NB: We're assuming that templates won't be zoomed in by default.
+ mCurrentZoomRatio = CameraCapabilities.ZOOM_RATIO_UNZOOMED;
// TODO: mCurrentZoomIndex
mExposureCompensationIndex =
queryTemplateDefaultOrMakeOneUp(CONTROL_AE_EXPOSURE_COMPENSATION, 0);
@@ -116,8 +138,9 @@
public AndroidCamera2Settings(AndroidCamera2Settings other) {
super(other);
mTemplateSettings = other.mTemplateSettings;
- mActiveArray = other.mActiveArray;
mRequestSettings = new Camera2RequestSettingsSet(other.mRequestSettings);
+ mActiveArray = other.mActiveArray;
+ mCropRectangle = new Rect(other.mCropRectangle);
}
@Override
@@ -159,13 +182,31 @@
return null;
}
+ @Override
+ public void setZoomRatio(float ratio) {
+ super.setZoomRatio(ratio);
+
+ // Compute the crop rectangle to be passed to the framework
+ mCropRectangle.set(0, 0,
+ toIntConstrained(
+ mActiveArray.width() / mCurrentZoomRatio, 0, mActiveArray.width()),
+ toIntConstrained(
+ mActiveArray.height() / mCurrentZoomRatio, 0, mActiveArray.height()));
+ mCropRectangle.offsetTo((mActiveArray.width() - mCropRectangle.width()) / 2,
+ (mActiveArray.height() - mCropRectangle.height()) / 2);
+
+ // Compute the effective crop rectangle to be used for computing focus/metering coordinates
+ mVisiblePreviewRectangle =
+ effectiveCropRectFromRequested(mCropRectangle, mCurrentPreviewSize);
+ }
+
private boolean matchesTemplateDefault(Key<?> setting) {
if (setting == CONTROL_AE_REGIONS) {
return mMeteringAreas.size() == 0;
} else if (setting == CONTROL_AF_REGIONS) {
return mFocusAreas.size() == 0;
} else if (setting == CONTROL_AE_TARGET_FPS_RANGE) {
- Range defaultFpsRange = mTemplateSettings.get(CONTROL_AE_TARGET_FPS_RANGE);
+ Range<Integer> defaultFpsRange = mTemplateSettings.get(CONTROL_AE_TARGET_FPS_RANGE);
return (mPreviewFpsRangeMin == 0 && mPreviewFpsRangeMax == 0) ||
(defaultFpsRange != null && mPreviewFpsRangeMin == defaultFpsRange.getLower() &&
mPreviewFpsRangeMax == defaultFpsRange.getUpper());
@@ -213,7 +254,7 @@
// TODO: mCurrentPreviewFormat
updateRequestSettingOrForceToDefault(JPEG_QUALITY, mJpegCompressQuality);
// TODO: mCurrentPhotoFormat
- // TODO: mCurrentZoomRatio
+ mRequestSettings.set(SCALER_CROP_REGION, mCropRectangle);
// TODO: mCurrentZoomIndex
updateRequestSettingOrForceToDefault(CONTROL_AE_EXPOSURE_COMPENSATION,
mExposureCompensationIndex);
@@ -231,7 +272,7 @@
updateRequestSettingOrForceToDefault(CONTROL_AE_LOCK, mAutoExposureLocked);
updateRequestSettingOrForceToDefault(CONTROL_AWB_LOCK, mAutoWhiteBalanceLocked);
// TODO: mRecordingHintEnabled
- // TODO: mGpsData
+ updateRequestGpsData();
updateRequestSettingOrForceToDefault(JPEG_THUMBNAIL_SIZE,
new android.util.Size(
mExifThumbnailSize.width(), mExifThumbnailSize.height()));
@@ -243,25 +284,25 @@
List<android.hardware.Camera.Area> reference) {
MeteringRectangle[] transformed = null;
if (reference.size() > 0) {
-
transformed = new MeteringRectangle[reference.size()];
for (int index = 0; index < reference.size(); ++index) {
android.hardware.Camera.Area source = reference.get(index);
Rect rectangle = source.rect;
// Old API coordinates were [-1000,1000]; new ones are [0,ACTIVE_ARRAY_SIZE).
+ // We're also going from preview image--relative to sensor active array--relative.
double oldLeft = (rectangle.left + 1000) / 2000.0;
double oldTop = (rectangle.top + 1000) / 2000.0;
double oldRight = (rectangle.right + 1000) / 2000.0;
double oldBottom = (rectangle.bottom + 1000) / 2000.0;
- int left = toIntConstrained( mActiveArray.width() * oldLeft + mActiveArray.left,
- 0, mActiveArray.width() - 1);
- int top = toIntConstrained( mActiveArray.height() * oldTop + mActiveArray.top,
- 0, mActiveArray.height() - 1);
- int right = toIntConstrained( mActiveArray.width() * oldRight + mActiveArray.left,
- 0, mActiveArray.width() - 1);
- int bottom = toIntConstrained( mActiveArray.height() * oldBottom + mActiveArray.top,
- 0, mActiveArray.height() - 1);
+ int left = mCropRectangle.left + toIntConstrained(
+ mCropRectangle.width() * oldLeft, 0, mCropRectangle.width() - 1);
+ int top = mCropRectangle.top + toIntConstrained(
+ mCropRectangle.height() * oldTop, 0, mCropRectangle.height() - 1);
+ int right = mCropRectangle.left + toIntConstrained(
+ mCropRectangle.width() * oldRight, 0, mCropRectangle.width() - 1);
+ int bottom = mCropRectangle.top + toIntConstrained(
+ mCropRectangle.height() * oldBottom, 0, mCropRectangle.height() - 1);
transformed[index] = new MeteringRectangle(left, top, right - left, bottom - top,
source.weight);
}
@@ -378,7 +419,10 @@
mode = CONTROL_SCENE_MODE_FIREWORKS;
break;
}
- // TODO: We cannot support HDR
+ case HDR: {
+ mode = LegacyVendorTags.CONTROL_SCENE_MODE_HDR;
+ break;
+ }
case LANDSCAPE: {
mode = CONTROL_SCENE_MODE_LANDSCAPE;
break;
@@ -469,4 +513,65 @@
}
mRequestSettings.set(CONTROL_AWB_MODE, mode);
}
+
+ private void updateRequestGpsData() {
+ if (mGpsData == null || mGpsData.processingMethod == null) {
+ // It's a hack since we always use GPS time stamp but does
+ // not use other fields sometimes. Setting processing
+ // method to null means the other fields should not be used.
+ mRequestSettings.set(JPEG_GPS_LOCATION, null);
+ } else {
+ Location location = new Location(mGpsData.processingMethod);
+ location.setTime(mGpsData.timeStamp);
+ location.setAltitude(mGpsData.altitude);
+ location.setLatitude(mGpsData.latitude);
+ location.setLongitude(mGpsData.longitude);
+ mRequestSettings.set(JPEG_GPS_LOCATION, location);
+ }
+ }
+
+ /**
+ * Calculate the effective crop rectangle for this preview viewport;
+ * assumes the preview is centered to the sensor and scaled to fit across one of the dimensions
+ * without skewing.
+ *
+ * <p>Assumes the zoom level of the provided desired crop rectangle.</p>
+ *
+ * @param requestedCrop Desired crop rectangle, in active array space.
+ * @param previewSize Size of the preview buffer render target, in pixels (not in sensor space).
+ * @return A rectangle that serves as the preview stream's effective crop region (unzoomed), in
+ * sensor space.
+ *
+ * @throws NullPointerException
+ * If any of the args were {@code null}.
+ */
+ private static Rect effectiveCropRectFromRequested(Rect requestedCrop, Size previewSize) {
+ float aspectRatioArray = requestedCrop.width() * 1.0f / requestedCrop.height();
+ float aspectRatioPreview = previewSize.width() * 1.0f / previewSize.height();
+
+ float cropHeight, cropWidth;
+ if (aspectRatioPreview < aspectRatioArray) {
+ // The new width must be smaller than the height, so scale the width by AR
+ cropHeight = requestedCrop.height();
+ cropWidth = cropHeight * aspectRatioPreview;
+ } else {
+ // The new height must be smaller (or equal) than the width, so scale the height by AR
+ cropWidth = requestedCrop.width();
+ cropHeight = cropWidth / aspectRatioPreview;
+ }
+
+ Matrix translateMatrix = new Matrix();
+ RectF cropRect = new RectF(/*left*/0, /*top*/0, cropWidth, cropHeight);
+
+ // Now center the crop rectangle so its center is in the center of the active array
+ translateMatrix.setTranslate(requestedCrop.exactCenterX(), requestedCrop.exactCenterY());
+ translateMatrix.postTranslate(-cropRect.centerX(), -cropRect.centerY());
+
+ translateMatrix.mapRect(/*inout*/cropRect);
+
+ // Round the rect corners towards the nearest integer values
+ Rect result = new Rect();
+ cropRect.roundOut(result);
+ return result;
+ }
}
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraAgentImpl.java b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraAgentImpl.java
index a9aba37..949ac62 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraAgentImpl.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraAgentImpl.java
@@ -38,6 +38,8 @@
import com.android.ex.camera2.portability.debug.Log;
import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
import java.util.StringTokenizer;
/**
@@ -402,6 +404,7 @@
break;
}
+ // TODO: Lock the CameraSettings object's sizes
case CameraActions.SET_PREVIEW_TEXTURE_ASYNC: {
setPreviewTexture(msg.obj);
break;
@@ -426,6 +429,7 @@
break;
}
+ // TODO: Unlock the CameraSettings object's sizes
case CameraActions.STOP_PREVIEW: {
mCamera.stopPreview();
break;
@@ -600,8 +604,8 @@
parameters.setPreviewFormat(settings.getCurrentPreviewFormat());
parameters.setJpegQuality(settings.getPhotoJpegCompressionQuality());
if (mCapabilities.supports(CameraCapabilities.Feature.ZOOM)) {
- // Should use settings.getCurrentZoomRatio() instead here.
- parameters.setZoom(settings.getCurrentZoomIndex());
+ parameters.setZoom(zoomRatioToIndex(settings.getCurrentZoomRatio(),
+ parameters.getZoomRatios()));
}
parameters.setExposureCompensation(settings.getExposureCompensationIndex());
if (mCapabilities.supports(CameraCapabilities.Feature.AUTO_EXPOSURE_LOCK)) {
@@ -614,11 +618,15 @@
if (mCapabilities.supports(CameraCapabilities.Feature.FOCUS_AREA)) {
if (settings.getFocusAreas().size() != 0) {
parameters.setFocusAreas(settings.getFocusAreas());
+ } else {
+ parameters.setFocusAreas(null);
}
}
if (mCapabilities.supports(CameraCapabilities.Feature.METERING_AREA)) {
if (settings.getMeteringAreas().size() != 0) {
parameters.setMeteringAreas(settings.getMeteringAreas());
+ } else {
+ parameters.setMeteringAreas(null);
}
}
if (settings.getCurrentFlashMode() != CameraCapabilities.FlashMode.NO_FLASH) {
@@ -652,6 +660,29 @@
}
}
+
+ /**
+ * @param ratio Desired zoom ratio, in [1.0f,+Inf).
+ * @param percentages Available zoom ratios, as percentages.
+ * @return Index of the closest corresponding ratio, rounded up toward
+ * that of the maximum available ratio.
+ */
+ private int zoomRatioToIndex(float ratio, List<Integer> percentages) {
+ int percent = (int) (ratio * AndroidCameraCapabilities.ZOOM_MULTIPLIER);
+ int index = Collections.binarySearch(percentages, percent);
+ if (index >= 0) {
+ // Found the desired ratio in the supported list
+ return index;
+ } else {
+ // Didn't find an exact match. Where would it have been?
+ index = -(index + 1);
+ if (index == percentages.size()) {
+ // Put it back in bounds by setting to the maximum allowable zoom
+ --index;
+ }
+ return index;
+ }
+ }
}
/**
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraCapabilities.java b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraCapabilities.java
index acff9c6..84b44e6 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraCapabilities.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraCapabilities.java
@@ -31,6 +31,9 @@
private static Log.Tag TAG = new Log.Tag("AndCamCapabs");
+ /** Conversion from ratios to percentages. */
+ public static final float ZOOM_MULTIPLIER = 100f;
+
private FpsComparator mFpsComparator = new FpsComparator();
private SizeComparator mSizeComparator = new SizeComparator();
@@ -44,9 +47,7 @@
mPreferredPreviewSizeForVideo = new Size(p.getPreferredPreviewSizeForVideo());
mSupportedPreviewFormats.addAll(p.getSupportedPreviewFormats());
mSupportedPhotoFormats.addAll(p.getSupportedPictureFormats());
- mMaxZoomIndex = p.getMaxZoom();
- mZoomRatioList.addAll(p.getZoomRatios());
- mMaxZoomRatio = mZoomRatioList.get(mMaxZoomIndex);
+ mMaxZoomRatio = p.getZoomRatios().get(p.getMaxZoom()) / ZOOM_MULTIPLIER;
mHorizontalViewAngle = p.getHorizontalViewAngle();
mVerticalViewAngle = p.getVerticalViewAngle();
buildPreviewFpsRange(p);
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraSettings.java b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraSettings.java
index ceab7fe..ee69b54 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraSettings.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraSettings.java
@@ -28,6 +28,8 @@
public AndroidCameraSettings(CameraCapabilities capabilities, Camera.Parameters params) {
CameraCapabilities.Stringifier stringifier = capabilities.getStringifier();
+ setSizesLocked(false);
+
// Preview
Camera.Size paramPreviewSize = params.getPreviewSize();
setPreviewSize(new Size(paramPreviewSize.width, paramPreviewSize.height));
@@ -41,10 +43,8 @@
// Capture: Focus, flash, zoom, exposure, scene mode.
if (capabilities.supports(CameraCapabilities.Feature.ZOOM)) {
setZoomRatio(params.getZoomRatios().get(params.getZoom()) / 100f);
- setZoomIndex(params.getZoom());
} else {
- setZoomRatio(1.0f);
- setZoomIndex(0);
+ setZoomRatio(CameraCapabilities.ZOOM_RATIO_UNZOOMED);
}
setExposureCompensationIndex(params.getExposureCompensation());
setFlashMode(stringifier.flashModeFromString(params.getFlashMode()));
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/CameraAgent.java b/camera2/portability/src/com/android/ex/camera2/portability/CameraAgent.java
index dd4f77c..b624b47 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/CameraAgent.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/CameraAgent.java
@@ -436,8 +436,24 @@
/**
* Sets the {@link android.graphics.SurfaceTexture} for preview.
*
+ * <p>Note that, once this operation has been performed, it is no longer
+ * possible to change the preview or photo sizes in the
+ * {@link CameraSettings} instance for this camera, and the mutators for
+ * these fields are allowed to ignore all further invocations until the
+ * preview is stopped with {@link #stopPreview}.</p>
+ *
* @param surfaceTexture The {@link SurfaceTexture} for preview.
+ *
+ * @see CameraSettings#setPhotoSize
+ * @see CameraSettings#setPreviewSize
*/
+ // XXX: Despite the above documentation about locking the sizes, the API
+ // 1 implementation doesn't currently enforce this at all, although the
+ // Camera class warns that preview sizes shouldn't be changed while a
+ // preview is running. Furthermore, the API 2 implementation doesn't yet
+ // unlock the sizes when stopPreview() is invoked (see related FIXME on
+ // the STOP_PREVIEW case in its handler; in the meantime, changing API 2
+ // sizes would require closing and reopening the camera.
public void setPreviewTexture(final SurfaceTexture surfaceTexture) {
getDispatchThread().runJob(new Runnable() {
@Override
@@ -452,7 +468,15 @@
* Blocks until a {@link android.graphics.SurfaceTexture} has been set
* for preview.
*
+ * <p>Note that, once this operation has been performed, it is no longer
+ * possible to change the preview or photo sizes in the
+ * {@link CameraSettings} instance for this camera, and the mutators for
+ * these fields are allowed to ignore all further invocations.</p>
+ *
* @param surfaceTexture The {@link SurfaceTexture} for preview.
+ *
+ * @see CameraSettings#setPhotoSize
+ * @see CameraSettings#setPreviewSize
*/
public void setPreviewTextureSync(final SurfaceTexture surfaceTexture) {
final WaitDoneBundle bundle = new WaitDoneBundle();
@@ -732,10 +756,11 @@
protected boolean applySettingsHelper(CameraSettings settings,
final int statesToAwait) {
if (settings == null) {
- Log.v(TAG, "null parameters in applySettings()");
+ Log.v(TAG, "null argument in applySettings()");
return false;
}
if (!getCapabilities().supports(settings)) {
+ Log.w(TAG, "Unsupported settings in applySettings()");
return false;
}
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/CameraCapabilities.java b/camera2/portability/src/com/android/ex/camera2/portability/CameraCapabilities.java
index 6a4c72c..60c8cb2 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/CameraCapabilities.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/CameraCapabilities.java
@@ -36,6 +36,9 @@
private static Log.Tag TAG = new Log.Tag("CamCapabs");
+ /** Zoom ratio used for seeing sensor's full field of view. */
+ protected static final float ZOOM_RATIO_UNZOOMED = 1.0f;
+
/* All internal states are declared final and should be thread-safe. */
protected final ArrayList<int[]> mSupportedPreviewFpsRange = new ArrayList<int[]>();
@@ -57,12 +60,10 @@
protected int mMaxNumOfFacesSupported;
protected int mMaxNumOfFocusAreas;
protected int mMaxNumOfMeteringArea;
- protected int mMaxZoomRatio;
+ protected float mMaxZoomRatio;
protected float mHorizontalViewAngle;
protected float mVerticalViewAngle;
private final Stringifier mStringifier;
- protected final ArrayList<Integer> mZoomRatioList = new ArrayList<Integer>();
- protected int mMaxZoomIndex;
/**
* Focus modes.
@@ -183,7 +184,7 @@
* Capture a scene using high dynamic range imaging techniques.
* @see {@link android.hardware.Camera.Parameters#SCENE_MODE_HDR}.
*/
- // TODO: Unsupported on API 2
+ // Note: Supported as a vendor tag on the Camera2 API for some LEGACY devices.
HDR,
/**
* Take pictures on distant objects.
@@ -488,8 +489,6 @@
mMaxNumOfFacesSupported = src.mMaxNumOfFacesSupported;
mMaxNumOfFocusAreas = src.mMaxNumOfFocusAreas;
mMaxNumOfMeteringArea = src.mMaxNumOfMeteringArea;
- mMaxZoomIndex = src.mMaxZoomIndex;
- mZoomRatioList.addAll(src.mZoomRatioList);
mMaxZoomRatio = src.mMaxZoomRatio;
mHorizontalViewAngle = src.mHorizontalViewAngle;
mVerticalViewAngle = src.mVerticalViewAngle;
@@ -635,17 +634,6 @@
return mMaxZoomRatio;
}
- // We'll replace these old style methods with new ones.
- @Deprecated
- public int getMaxZoomIndex() {
- return mMaxZoomIndex;
- }
-
- @Deprecated
- public List<Integer> getZoomRatioList() {
- return new ArrayList<Integer>(mZoomRatioList);
- }
-
/**
* @return The min exposure compensation index. The EV is the compensation
* index multiplied by the step value. If unsupported, both this method and
@@ -689,17 +677,15 @@
private boolean zoomCheck(final CameraSettings settings) {
final float ratio = settings.getCurrentZoomRatio();
- final int index = settings.getCurrentZoomIndex();
if (!supports(Feature.ZOOM)) {
- if (ratio != 1.0f || index != 0) {
+ if (ratio != ZOOM_RATIO_UNZOOMED) {
Log.v(TAG, "Zoom is not supported");
return false;
}
} else {
- if (settings.getCurrentZoomRatio() > getMaxZoomRatio() ||
- index > getMaxZoomIndex()) {
+ if (settings.getCurrentZoomRatio() > getMaxZoomRatio()) {
Log.v(TAG, "Zoom ratio is not supported: ratio = " +
- settings.getCurrentZoomRatio() + ", index = " + index);
+ settings.getCurrentZoomRatio());
return false;
}
}
@@ -720,9 +706,16 @@
private boolean focusCheck(final CameraSettings settings) {
FocusMode focusMode = settings.getCurrentFocusMode();
if (!supports(focusMode)) {
- Log.v(TAG,
- "Focus mode not supported:" + (focusMode != null ? focusMode.name() : "null"));
- return false;
+ if (supports(FocusMode.FIXED)) {
+ // Workaround for devices whose templates define defaults they don't really support
+ // TODO: Remove workaround (b/17177436)
+ Log.w(TAG, "Focus mode not supported... trying FIXED");
+ settings.setFocusMode(FocusMode.FIXED);
+ } else {
+ Log.v(TAG, "Focus mode not supported:" +
+ (focusMode != null ? focusMode.name() : "null"));
+ return false;
+ }
}
return true;
}
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/CameraSettings.java b/camera2/portability/src/com/android/ex/camera2/portability/CameraSettings.java
index 26d0f85..87e9adf 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/CameraSettings.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/CameraSettings.java
@@ -38,6 +38,7 @@
protected final Map<String, String> mGeneralSetting = new TreeMap<>();
protected final List<Camera.Area> mMeteringAreas = new ArrayList<>();
protected final List<Camera.Area> mFocusAreas = new ArrayList<>();
+ protected boolean mSizesLocked;
protected int mPreviewFpsRangeMin;
protected int mPreviewFpsRangeMax;
protected int mPreviewFrameRate;
@@ -47,7 +48,6 @@
protected byte mJpegCompressQuality;
protected int mCurrentPhotoFormat;
protected float mCurrentZoomRatio;
- protected int mCurrentZoomIndex;
protected int mExposureCompensationIndex;
protected CameraCapabilities.FlashMode mCurrentFlashMode;
protected CameraCapabilities.FocusMode mCurrentFocusMode;
@@ -73,9 +73,20 @@
public final long timeStamp;
public final String processingMethod;
- /** Constructor. */
+ /**
+ * Construct what may or may not actually represent a location,
+ * depending on the value of {@code processingMethod}.
+ *
+ * <p>Setting {@code processingMethod} to {@code null} means that
+ * {@code latitude}, {@code longitude}, and {@code altitude} will be
+ * completely ignored.</p>
+ */
public GpsData(double latitude, double longitude, double altitude, long timeStamp,
String processingMethod) {
+ if (processingMethod == null &&
+ (latitude != 0.0 || longitude != 0.0 || altitude != 0.0)) {
+ Log.w(TAG, "GpsData's nonzero data will be ignored due to null processingMethod");
+ }
this.latitude = latitude;
this.longitude = longitude;
this.altitude = altitude;
@@ -106,6 +117,7 @@
mGeneralSetting.putAll(src.mGeneralSetting);
mMeteringAreas.addAll(src.mMeteringAreas);
mFocusAreas.addAll(src.mFocusAreas);
+ mSizesLocked = src.mSizesLocked;
mPreviewFpsRangeMin = src.mPreviewFpsRangeMin;
mPreviewFpsRangeMax = src.mPreviewFpsRangeMax;
mPreviewFrameRate = src.mPreviewFrameRate;
@@ -117,7 +129,6 @@
mJpegCompressQuality = src.mJpegCompressQuality;
mCurrentPhotoFormat = src.mCurrentPhotoFormat;
mCurrentZoomRatio = src.mCurrentZoomRatio;
- mCurrentZoomIndex = src.mCurrentZoomIndex;
mExposureCompensationIndex = src.mExposureCompensationIndex;
mCurrentFlashMode = src.mCurrentFlashMode;
mCurrentFocusMode = src.mCurrentFocusMode;
@@ -142,6 +153,19 @@
mGeneralSetting.put(key, value);
}
+ /**
+ * Changes whether classes outside this class are allowed to set the preview
+ * and photo capture sizes.
+ *
+ * @param locked Whether to prevent changes to these fields.
+ *
+ * @see #setPhotoSize
+ * @see #setPreviewSize
+ */
+ /*package*/ void setSizesLocked(boolean locked) {
+ mSizesLocked = locked;
+ }
+
/** Preview **/
/**
@@ -203,9 +227,16 @@
/**
* @param previewSize The size to use for preview.
+ * @return Whether the operation was allowed (i.e. the sizes are unlocked).
*/
- public void setPreviewSize(Size previewSize) {
+ public boolean setPreviewSize(Size previewSize) {
+ if (mSizesLocked) {
+ Log.w(TAG, "Attempt to change preview size while locked");
+ return false;
+ }
+
mCurrentPreviewSize = new Size(previewSize);
+ return true;
}
/**
@@ -236,12 +267,17 @@
}
/**
- * Sets the size for the photo.
- *
- * @param photoSize The photo size.
+ * @param photoSize The size to use for preview.
+ * @return Whether the operation was allowed (i.e. the sizes are unlocked).
*/
- public void setPhotoSize(Size photoSize) {
+ public boolean setPhotoSize(Size photoSize) {
+ if (mSizesLocked) {
+ Log.w(TAG, "Attempt to change photo size while locked");
+ return false;
+ }
+
mCurrentPhotoSize = new Size(photoSize);
+ return true;
}
/**
@@ -301,16 +337,6 @@
mCurrentZoomRatio = ratio;
}
- @Deprecated
- public int getCurrentZoomIndex() {
- return mCurrentZoomIndex;
- }
-
- @Deprecated
- public void setZoomIndex(int index) {
- mCurrentZoomIndex = index;
- }
-
/** Exposure **/
public void setExposureCompensationIndex(int index) {
@@ -332,6 +358,14 @@
return mAutoExposureLocked;
}
+ /**
+ * @param areas The areas for autoexposure. The coordinate system has domain
+ * and range [-1000,1000], measured relative to the visible
+ * preview image, with orientation matching that of the sensor.
+ * This means the coordinates must be transformed to account
+ * for the devices rotation---but not the zoom level---before
+ * being passed into this method.
+ */
public void setMeteringAreas(List<Camera.Area> areas) {
mMeteringAreas.clear();
if (areas != null) {
@@ -371,7 +405,12 @@
}
/**
- * @param areas The areas to focus.
+ * @param areas The areas to focus. The coordinate system has domain and
+ * range [-1000,1000], measured relative to the visible preview
+ * image, with orientation matching that of the sensor. This
+ * means the coordinates must be transformed to account for
+ * the devices rotation---but not the zoom level---before being
+ * passed into this method.
*/
public void setFocusAreas(List<Camera.Area> areas) {
mFocusAreas.clear();
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/LegacyVendorTags.java b/camera2/portability/src/com/android/ex/camera2/portability/LegacyVendorTags.java
new file mode 100644
index 0000000..7eb5c33
--- /dev/null
+++ b/camera2/portability/src/com/android/ex/camera2/portability/LegacyVendorTags.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ex.camera2.portability;
+
+import android.hardware.camera2.CameraCharacteristics;
+import android.util.Log;
+
+import java.lang.ExceptionInInitializerError;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+/**
+ * Vendor tag declarations for the Legacy Camera2 API implementation.
+ */
+public class LegacyVendorTags {
+
+ private static final String TAG = "LegacyVendorTags";
+
+ /**
+ * Hidden enum for scene modes supported only by the Camera1 API.
+ */
+ public static final int CONTROL_SCENE_MODE_HDR;
+
+ static {
+ int tempSceneMode = -1;
+ try {
+ tempSceneMode =
+ Class.forName("android.hardware.camera2.CameraCharacteristics").
+ getField("CONTROL_SCENE_MODE_HDR").getInt(null);
+ } catch (Exception e) {
+ Log.e(TAG, "Error while reflecting on SCENE_MODE_HDR enum, HDR will not be available: "
+ + e);
+ } finally {
+ CONTROL_SCENE_MODE_HDR = tempSceneMode;
+ }
+ }
+
+ private LegacyVendorTags() {
+ throw new AssertionError();
+ }
+}
\ No newline at end of file
diff --git a/camera2/portability/tests/src/com/android/ex/camera2/portability/Camera2PortabilityTest.java b/camera2/portability/tests/src/com/android/ex/camera2/portability/Camera2PortabilityTest.java
index 034fac7..1f340fd 100644
--- a/camera2/portability/tests/src/com/android/ex/camera2/portability/Camera2PortabilityTest.java
+++ b/camera2/portability/tests/src/com/android/ex/camera2/portability/Camera2PortabilityTest.java
@@ -21,6 +21,7 @@
import static org.junit.Assert.fail;
import android.content.Context;
+import android.graphics.Rect;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
@@ -40,6 +41,11 @@
import java.lang.reflect.ParameterizedType;
public class Camera2PortabilityTest extends Camera2DeviceTester {
+ /**
+ * Ensure that applying {@code Stringifier#.*FromString()} reverses
+ * {@link Stringifier#stringify} for {@link FocusMode}, {@link FlashMode},
+ * {@link SceneMode}, and {@link WhiteBalance}.
+ */
@Test
public void cameraCapabilitiesStringifier() {
Stringifier strfy = new Stringifier();
@@ -57,6 +63,11 @@
}
}
+ /**
+ * Ensure that {@code Stringifier#.*FromString()} default to the correct
+ * {@link FocusMode}, {@link FlashMode}, {@link SceneMode}, and
+ * {@link WhiteBalance} when given a {@code null}.
+ */
@Test
public void cameraCapabilitiesStringifierNull() {
Stringifier strfy = new Stringifier();
@@ -66,6 +77,11 @@
assertEquals(strfy.whiteBalanceFromString(null), WhiteBalance.AUTO);
}
+ /**
+ * Ensure that {@code Stringifier#.*FromString()} default to the correct
+ * {@link FocusMode}, {@link FlashMode}, {@link SceneMode}, and
+ * {@link WhiteBalance} when given an unrecognized string.
+ */
@Test
public void cameraCapabilitiesStringifierInvalid() {
Stringifier strfy = new Stringifier();
@@ -86,10 +102,19 @@
assertEquals(apiVal, setts.getRequestSettings().get(apiKey));
}
+ /**
+ * Ensure that {@link AndroidCamera2Settings} correctly translates its
+ * {@code FocusMode}, {@code SceneMode}, and {@code WhiteBalance} to the
+ * corresponding framework API 2 representations.
+ */
@Test
public void camera2SettingsSetOptionsAndGetRequestSettings() throws CameraAccessException {
+ // We're only testing the focus modes, scene modes and white balances,
+ // and won't use the activeArray, previewSize, or photoSize. The
+ // constructor requires the former, so pass a degenerate rectangle.
AndroidCamera2Settings set = new AndroidCamera2Settings(
- mCamera, CameraDevice.TEMPLATE_PREVIEW, null, null, null);
+ mCamera, CameraDevice.TEMPLATE_PREVIEW, /*activeArray*/new Rect(),
+ /*previewSize*/null, /*photoSize*/null);
// Focus modes
set.setFocusMode(FocusMode.AUTO);
@@ -158,6 +183,11 @@
// TODO: Add a test checking whether stringification matches API 1 representation
+ /**
+ * Ensure that {@code AndroidCamera2Capabilities#.*FromInt} correctly
+ * translates from framework API 2 representations to the equivalent
+ * {@code FocusMode}s, {@code SceneMode}s, and {@code WhiteBalance}s.
+ */
@Test
public void camera2CapabilitiesFocusModeFromInt() throws CameraAccessException {
CameraCharacteristics chars = buildFrameworkCharacteristics();
diff --git a/camera2/public/src/com/android/ex/camera2/blocking/BlockingCameraManager.java b/camera2/public/src/com/android/ex/camera2/blocking/BlockingCameraManager.java
index 02dbbba..407a08a 100644
--- a/camera2/public/src/com/android/ex/camera2/blocking/BlockingCameraManager.java
+++ b/camera2/public/src/com/android/ex/camera2/blocking/BlockingCameraManager.java
@@ -66,7 +66,7 @@
/**
* Returns the error code {@link ERROR_DISCONNECTED} if disconnected, or one of
- * {@code CameraDevice.StateListener#ERROR_*} if there was another error.
+ * {@code CameraDevice.StateCallback#ERROR_*} if there was another error.
*
* @return int Disconnect/error code
*/
@@ -81,7 +81,7 @@
* @param errorCode
* @param message
*
- * @see {@link CameraDevice.StateListener#ERROR_CAMERA_DEVICE}
+ * @see {@link CameraDevice.StateCallback#ERROR_CAMERA_DEVICE}
*/
public BlockingOpenException(int errorCode, String message) {
super(message);
@@ -117,8 +117,8 @@
* does.</p>
*
* <p>Throws {@link BlockingOpenException} when the open fails asynchronously (due to
- * {@link CameraDevice.StateListener#onDisconnected(CameraDevice)} or
- * ({@link CameraDevice.StateListener#onError(CameraDevice)}.</p>
+ * {@link CameraDevice.StateCallback#onDisconnected(CameraDevice)} or
+ * ({@link CameraDevice.StateCallback#onError(CameraDevice)}.</p>
*
* <p>Throws {@link TimeoutRuntimeException} if opening times out. This is usually
* highly unrecoverable, and all future calls to opening that camera will fail since the
@@ -142,7 +142,7 @@
* @throws TimeoutRuntimeException
* If opening times out. Typically unrecoverable.
*/
- public CameraDevice openCamera(String cameraId, CameraDevice.StateListener listener,
+ public CameraDevice openCamera(String cameraId, CameraDevice.StateCallback listener,
Handler handler) throws CameraAccessException, BlockingOpenException {
if (handler == null) {
@@ -163,17 +163,17 @@
/**
* Block until CameraManager#openCamera finishes with onOpened/onError/onDisconnected
*
- * <p>Pass-through all StateListener changes to the proxy.</p>
+ * <p>Pass-through all StateCallback changes to the proxy.</p>
*
* <p>Time out after {@link #OPEN_TIME_OUT} and unblock. Clean up camera if it arrives
* later.</p>
*/
- private class OpenListener extends CameraDevice.StateListener {
+ private class OpenListener extends CameraDevice.StateCallback {
private static final int ERROR_UNINITIALIZED = -1;
private final String mCameraId;
- private final CameraDevice.StateListener mProxy;
+ private final CameraDevice.StateCallback mProxy;
private final Object mLock = new Object();
private final ConditionVariable mDeviceReady = new ConditionVariable();
@@ -187,7 +187,7 @@
private boolean mTimedOut = false;
OpenListener(CameraManager manager, String cameraId,
- CameraDevice.StateListener listener, Handler handler)
+ CameraDevice.StateCallback listener, Handler handler)
throws CameraAccessException {
mCameraId = cameraId;
mProxy = listener;
diff --git a/camera2/public/src/com/android/ex/camera2/blocking/BlockingCaptureListener.java b/camera2/public/src/com/android/ex/camera2/blocking/BlockingCaptureCallback.java
similarity index 93%
rename from camera2/public/src/com/android/ex/camera2/blocking/BlockingCaptureListener.java
rename to camera2/public/src/com/android/ex/camera2/blocking/BlockingCaptureCallback.java
index eae85d1..4fb2c43 100644
--- a/camera2/public/src/com/android/ex/camera2/blocking/BlockingCaptureListener.java
+++ b/camera2/public/src/com/android/ex/camera2/blocking/BlockingCaptureCallback.java
@@ -36,7 +36,7 @@
*
* @see #getStateWaiter
*/
-public class BlockingCaptureListener extends CameraCaptureSession.CaptureListener {
+public class BlockingCaptureCallback extends CameraCaptureSession.CaptureCallback {
/**
* {@link #onCaptureStarted} has been called.
@@ -80,10 +80,10 @@
"CAPTURE_SEQUENCE_ABORTED"
};
- private static final String TAG = "BlockingCaptureListener";
+ private static final String TAG = "BlockingCaptureCallback";
private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
- private final CameraCaptureSession.CaptureListener mProxy;
+ private final CameraCaptureSession.CaptureCallback mProxy;
private final StateWaiter mStateWaiter = new StateWaiter(sStateNames);
private final StateChangeListener mStateChangeListener = mStateWaiter.getListener();
@@ -92,7 +92,7 @@
* Create a blocking capture listener without forwarding the capture listener invocations
* to another capture listener.
*/
- public BlockingCaptureListener() {
+ public BlockingCaptureCallback() {
mProxy = null;
}
@@ -104,7 +104,7 @@
*
* @throws NullPointerException if {@code listener} was {@code null}
*/
- public BlockingCaptureListener(CameraCaptureSession.CaptureListener listener) {
+ public BlockingCaptureCallback(CameraCaptureSession.CaptureCallback listener) {
if (listener == null) {
throw new NullPointerException("listener must not be null");
}
diff --git a/camera2/public/src/com/android/ex/camera2/blocking/BlockingSessionListener.java b/camera2/public/src/com/android/ex/camera2/blocking/BlockingSessionCallback.java
similarity index 93%
rename from camera2/public/src/com/android/ex/camera2/blocking/BlockingSessionListener.java
rename to camera2/public/src/com/android/ex/camera2/blocking/BlockingSessionCallback.java
index 26bb652..e041d27 100644
--- a/camera2/public/src/com/android/ex/camera2/blocking/BlockingSessionListener.java
+++ b/camera2/public/src/com/android/ex/camera2/blocking/BlockingSessionCallback.java
@@ -36,11 +36,11 @@
* <p>Provides a waiter that can be used to block until the next unobserved state of the
* requested type arrives.</p>
*
- * <p>Pass-through all StateListener changes to the proxy.</p>
+ * <p>Pass-through all StateCallback changes to the proxy.</p>
*
* @see #getStateWaiter
*/
-public class BlockingSessionListener extends CameraCaptureSession.StateListener {
+public class BlockingSessionCallback extends CameraCaptureSession.StateCallback {
/**
* Session is configured, ready for captures
*/
@@ -71,10 +71,10 @@
/*
* Private fields
*/
- private static final String TAG = "BlockingSessionListener";
+ private static final String TAG = "BlockingSessionCallback";
private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
- private final CameraCaptureSession.StateListener mProxy;
+ private final CameraCaptureSession.StateCallback mProxy;
private final SessionFuture mSessionFuture = new SessionFuture();
private final StateWaiter mStateWaiter = new StateWaiter(sStateNames);
@@ -92,7 +92,7 @@
* Create a blocking session listener without forwarding the session listener invocations
* to another session listener.
*/
- public BlockingSessionListener() {
+ public BlockingSessionCallback() {
mProxy = null;
}
@@ -104,7 +104,7 @@
*
* @throws NullPointerException if {@code listener} was {@code null}
*/
- public BlockingSessionListener(CameraCaptureSession.StateListener listener) {
+ public BlockingSessionCallback(CameraCaptureSession.StateCallback listener) {
if (listener == null) {
throw new NullPointerException("listener must not be null");
}
@@ -142,7 +142,7 @@
}
/*
- * CameraCaptureSession.StateListener implementation
+ * CameraCaptureSession.StateCallback implementation
*/
@Override
diff --git a/camera2/public/src/com/android/ex/camera2/blocking/BlockingStateListener.java b/camera2/public/src/com/android/ex/camera2/blocking/BlockingStateCallback.java
similarity index 94%
rename from camera2/public/src/com/android/ex/camera2/blocking/BlockingStateListener.java
rename to camera2/public/src/com/android/ex/camera2/blocking/BlockingStateCallback.java
index 02c2ba3..5f93fbc 100644
--- a/camera2/public/src/com/android/ex/camera2/blocking/BlockingStateListener.java
+++ b/camera2/public/src/com/android/ex/camera2/blocking/BlockingStateCallback.java
@@ -36,14 +36,14 @@
* the last wait, or that will be received from the camera device in the
* future.</p>
*
- * <p>Pass-through all StateListener changes to the proxy.</p>
+ * <p>Pass-through all StateCallback changes to the proxy.</p>
*
*/
-public class BlockingStateListener extends CameraDevice.StateListener {
- private static final String TAG = "BlockingStateListener";
+public class BlockingStateCallback extends CameraDevice.StateCallback {
+ private static final String TAG = "BlockingStateCallback";
private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
- private final CameraDevice.StateListener mProxy;
+ private final CameraDevice.StateCallback mProxy;
// Guards mWaiting
private final Object mLock = new Object();
@@ -99,11 +99,11 @@
*/
private static int NUM_STATES = 4;
- public BlockingStateListener() {
+ public BlockingStateCallback() {
mProxy = null;
}
- public BlockingStateListener(CameraDevice.StateListener listener) {
+ public BlockingStateCallback(CameraDevice.StateCallback listener) {
mProxy = listener;
}
diff --git a/camera2/public/src/com/android/ex/camera2/pos/AutoFocusStateMachine.java b/camera2/public/src/com/android/ex/camera2/pos/AutoFocusStateMachine.java
index 9fa2af2..e8a3ab6 100644
--- a/camera2/public/src/com/android/ex/camera2/pos/AutoFocusStateMachine.java
+++ b/camera2/public/src/com/android/ex/camera2/pos/AutoFocusStateMachine.java
@@ -91,7 +91,7 @@
/**
* Invoke every time we get a new CaptureResult via
- * {@link CameraDevice.CaptureListener#onCaptureCompleted}.
+ * {@link CameraDevice.CaptureCallback#onCaptureCompleted}.
*
* <p>This function is responsible for dispatching updates via the
* {@link AutoFocusStateListener} so without calling this on a regular basis, no
diff --git a/camera2/utils/src/com/android/ex/camera2/utils/Camera2CaptureListenerForwarder.java b/camera2/utils/src/com/android/ex/camera2/utils/Camera2CaptureCallbackForwarder.java
similarity index 90%
rename from camera2/utils/src/com/android/ex/camera2/utils/Camera2CaptureListenerForwarder.java
rename to camera2/utils/src/com/android/ex/camera2/utils/Camera2CaptureCallbackForwarder.java
index 35b1c6d..97b5b6e 100644
--- a/camera2/utils/src/com/android/ex/camera2/utils/Camera2CaptureListenerForwarder.java
+++ b/camera2/utils/src/com/android/ex/camera2/utils/Camera2CaptureCallbackForwarder.java
@@ -17,7 +17,7 @@
package com.android.ex.camera2.utils;
import android.hardware.camera2.CameraCaptureSession;
-import android.hardware.camera2.CameraCaptureSession.CaptureListener;
+import android.hardware.camera2.CameraCaptureSession.CaptureCallback;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
@@ -25,14 +25,14 @@
import android.os.Handler;
/**
- * Proxy that forwards all updates to another {@link CaptureListener}, invoking
+ * Proxy that forwards all updates to another {@link CaptureCallback}, invoking
* its callbacks on a separate {@link Handler}.
*/
-public class Camera2CaptureListenerForwarder extends CaptureListener {
- private CaptureListener mListener;
+public class Camera2CaptureCallbackForwarder extends CaptureCallback {
+ private CaptureCallback mListener;
private Handler mHandler;
- public Camera2CaptureListenerForwarder(CaptureListener listener, Handler handler) {
+ public Camera2CaptureCallbackForwarder(CaptureCallback listener, Handler handler) {
mListener = listener;
mHandler = handler;
}
diff --git a/camera2/utils/src/com/android/ex/camera2/utils/Camera2CaptureListenerSplitter.java b/camera2/utils/src/com/android/ex/camera2/utils/Camera2CaptureCallbackSplitter.java
similarity index 79%
rename from camera2/utils/src/com/android/ex/camera2/utils/Camera2CaptureListenerSplitter.java
rename to camera2/utils/src/com/android/ex/camera2/utils/Camera2CaptureCallbackSplitter.java
index a13dc04..f813076 100644
--- a/camera2/utils/src/com/android/ex/camera2/utils/Camera2CaptureListenerSplitter.java
+++ b/camera2/utils/src/com/android/ex/camera2/utils/Camera2CaptureCallbackSplitter.java
@@ -17,7 +17,7 @@
package com.android.ex.camera2.utils;
import android.hardware.camera2.CameraCaptureSession;
-import android.hardware.camera2.CameraCaptureSession.CaptureListener;
+import android.hardware.camera2.CameraCaptureSession.CaptureCallback;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
@@ -28,18 +28,18 @@
import java.util.List;
/**
- * Junction that allows notifying multiple {@link CaptureListener}s whenever
+ * Junction that allows notifying multiple {@link CaptureCallback}s whenever
* the {@link CameraCaptureSession} posts a capture-related update.
*/
-public class Camera2CaptureListenerSplitter extends CaptureListener {
- private final List<CaptureListener> mRecipients = new LinkedList<>();
+public class Camera2CaptureCallbackSplitter extends CaptureCallback {
+ private final List<CaptureCallback> mRecipients = new LinkedList<>();
/**
* @param recipients The listeners to notify. Any {@code null} passed here
* will be completely ignored.
*/
- public Camera2CaptureListenerSplitter(CaptureListener... recipients) {
- for (CaptureListener listener : recipients) {
+ public Camera2CaptureCallbackSplitter(CaptureCallback... recipients) {
+ for (CaptureCallback listener : recipients) {
if (listener != null) {
mRecipients.add(listener);
}
@@ -49,7 +49,7 @@
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
TotalCaptureResult result) {
- for (CaptureListener target : mRecipients) {
+ for (CaptureCallback target : mRecipients) {
target.onCaptureCompleted(session, request, result);
}
}
@@ -57,7 +57,7 @@
@Override
public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request,
CaptureFailure failure) {
- for (CaptureListener target : mRecipients) {
+ for (CaptureCallback target : mRecipients) {
target.onCaptureFailed(session, request, failure);
}
}
@@ -65,14 +65,14 @@
@Override
public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request,
CaptureResult partialResult) {
- for (CaptureListener target : mRecipients) {
+ for (CaptureCallback target : mRecipients) {
target.onCaptureProgressed(session, request, partialResult);
}
}
@Override
public void onCaptureSequenceAborted(CameraCaptureSession session, int sequenceId) {
- for (CaptureListener target : mRecipients) {
+ for (CaptureCallback target : mRecipients) {
target.onCaptureSequenceAborted(session, sequenceId);
}
}
@@ -80,7 +80,7 @@
@Override
public void onCaptureSequenceCompleted(CameraCaptureSession session, int sequenceId,
long frameNumber) {
- for (CaptureListener target : mRecipients) {
+ for (CaptureCallback target : mRecipients) {
target.onCaptureSequenceCompleted(session, sequenceId, frameNumber);
}
}
@@ -88,7 +88,7 @@
@Override
public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request,
long timestamp) {
- for (CaptureListener target : mRecipients) {
+ for (CaptureCallback target : mRecipients) {
target.onCaptureStarted(session, request, timestamp);
}
}
diff --git a/camera2/utils/src/com/android/ex/camera2/utils/Camera2RequestSettingsSet.java b/camera2/utils/src/com/android/ex/camera2/utils/Camera2RequestSettingsSet.java
index fac8f1a..6e1d825 100644
--- a/camera2/utils/src/com/android/ex/camera2/utils/Camera2RequestSettingsSet.java
+++ b/camera2/utils/src/com/android/ex/camera2/utils/Camera2RequestSettingsSet.java
@@ -146,7 +146,7 @@
* to its default value or simply unset. While {@link #get} will return
* {@code null} in both these cases, this method will return {@code true}
* and {@code false}, respectively.</p>
-
+ *
* @param key Which setting to look for.
* @return Whether that setting has a value that will propagate with unions.
*
@@ -160,8 +160,23 @@
}
/**
+ * Check whether the value of the specified setting matches the given one.
+ *
+ * <p>This method uses the {@code T} type's {@code equals} method, but is
+ * {@code null}-tolerant.</p>
+ *
+ * @param key Which of this class's settings to check.
+ * @param value Value to test for equality against.
+ * @return Whether they are the same.
+ */
+ public <T> boolean matches(Key<T> key, T value) {
+ return Objects.equals(get(key), value);
+ }
+
+ /**
* Get this set of settings's revision identifier, which can be compared
* against cached past values to determine whether it has been modified.
+ *
* <p>Distinct revisions across the same object do not necessarily indicate
* that the object's key/value pairs have changed at all, but the same
* revision on the same object does imply that they've stayed the same.</p>
diff --git a/camera2/utils/tests/src/com/android/ex/camera2/utils/Camera2DeviceTester.java b/camera2/utils/tests/src/com/android/ex/camera2/utils/Camera2DeviceTester.java
index 4db6dfb..e8639ba 100644
--- a/camera2/utils/tests/src/com/android/ex/camera2/utils/Camera2DeviceTester.java
+++ b/camera2/utils/tests/src/com/android/ex/camera2/utils/Camera2DeviceTester.java
@@ -52,7 +52,7 @@
@InjectContext
public Context mContext;
- private class DeviceCapturer extends CameraDevice.StateListener {
+ private class DeviceCapturer extends CameraDevice.StateCallback {
private CameraDevice mCamera;
public CameraDevice captureCameraDevice() throws Exception {
diff --git a/camera2/utils/tests/src/com/android/ex/camera2/utils/Camera2UtilsTest.java b/camera2/utils/tests/src/com/android/ex/camera2/utils/Camera2UtilsTest.java
index bb23e37..3156cf7 100644
--- a/camera2/utils/tests/src/com/android/ex/camera2/utils/Camera2UtilsTest.java
+++ b/camera2/utils/tests/src/com/android/ex/camera2/utils/Camera2UtilsTest.java
@@ -23,7 +23,8 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
-import android.hardware.camera2.CameraCaptureSession.CaptureListener;
+import android.graphics.Rect;
+import android.hardware.camera2.CameraCaptureSession.CaptureCallback;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureRequest.Key;
@@ -32,65 +33,65 @@
import org.junit.Test;
public class Camera2UtilsTest extends Camera2DeviceTester {
- private void captureListenerSplitterAllCallbacksReceived(CaptureListener splitter,
- CaptureListener... terminals) {
+ private void captureListenerSplitterAllCallbacksReceived(CaptureCallback splitter,
+ CaptureCallback... terminals) {
splitter.onCaptureCompleted(null, null, null);
- for (CaptureListener each : terminals) {
+ for (CaptureCallback each : terminals) {
verify(each).onCaptureCompleted(null, null, null);
}
splitter.onCaptureFailed(null, null, null);
- for (CaptureListener each : terminals) {
+ for (CaptureCallback each : terminals) {
verify(each).onCaptureFailed(null, null, null);
}
splitter.onCaptureProgressed(null, null, null);
- for (CaptureListener each : terminals) {
+ for (CaptureCallback each : terminals) {
verify(each).onCaptureProgressed(null, null, null);
}
splitter.onCaptureSequenceAborted(null, 0);
- for (CaptureListener each : terminals) {
+ for (CaptureCallback each : terminals) {
verify(each).onCaptureSequenceAborted(null, 0);
}
splitter.onCaptureSequenceCompleted(null, 0, 0L);
- for (CaptureListener each : terminals) {
+ for (CaptureCallback each : terminals) {
verify(each).onCaptureSequenceCompleted(null, 0, 0L);
}
splitter.onCaptureStarted(null, null, 0L);
- for (CaptureListener each : terminals) {
+ for (CaptureCallback each : terminals) {
verify(each).onCaptureStarted(null, null, 0L);
}
}
@Test
public void captureListenerSplitter() {
- CaptureListener firstBackingListener = mock(CaptureListener.class);
- CaptureListener secondBackingListener = mock(CaptureListener.class);
+ CaptureCallback firstBackingListener = mock(CaptureCallback.class);
+ CaptureCallback secondBackingListener = mock(CaptureCallback.class);
captureListenerSplitterAllCallbacksReceived(
- new Camera2CaptureListenerSplitter(firstBackingListener, secondBackingListener),
+ new Camera2CaptureCallbackSplitter(firstBackingListener, secondBackingListener),
firstBackingListener, secondBackingListener);
}
@Test
public void captureListenerSplitterEmpty() {
- captureListenerSplitterAllCallbacksReceived(new Camera2CaptureListenerSplitter());
+ captureListenerSplitterAllCallbacksReceived(new Camera2CaptureCallbackSplitter());
}
@Test
public void captureListenerSplitterNoNpe() {
captureListenerSplitterAllCallbacksReceived(
- new Camera2CaptureListenerSplitter((CaptureListener) null));
+ new Camera2CaptureCallbackSplitter((CaptureCallback) null));
}
@Test
public void captureListenerSplitterMultipleNulls() {
captureListenerSplitterAllCallbacksReceived(
- new Camera2CaptureListenerSplitter(null, null, null));
+ new Camera2CaptureCallbackSplitter(null, null, null));
}
@Test
public void captureListenerSplitterValidAndNull() {
- CaptureListener onlyRealBackingListener = mock(CaptureListener.class);
+ CaptureCallback onlyRealBackingListener = mock(CaptureCallback.class);
captureListenerSplitterAllCallbacksReceived(
- new Camera2CaptureListenerSplitter(null, onlyRealBackingListener),
+ new Camera2CaptureCallbackSplitter(null, onlyRealBackingListener),
onlyRealBackingListener);
}
@@ -234,22 +235,61 @@
setUp.get(null);
}
+ @Test
+ public void requestSettingsSetMatchesPrimitives() {
+ Camera2RequestSettingsSet setUp = new Camera2RequestSettingsSet();
+ assertTrue(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, null));
+ assertFalse(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, false));
+ assertFalse(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, true));
+
+ setUp.set(CaptureRequest.CONTROL_AE_LOCK, null);
+ assertTrue(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, null));
+ assertFalse(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, false));
+ assertFalse(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, true));
+
+ setUp.set(CaptureRequest.CONTROL_AE_LOCK, false);
+ assertFalse(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, null));
+ assertTrue(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, false));
+ assertFalse(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, true));
+
+ setUp.set(CaptureRequest.CONTROL_AE_LOCK, true);
+ assertFalse(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, null));
+ assertFalse(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, false));
+ assertTrue(setUp.matches(CaptureRequest.CONTROL_AE_LOCK, true));
+ }
+
+ @Test
+ public void requestSettingsSetMatchesReferences() {
+ Camera2RequestSettingsSet setUp = new Camera2RequestSettingsSet();
+ assertTrue(setUp.matches(CaptureRequest.SCALER_CROP_REGION, null));
+ assertFalse(setUp.matches(CaptureRequest.SCALER_CROP_REGION, new Rect(0, 0, 0, 0)));
+
+ setUp.set(CaptureRequest.SCALER_CROP_REGION, null);
+ assertTrue(setUp.matches(CaptureRequest.SCALER_CROP_REGION, null));
+ assertFalse(setUp.matches(CaptureRequest.SCALER_CROP_REGION, new Rect(0, 0, 0, 0)));
+
+ setUp.set(CaptureRequest.SCALER_CROP_REGION, new Rect(0, 0, 0, 0));
+ assertFalse(setUp.matches(CaptureRequest.SCALER_CROP_REGION, null));
+ assertTrue(setUp.matches(CaptureRequest.SCALER_CROP_REGION, new Rect(0, 0, 0, 0)));
+ assertFalse(setUp.matches(CaptureRequest.SCALER_CROP_REGION, new Rect(0, 0, 1, 1)));
+ }
+
@Test(expected=NullPointerException.class)
public void requestSettingsSetNullArgToCreateRequest0() throws Exception {
Camera2RequestSettingsSet setUp = new Camera2RequestSettingsSet();
- setUp.createRequest(null, 0);
+ setUp.createRequest(null, CameraDevice.TEMPLATE_PREVIEW);
}
@Test(expected=NullPointerException.class)
public void requestSettingsSetNullArgToCreateRequest2() throws Exception {
Camera2RequestSettingsSet setUp = new Camera2RequestSettingsSet();
- setUp.createRequest(mCamera, 0, (Surface) null);
+ setUp.createRequest(mCamera, CameraDevice.TEMPLATE_PREVIEW, (Surface) null);
}
@Test(expected=NullPointerException.class)
public void requestSettingsSetNullArgToCreateRequest02() throws Exception {
Camera2RequestSettingsSet setUp = new Camera2RequestSettingsSet();
- setUp.createRequest(null, 0, (Surface) null);
+ setUp.createRequest(null, CameraDevice.TEMPLATE_PREVIEW, (Surface) null);
}
@Test
diff --git a/carousel/Android.mk b/carousel/Android.mk
deleted file mode 100644
index 1f2592f..0000000
--- a/carousel/Android.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-# Note: the source code is in java/, not src/, because this code is also part of
-# the framework library, and build/core/pathmap.mk expects a java/ subdirectory.
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := android-common-carousel
-LOCAL_SRC_FILES := \
- $(call all-java-files-under, java) \
- $(call all-logtags-files-under, java) \
- $(call all-renderscript-files-under, java)
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/carousel/java/com/android/ex/carousel/CarouselController.java b/carousel/java/com/android/ex/carousel/CarouselController.java
deleted file mode 100644
index 8bb9c01..0000000
--- a/carousel/java/com/android/ex/carousel/CarouselController.java
+++ /dev/null
@@ -1,842 +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.
- */
-
-package com.android.ex.carousel;
-
-import com.android.ex.carousel.CarouselRS.CarouselCallback;
-import com.android.ex.carousel.CarouselView.DetailAlignment;
-
-import android.graphics.Bitmap;
-import android.renderscript.Float4;
-import android.renderscript.Mesh;
-import android.renderscript.RenderScriptGL;
-import android.util.Log;
-
-/**
- * <p>
- * This class represents the basic building block for using a 3D Carousel. The Carousel is
- * basically a scene of cards and slots. The spacing between cards is dictated by the number
- * of slots and the radius. The number of visible cards dictates how far the Carousel can be moved.
- * If the number of cards exceeds the number of slots, then the Carousel will continue to go
- * around until the last card can be seen.
- */
-public class CarouselController {
- private final int DEFAULT_SLOT_COUNT = 10;
- private final float DEFAULT_RADIUS = 20.0f;
- private final int DEFAULT_VISIBLE_DETAIL_COUNT = 3;
- private final int DEFAULT_PREFETCH_CARD_COUNT = 2;
- private final int DEFAULT_ROW_COUNT = 1;
- private final float DEFAULT_OVERSCROLL_SLOTS = 1.0f;
- private final float DEFAULT_ROW_SPACING = 0.0f;
- private final float DEFAULT_SWAY_SENSITIVITY = 0.0f;
- private final float DEFAULT_FRICTION_COEFFICIENT = 10.0f;
- private final float DEFAULT_DRAG_FACTOR = 0.25f;
- private final int DEFAULT_DETAIL_ALIGNMENT =
- DetailAlignment.VIEW_TOP | DetailAlignment.LEFT;
- private CarouselRS mRenderScript;
- private RenderScriptGL mRS;
- private static final String TAG = "CarouselController";
- private static final boolean DBG = false;
-
- // These shadow the state of the renderer in case the surface changes so the surface
- // can be restored to its previous state.
- private Bitmap mDefaultBitmap;
- private Bitmap mLoadingBitmap;
- private Bitmap mBackgroundBitmap;
- private Bitmap mDefaultLineBitmap = Bitmap.createBitmap(
- new int[] {0x00000000, 0xffffffff, 0x00000000}, 0, 3, 3, 1, Bitmap.Config.ARGB_4444);
- private int mDefaultGeometry;
- private int mLoadingGeometry;
- private float[] mDefaultCardMatrix;
- private int mCardCount = 0;
- private int mVisibleSlots = 0;
- private int mVisibleDetails = DEFAULT_VISIBLE_DETAIL_COUNT;
- private int mPrefetchCardCount = DEFAULT_PREFETCH_CARD_COUNT;
- private int mDetailTextureAlignment = DEFAULT_DETAIL_ALIGNMENT;
- private boolean mForceBlendCardsWithZ = false;
- private boolean mDrawRuler = true;
- private float mStartAngle;
- private float mCarouselRotationAngle;
- private float mRadius = DEFAULT_RADIUS;
- private float mCardRotation = 0.0f;
- private boolean mCardsFaceTangent = false;
- private float mOverscrollSlots = DEFAULT_OVERSCROLL_SLOTS;
- private float mSwaySensitivity = DEFAULT_SWAY_SENSITIVITY;
- private float mFrictionCoefficient = DEFAULT_FRICTION_COEFFICIENT;
- private float mDragFactor = DEFAULT_DRAG_FACTOR;
- private int mSlotCount = DEFAULT_SLOT_COUNT;
- private int mRowCount = DEFAULT_ROW_COUNT;
- private float mRowSpacing = DEFAULT_ROW_SPACING;
- private float mEye[] = { 20.6829f, 2.77081f, 16.7314f };
- private float mAt[] = { 14.7255f, -3.40001f, -1.30184f };
- private float mUp[] = { 0.0f, 1.0f, 0.0f };
- private Float4 mBackgroundColor = new Float4(0.0f, 0.0f, 0.0f, 1.0f);
- private CarouselCallback mCarouselCallback;
- private float mRezInCardCount = 0.0f;
- private long mFadeInDuration = 250L;
- private long mCardCreationFadeDuration = 0L;
- private Bitmap mDetailLoadingBitmap = Bitmap.createBitmap(
- new int[] {0}, 0, 1, 1, 1, Bitmap.Config.ARGB_4444);
- private int mDragModel = CarouselRS.DRAG_MODEL_SCREEN_DELTA;
- private int mFillDirection = CarouselRS.FILL_DIRECTION_CCW;
- private boolean mFirstCardTop = false;
- private int[] mStoreConfigs;
-
- public CarouselController() {
- boolean useDepthBuffer = true;
- }
-
- public void setRS(RenderScriptGL rs, CarouselRS renderScript) {
- mRS = rs;
- mRenderScript = renderScript;
- }
-
- public void onSurfaceChanged() {
- setSlotCount(mSlotCount);
- setDefaultCardMatrix(mDefaultCardMatrix);
- createCards(mCardCount);
- setVisibleSlots(mVisibleSlots);
- setVisibleDetails(mVisibleDetails);
- setPrefetchCardCount(mPrefetchCardCount);
- setOverscrollSlots(mOverscrollSlots);
- setRowCount(mRowCount);
- setRowSpacing(mRowSpacing);
- setFirstCardTop(mFirstCardTop);
- setDetailTextureAlignment(mDetailTextureAlignment);
- setForceBlendCardsWithZ(mForceBlendCardsWithZ);
- setDrawRuler(mDrawRuler);
- setCallback(mCarouselCallback);
- setDefaultBitmap(mDefaultBitmap);
- setLoadingBitmap(mLoadingBitmap);
- setDefaultGeometry(mDefaultGeometry);
- setLoadingGeometry(mLoadingGeometry);
- setBackgroundColor(mBackgroundColor.x, mBackgroundColor.y, mBackgroundColor.z,
- mBackgroundColor.w);
- setBackgroundBitmap(mBackgroundBitmap);
- setDetailLineBitmap(mDefaultLineBitmap);
- setStartAngle(mStartAngle);
- setCarouselRotationAngle(mCarouselRotationAngle);
- setRadius(mRadius);
- setCardRotation(mCardRotation);
- setCardsFaceTangent(mCardsFaceTangent);
- setSwaySensitivity(mSwaySensitivity);
- setFrictionCoefficient(mFrictionCoefficient);
- setDragFactor(mDragFactor);
- setDragModel(mDragModel);
- setFillDirection(mFillDirection);
- setLookAt(mEye, mAt, mUp);
- setRezInCardCount(mRezInCardCount);
- setFadeInDuration(mFadeInDuration);
- setCardCreationFadeDuration(mCardCreationFadeDuration);
- setDetailLoadingBitmap(mDetailLoadingBitmap);
- setStoreConfigs(mStoreConfigs);
- }
-
- /**
- * Loads geometry from a resource id.
- *
- * @param resId
- * @return the loaded mesh or null if it cannot be loaded
- */
- public Mesh loadGeometry(int resId) {
- if (mRenderScript != null) {
- return mRenderScript.loadGeometry(resId);
- }
- return null;
- }
-
- /**
- * Set the geometry to show for a given slot.
- * @param n The card to set the geometry for
- * @param mesh The geometry for that item
- * @see {@link #setDefaultGeometry}
- */
- public void setGeometryForItem(int n, Mesh mesh) {
- if (mRenderScript != null) {
- mRenderScript.setGeometry(n, mesh);
- }
- }
-
- /**
- * Load A3D file from resource. If resId == 0, will clear geometry for this item.
- * @param n The card to set the geometry for
- * @param resId The resource ID for the geometry for that item
- * @see {@link #setDefaultGeometry}
- */
- public void setGeometryForItem(int n, int resId) {
- if (mRenderScript != null) {
- Mesh mesh = mRenderScript.loadGeometry(resId);
- mRenderScript.setGeometry(n, mesh);
- }
- }
-
- /**
- * Set the matrix for the specified card
- * @param n The card to set the matrix for
- * @param matrix The matrix to use
- * @see {@link #setDefaultGeometry}
- */
- public void setMatrixForItem(int n, float[] matrix) {
- if (mRenderScript != null) {
- mRenderScript.setMatrix(n, matrix);
- }
- }
-
- /**
- * Set the number of slots around the Carousel. Basically equivalent to the poles horses
- * might attach to on a real Carousel.
- *
- * @param n the number of slots
- */
- public void setSlotCount(int n) {
- mSlotCount = n;
- if (mRenderScript != null) {
- mRenderScript.setSlotCount(n);
- }
- }
-
- /**
- * Sets the number of visible slots around the Carousel. This is primarily used as a cheap
- * form of clipping. The Carousel will never show more than this many cards.
- * @param n the number of visible slots
- */
- public void setVisibleSlots(int n) {
- mVisibleSlots = n;
- if (mRenderScript != null) {
- mRenderScript.setVisibleSlots(n);
- }
- }
-
- /**
- * Set the number of detail textures that can be visible at one time.
- *
- * @param n the number of slots
- */
- public void setVisibleDetails(int n) {
- mVisibleDetails = n;
- if (mRenderScript != null) {
- mRenderScript.setVisibleDetails(n);
- }
- }
-
- /**
- * Set the number of cards to pre-load that are outside of the visible region, as determined by
- * setVisibleSlots(). This number gets added to the number of visible slots and used to
- * determine when resources for cards should be loaded. This number should be small (n <= 4)
- * for systems with limited texture memory or views that show more than half dozen cards in the
- * view.
- *
- * @param n the number of cards; should be even, so the count is the same on each side
- */
- public void setPrefetchCardCount(int n) {
- mPrefetchCardCount = n;
- if (mRenderScript != null) {
- mRenderScript.setPrefetchCardCount(n);
- }
- }
-
- /**
- * Sets the number of rows of cards to show in each slot.
- */
- public void setRowCount(int n) {
- mRowCount = n;
- if (mRenderScript != null) {
- mRenderScript.setRowCount(n);
- }
- }
-
- /**
- * Sets the spacing between each row of cards when rowCount > 1.
- */
- public void setRowSpacing(float s) {
- mRowSpacing = s;
- if (mRenderScript != null) {
- mRenderScript.setRowSpacing(s);
- }
- }
-
- /**
- * Sets the position of the first card when rowCount > 1 .
- */
- public void setFirstCardTop(boolean f) {
- mFirstCardTop = f;
- if (mRenderScript != null) {
- mRenderScript.setFirstCardTop(f);
- }
- }
-
- /**
- * Sets the amount of allowed overscroll (in slots)
- */
- public void setOverscrollSlots(float slots) {
- mOverscrollSlots = slots;
- if (mRenderScript != null) {
- mRenderScript.setOverscrollSlots(slots);
- }
- }
-
- /**
- * Sets how detail textures are aligned with respect to the card.
- *
- * @param alignment a bitmask of DetailAlignment flags.
- */
- public void setDetailTextureAlignment(int alignment) {
- int xBits = alignment & DetailAlignment.HORIZONTAL_ALIGNMENT_MASK;
- if (xBits == 0 || ((xBits & (xBits - 1)) != 0)) {
- throw new IllegalArgumentException(
- "Must specify exactly one horizontal alignment flag");
- }
- int yBits = alignment & DetailAlignment.VERTICAL_ALIGNMENT_MASK;
- if (yBits == 0 || ((yBits & (yBits - 1)) != 0)) {
- throw new IllegalArgumentException(
- "Must specify exactly one vertical alignment flag");
- }
-
- mDetailTextureAlignment = alignment;
- if (mRenderScript != null) {
- mRenderScript.setDetailTextureAlignment(alignment);
- }
- }
-
- /**
- * Set whether depth is enabled while blending. Generally, this is discouraged because
- * it causes bad artifacts. Careful attention to geometry and alpha transparency of
- * textures can mitigate much of this. Geometry for an individual item must be drawn
- * back-to-front, for example.
- *
- * @param enabled True to enable depth while blending, and false to disable it.
- */
- public void setForceBlendCardsWithZ(boolean enabled) {
- mForceBlendCardsWithZ = enabled;
- if (mRenderScript != null) {
- mRenderScript.setForceBlendCardsWithZ(enabled);
- }
- }
-
- /**
- * Set whether to draw a ruler from the card to the detail texture
- *
- * @param drawRuler True to draw a ruler, false to draw nothing where the ruler would go.
- */
- public void setDrawRuler(boolean drawRuler) {
- mDrawRuler = drawRuler;
- if (mRenderScript != null) {
- mRenderScript.setDrawRuler(drawRuler);
- }
- }
-
- /**
- * This dictates how many cards are in the deck. If the number of cards is greater than the
- * number of slots, then the Carousel goes around n / slot_count times.
- *
- * Can be called again to increase or decrease the number of cards.
- *
- * @param n the number of cards to create.
- */
- public void createCards(int n) {
- mCardCount = n;
- if (mRenderScript != null) {
- mRenderScript.createCards(n);
- }
- }
-
- public int getCardCount() {
- return mCardCount;
- }
-
- /**
- * This sets the texture on card n. It should only be called in response to
- * {@link CarouselCallback#onRequestTexture(int)}. Since there's no guarantee
- * that a given texture is still on the screen, replacing this texture should be done
- * by first setting it to null and then waiting for the next
- * {@link CarouselCallback#onRequestTexture(int)} to swap it with the new one.
- *
- * @param n the card given by {@link CarouselCallback#onRequestTexture(int)}
- * @param bitmap the bitmap image to show
- */
- public void setTextureForItem(int n, Bitmap bitmap) {
- // Also check against mRS, to handle the case where the result is being delivered by a
- // background thread but the sender no longer exists.
- if (mRenderScript != null && mRS != null) {
- if (DBG) Log.v(TAG, "setTextureForItem(" + n + ")");
- mRenderScript.setTexture(n, bitmap);
- if (DBG) Log.v(TAG, "done");
- }
- }
-
- /**
- * This sets the detail texture that floats above card n. It should only be called in response
- * to {@link CarouselCallback#onRequestDetailTexture(int)}. Since there's no guarantee
- * that a given texture is still on the screen, replacing this texture should be done
- * by first setting it to null and then waiting for the next
- * {@link CarouselCallback#onRequestDetailTexture(int)} to swap it with the new one.
- *
- * @param n the card to set detail texture for
- * @param offx an optional offset to apply to the texture (in pixels) from top of detail line
- * @param offy an optional offset to apply to the texture (in pixels) from top of detail line
- * @param loffx an optional offset to apply to the line (in pixels) from left edge of card
- * @param loffy an optional offset to apply to the line (in pixels) from top of screen
- * @param bitmap the bitmap to show as the detail
- */
- public void setDetailTextureForItem(int n, float offx, float offy, float loffx, float loffy,
- Bitmap bitmap) {
- if (mRenderScript != null && mRS != null) {
- if (DBG) Log.v(TAG, "setDetailTextureForItem(" + n + ")");
- mRenderScript.setDetailTexture(n, offx, offy, loffx, loffy, bitmap);
- if (DBG) Log.v(TAG, "done");
- }
- }
-
- /**
- * Sets the specified texture as invalid. If {@code eraseCurrent} is true,
- * the texture will be immediately cleared from view and an invalidate
- * handler will be called. If {@code eraseCurrent} is false, a replacement
- * texture will be requested, and the old texture will be left in place in
- * the meantime.
- *
- * @param n the card to invalidate the detail texture for
- * @param eraseCurrent whether to erase the current texture
- */
- public void invalidateTexture(int n, boolean eraseCurrent) {
- if (mRenderScript != null && mRS != null) {
- if (DBG) Log.v(TAG, "invalidateTexture(" + n + ", " + eraseCurrent + ")");
- mRenderScript.invalidateTexture(n, eraseCurrent);
- if (DBG) Log.v(TAG, "done");
- }
- }
-
- /**
- * Sets the specified detail texture as invalid. If eraseCurrent is true, the texture will be
- * immediately cleared from view and an invalidate handler will be called. If eraseCurrent is
- * false, a replacement texture will be requested, and the old texture will be left in place
- * in the meantime.
- * @param n the card to invalidate the detail texture for
- * @param eraseCurrent whether to erase the current texture
- */
- public void invalidateDetailTexture(int n, boolean eraseCurrent) {
- if (mRenderScript != null && mRS != null) {
- if (DBG) Log.v(TAG, "invalidateDetailTexture(" + n + ", " + eraseCurrent + ")");
- mRenderScript.invalidateDetailTexture(n, eraseCurrent);
- if (DBG) Log.v(TAG, "done");
- }
- }
-
- /**
- * Sets the bitmap to show on a card when the card draws the very first time.
- * Generally, this bitmap will only be seen during the first few frames of startup
- * or when the number of cards are changed. It can be ignored in most cases,
- * as the cards will generally only be in the loading or loaded state.
- *
- * @param bitmap
- */
- public void setDefaultBitmap(Bitmap bitmap) {
- mDefaultBitmap = bitmap;
- if (mRenderScript != null) {
- mRenderScript.setDefaultBitmap(bitmap);
- }
- }
-
- /**
- * Sets the bitmap to show on the card while the texture is loading. It is set to this
- * value just before {@link CarouselCallback#onRequestTexture(int)} is called and changed
- * when {@link CarouselView#setTextureForItem(int, Bitmap)} is called. It is shared by all
- * cards.
- *
- * @param bitmap
- */
- public void setLoadingBitmap(Bitmap bitmap) {
- mLoadingBitmap = bitmap;
- if (mRenderScript != null) {
- mRenderScript.setLoadingBitmap(bitmap);
- }
- }
-
- /**
- * Sets background to specified color. If a background texture is specified with
- * {@link CarouselView#setBackgroundBitmap(Bitmap)}, then this call has no effect.
- *
- * @param red the amount of red
- * @param green the amount of green
- * @param blue the amount of blue
- * @param alpha the amount of alpha
- */
- public void setBackgroundColor(float red, float green, float blue, float alpha) {
- mBackgroundColor = new Float4(red, green, blue, alpha);
- if (mRenderScript != null) {
- mRenderScript.setBackgroundColor(mBackgroundColor);
- }
- }
-
- /**
- * Can be used to optionally set the background to a bitmap. When set to something other than
- * null, this overrides {@link CarouselController#setBackgroundColor(Float4)}.
- *
- * @param bitmap
- */
- public void setBackgroundBitmap(Bitmap bitmap) {
- mBackgroundBitmap = bitmap;
- if (mRenderScript != null) {
- mRenderScript.setBackgroundTexture(bitmap);
- }
- }
-
- /**
- * Can be used to optionally set a "loading" detail bitmap. Typically, this is just a black
- * texture with alpha = 0 to allow details to slowly fade in.
- *
- * @param bitmap
- */
- public void setDetailLoadingBitmap(Bitmap bitmap) {
- mDetailLoadingBitmap = bitmap;
- if (mRenderScript != null) {
- mRenderScript.setDetailLoadingTexture(bitmap);
- }
- }
-
- /**
- * This texture is used to draw a line from the card alongside the texture detail. The line
- * will be as wide as the texture. It can be used to give the line glow effects as well as
- * allowing other blending effects. It is typically one dimensional, e.g. 3x1.
- *
- * @param bitmap
- */
- public void setDetailLineBitmap(Bitmap bitmap) {
- mDefaultLineBitmap = bitmap;
- if (mRenderScript != null) {
- mRenderScript.setDetailLineTexture(bitmap);
- }
- }
-
- /**
- * This geometry will be shown when no geometry has been loaded for a given slot. If not set,
- * a quad will be drawn in its place. It is shared for all cards. If something other than
- * simple planar geometry is used, consider enabling depth test with
- * {@link CarouselController#setForceBlendCardsWithZ(boolean)}
- *
- * @param mesh
- */
- public void setDefaultGeometry(int resId) {
- mDefaultGeometry = resId;
- if (mRenderScript != null) {
- Mesh mesh = mRenderScript.loadGeometry(resId);
- mRenderScript.setDefaultGeometry(mesh);
- }
- }
-
- /**
- * Sets the matrix used to transform card geometries. By default, this
- * is the identity matrix, but you can specify a different matrix if you
- * want to scale, translate and / or rotate the card before drawing.
- *
- * @param matrix array of 9 or 16 floats representing a 3x3 or 4x4 matrix,
- * or null as a shortcut for an identity matrix.
- */
- public void setDefaultCardMatrix(float[] matrix) {
- mDefaultCardMatrix = matrix;
- if (mRenderScript != null) {
- mRenderScript.setDefaultCardMatrix(matrix);
- }
- }
-
- /**
- * This is an intermediate version of the object to show while geometry is loading. If not set,
- * a quad will be drawn in its place. It is shared for all cards. If something other than
- * simple planar geometry is used, consider enabling depth test with
- * {@link CarouselView#setForceBlendCardsWithZ(boolean)}
- *
- * @param resId
- */
- public void setLoadingGeometry(int resId) {
- mLoadingGeometry = resId;
- if (mRenderScript != null) {
- Mesh mesh = mRenderScript.loadGeometry(resId);
- mRenderScript.setLoadingGeometry(mesh);
- }
- }
-
- /**
- * Sets the callback for receiving events from RenderScript.
- *
- * @param callback
- */
- public void setCallback(CarouselCallback callback)
- {
- mCarouselCallback = callback;
- if (mRenderScript != null) {
- mRenderScript.setCallback(callback);
- }
- }
-
- /**
- * Gets the callback for receiving events from Renderscript.
- */
- public CarouselCallback getCallback() {
- return mCarouselCallback;
- }
-
- /**
- * Sets the startAngle for the Carousel. The start angle is the first position of the first
- * slot draw. Cards will be drawn from this angle in a counter-clockwise manner around the
- * Carousel.
- *
- * @param angle the angle, in radians.
- */
- public void setStartAngle(float angle)
- {
- mStartAngle = angle;
- if (mRenderScript != null) {
- mRenderScript.setStartAngle(angle);
- }
- }
-
- /**
- * Set the current carousel rotation angle, in card units.
- * This is measured in card positions, not in radians or degrees.
- *
- * A value of 0.0 means that card 0 is in the home position.
- * A value of 1.0 means that card 1 is in the home position, and so on.
- * The maximum value will be somewhat less than the total number of cards.
- *
- * @param angle
- */
- public void setCarouselRotationAngle(float angle) {
- mCarouselRotationAngle = angle;
- if (mRenderScript != null) {
- mRenderScript.setCarouselRotationAngle(angle);
- }
- }
-
- /**
- * Triggers a rotation of the carousel. All angles are in card units, see:
- * {@link CarouselController#setCarouselRotationAngle(float)}) for more details.
- *
- * @param endAngle the card unit to which the carousel should rotate to
- * @param milliseconds the length of the animation
- * @param interpolationMode three modes are currently supported :
- * {@link CarouselView.InterpolationMode#LINEAR}
- * {@link CarouselView.InterpolationMode#DECELERATE_QUADRATIC}
- * {@link CarouselView.InterpolationMode#ACCELERATE_DECELERATE_CUBIC}
- * @param maxAnimatedArc the maximum angular distance over which the transition will be
- * animated.
- * If the current position is further away, it is set at maxAnimatedArc from endAngle.
- * This parameter is ignored when <= 0.
- */
- public void setCarouselRotationAngle(float endAngle, int milliseconds, int interpolationMode,
- float maxAnimatedArc) {
- if (mRenderScript != null) {
- mRenderScript.setCarouselRotationAngle(endAngle, milliseconds,
- interpolationMode, maxAnimatedArc);
- }
- }
-
- public void setRadius(float radius) {
- mRadius = radius;
- if (mRenderScript != null) {
- mRenderScript.setRadius(radius);
- }
- }
-
- /**
- * Sets the current model for dragging. There are currently four drag models:
- * {@link CarouselView#DRAG_MODEL_SCREEN_DELTA}
- * {@link CarouselView#DRAG_MODEL_PLANE}
- * {@link CarouselView#DRAG_MODEL_CYLINDER_INSIDE}
- * {@link CarouselView#DRAG_MODEL_CYLINDER_OUTSIDE}
- *
- * @param model
- */
- public void setDragModel(int model) {
- mDragModel = model;
- if (mRenderScript != null) {
- mRenderScript.setDragModel(model);
- }
- }
-
- /** Sets the direction to fill in cards around the carousel.
- *
- * @param direction Either {@link CarouselRS#FILL_DIRECTION_CCW} or
- * {@link CarouselRS#FILL_DIRECTION_CW}.
- */
- public void setFillDirection(int direction) {
- mFillDirection = direction;
- if (mRenderScript != null) {
- mRenderScript.setFillDirection(direction);
- }
- }
-
- public void setCardRotation(float cardRotation) {
- mCardRotation = cardRotation;
- if (mRenderScript != null) {
- mRenderScript.setCardRotation(cardRotation);
- }
- }
-
- public void setCardsFaceTangent(boolean faceTangent) {
- mCardsFaceTangent = faceTangent;
- if (mRenderScript != null) {
- mRenderScript.setCardsFaceTangent(faceTangent);
- }
- }
-
- public void setSwaySensitivity(float swaySensitivity) {
- mSwaySensitivity = swaySensitivity;
- if (mRenderScript != null) {
- mRenderScript.setSwaySensitivity(swaySensitivity);
- }
- }
-
- public void setFrictionCoefficient(float frictionCoefficient) {
- mFrictionCoefficient = frictionCoefficient;
- if (mRenderScript != null) {
- mRenderScript.setFrictionCoefficient(frictionCoefficient);
- }
- }
-
- public void setDragFactor(float dragFactor) {
- mDragFactor = dragFactor;
- if (mRenderScript != null) {
- mRenderScript.setDragFactor(dragFactor);
- }
- }
-
- public void setLookAt(float[] eye, float[] at, float[] up) {
- mEye = eye;
- mAt = at;
- mUp = up;
- if (mRenderScript != null) {
- mRenderScript.setLookAt(eye, at, up);
- }
- }
-
- /**
- * This sets the number of cards in the distance that will be shown "rezzing in".
- * These alpha values will be faded in from the background to the foreground over
- * 'n' cards. A floating point value is used to allow subtly changing the rezzing in
- * position.
- *
- * @param n the number of cards to rez in.
- */
- public void setRezInCardCount(float n) {
- mRezInCardCount = n;
- if (mRenderScript != null) {
- mRenderScript.setRezInCardCount(n);
- }
- }
-
- /**
- * This sets the duration (in ms) that a card takes to fade in when loaded via a call
- * to {@link CarouselView#setTextureForItem(int, Bitmap)}. The timer starts the
- * moment {@link CarouselView#setTextureForItem(int, Bitmap)} is called and continues
- * until all of the cards have faded in. Note: using large values will extend the
- * animation until all cards have faded in.
- *
- * @param t The time, in milliseconds
- */
- public void setFadeInDuration(long t) {
- mFadeInDuration = t;
- if (mRenderScript != null) {
- mRenderScript.setFadeInDuration(t);
- }
- }
-
- /**
- * This sets the duration (in ms) that a card takes to fade in when it is initially created,
- * such as when it is added or when the application starts. The timer starts at the moment
- * when the card is first created. Replacing a card's contents does not affect the timer.
- * @param t The time, in milliseconds
- */
- public void setCardCreationFadeDuration(long t) {
- mCardCreationFadeDuration = t;
- if (mRenderScript != null) {
- mRenderScript.setCardCreationFadeDuration(t);
- }
- }
-
- /**
- * Tells the carousel that a touch event has started at the designated location.
- * @param x The number of pixels from the left edge that the event occurred
- * @param y The number of pixels from the top edge that the event occurred
- * @param t The time stamp of the event
- */
- public void onTouchStarted(float x, float y, long t) {
- mRenderScript.doStart(x, y, t);
- }
-
- /**
- * Tells the carousel that a touch event has moved to the designated location.
- * @param x The number of pixels from the left edge that the event occurred
- * @param y The number of pixels from the top edge that the event occurred
- * @param t The time stamp of the event
- */
- public void onTouchMoved(float x, float y, long t) {
- mRenderScript.doMotion(x, y, t);
- }
-
- /**
- * Tells the carousel that the user has long-pressed.
- */
- public void onLongPress() {
- mRenderScript.doLongPress();
- }
-
- /**
- * Tells the carousel that a touch event has stopped at the designated location.
- * @param x The number of pixels from the left edge that the event occurred
- * @param y The number of pixels from the top edge that the event occurred
- * @param t The time stamp of the event
- */
- public void onTouchStopped(float x, float y, long t) {
- mRenderScript.doStop(x, y, t);
- }
-
- /**
- * Whether to use alpha when drawing a primitive: on for translucent, off for opaque.
- */
- public static final int STORE_CONFIG_ALPHA = 1;
-
- /**
- * Whether to read from the depth buffer when rendering. Determines with glDepthFunc()
- * is given GL_LESS or GL_ALWAYS. On for GL_LESS, off for GL_ALWAYS.
- */
- public static final int STORE_CONFIG_DEPTH_READS = 2;
-
- /**
- * Whether to write to the depth buffer when rendering. Passed to glDepthMask().
- */
- public static final int STORE_CONFIG_DEPTH_WRITES = 4;
-
- /**
- * Set the StoreConfig parameters that will be used for each mesh primitive.
- *
- * Each integer in the array is a bitfield composed of
- * {@link CarouselController#STORE_CONFIG_ALPHA},
- * {@link CarouselController#STORE_CONFIG_DEPTH_READS}, and
- * {@link CarouselController#STORE_CONFIG_DEPTH_WRITES}.
- *
- * These parameters MUST correspond to primitives in geometry previously set in
- * {@link CarouselController#setDefaultGeometry(int)} or
- * {@link CarouselController#setLoadingGeometry(int)} or
- * {@link CarouselController#setGeometryForItem(int,Mesh)}.
- *
- * @param configs An array, each element of which corresponds to an ordered mesh primitive
- */
- public void setStoreConfigs(int configs[]) {
- mStoreConfigs = configs;
- if (mRenderScript != null) {
- mRenderScript.setStoreConfigs(configs);
- }
- }
-}
diff --git a/carousel/java/com/android/ex/carousel/CarouselRS.java b/carousel/java/com/android/ex/carousel/CarouselRS.java
deleted file mode 100644
index 9d78d09..0000000
--- a/carousel/java/com/android/ex/carousel/CarouselRS.java
+++ /dev/null
@@ -1,949 +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.
- */
-
-package com.android.ex.carousel;
-
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Rect;
-import android.renderscript.*;
-import static android.renderscript.Element.*;
-import android.renderscript.Program.TextureType;
-import android.renderscript.RenderScript.RSMessageHandler;
-import android.util.Log;
-
-/**
- * This is a support class for Carousel renderscript. It handles most of the low-level interactions
- * with Renderscript as well as dispatching events.
- *
- */
-public class CarouselRS {
- private static final int DEFAULT_VISIBLE_SLOTS = 1;
- private static final int DEFAULT_CARD_COUNT = 0;
- private static final int DEFAULT_ROW_COUNT = 1;
-
- // Client messages *** THIS LIST MUST MATCH THOSE IN carousel.rs ***
- public static final int CMD_CARD_SELECTED = 100;
- public static final int CMD_DETAIL_SELECTED = 105;
- public static final int CMD_CARD_LONGPRESS = 110;
- public static final int CMD_REQUEST_TEXTURE = 200;
- public static final int CMD_INVALIDATE_TEXTURE = 210;
- public static final int CMD_REQUEST_GEOMETRY = 300;
- public static final int CMD_INVALIDATE_GEOMETRY = 310;
- public static final int CMD_ANIMATION_STARTED = 400;
- public static final int CMD_ANIMATION_FINISHED = 500;
- public static final int CMD_REQUEST_DETAIL_TEXTURE = 600;
- public static final int CMD_INVALIDATE_DETAIL_TEXTURE = 610;
- public static final int CMD_PING = 1000; // for debugging
-
- // Drag models *** THIS LIST MUST MATCH THOSE IN carousel.rs ***
- public static final int DRAG_MODEL_SCREEN_DELTA = 0;
- public static final int DRAG_MODEL_PLANE = 1;
- public static final int DRAG_MODEL_CYLINDER_INSIDE = 2;
- public static final int DRAG_MODEL_CYLINDER_OUTSIDE = 3;
-
- public static final int FILL_DIRECTION_CCW = +1;
- public static final int FILL_DIRECTION_CW = -1;
-
- private static final String TAG = "CarouselRS";
- private static final int DEFAULT_SLOT_COUNT = 10;
- private static final Allocation.MipmapControl MIPMAP =
- Allocation.MipmapControl.MIPMAP_NONE;
- private static final boolean DBG = false;
-
- private RenderScriptGL mRS;
- private Resources mRes;
- private ScriptC_carousel mScript;
- private ScriptField_Card mCards;
- private ScriptField_FragmentShaderConstants_s mFSConst;
- private ScriptField_ProgramStore_s mProgramStoresCard;
- private ProgramFragment mSingleTextureFragmentProgram;
- private ProgramFragment mSingleTextureBlendingFragmentProgram;
- private ProgramFragment mMultiTextureFragmentProgram;
- private ProgramFragment mMultiTextureBlendingFragmentProgram;
- private ProgramVertex mVertexProgram;
- private ProgramRaster mRasterProgram;
- private Allocation[] mAllocationPool;
- private boolean mForceBlendCardsWithZ;
- private int mVisibleSlots;
- private int mRowCount;
- private int mPrefetchCardCount;
- private CarouselCallback mCallback;
- private float[] mEyePoint = new float[] { 2.0f, 0.0f, 0.0f };
- private float[] mAtPoint = new float[] { 0.0f, 0.0f, 0.0f };
- private float[] mUp = new float[] { 0.0f, 1.0f, 0.0f };
-
- private static final String mSingleTextureShader = new String(
- "varying vec2 varTex0;" +
- "void main() {" +
- "vec2 t0 = varTex0.xy;" +
- "vec4 col = texture2D(UNI_Tex0, t0);" +
- "gl_FragColor = col; " +
- "}");
-
- private static final String mSingleTextureBlendingShader = new String(
- "varying vec2 varTex0;" +
- "void main() {" +
- "vec2 t0 = varTex0.xy;" +
- "vec4 col = texture2D(UNI_Tex0, t0);" +
- "gl_FragColor = col * UNI_overallAlpha; " +
- "}");
-
- private static final String mMultiTextureShader = new String(
- "varying vec2 varTex0;" +
- "void main() {" +
- "vec2 t0 = varTex0.xy;" +
- "vec4 col = texture2D(UNI_Tex0, t0);" +
- "vec4 col2 = texture2D(UNI_Tex1, t0);" +
- "gl_FragColor = mix(col, col2, UNI_fadeAmount);}");
-
- private static final String mMultiTextureBlendingShader = new String(
- "varying vec2 varTex0;" +
- "void main() {" +
- "vec2 t0 = varTex0.xy;" +
- "vec4 col = texture2D(UNI_Tex0, t0);" +
- "vec4 col2 = texture2D(UNI_Tex1, t0);" +
- "gl_FragColor = mix(col, col2, UNI_fadeAmount) * UNI_overallAlpha;" +
- "}"
- );
-
- public static interface CarouselCallback {
- /**
- * Called when a card is selected
- * @param n the id of the card
- */
- void onCardSelected(int n);
-
- /**
- * Called when the detail texture for a card is tapped
- * @param n the id of the card
- * @param x how far the user tapped from the left edge of the card, in pixels
- * @param y how far the user tapped from the top edge of the card, in pixels
- */
- void onDetailSelected(int n, int x, int y);
-
- /**
- * Called when a card is long-pressed
- * @param n the id of the card
- * @param touchPosition position of where the user pressed, in screen coordinates
- * @param detailCoordinates position of detail texture, in screen coordinates
- */
- void onCardLongPress(int n, int touchPosition[], Rect detailCoordinates);
-
- /**
- * Called when texture is needed for card n. This happens when the given card becomes
- * visible.
- * @param n the id of the card
- */
- void onRequestTexture(int n);
-
- /**
- * Called when a texture is no longer needed for card n. This happens when the card
- * goes out of view.
- * @param n the id of the card
- */
- void onInvalidateTexture(int n);
-
- /**
- * Called when detail texture is needed for card n. This happens when the given card
- * becomes visible.
- * @param n the id of the card
- */
- void onRequestDetailTexture(int n);
-
- /**
- * Called when a detail texture is no longer needed for card n. This happens when the card
- * goes out of view.
- * @param n the id of the card
- */
- void onInvalidateDetailTexture(int n);
-
- /**
- * Called when geometry is needed for card n.
- * @param n the id of the card.
- */
- void onRequestGeometry(int n);
-
- /**
- * Called when geometry is no longer needed for card n. This happens when the card goes
- * out of view.
- * @param n the id of the card
- */
- void onInvalidateGeometry(int n);
-
- /**
- * Called when card animation (e.g. a fling) has started.
- */
- void onAnimationStarted();
-
- /**
- * Called when card animation has stopped.
- * @param carouselRotationAngle the angle of rotation, in radians, at which the animation
- * stopped.
- */
- void onAnimationFinished(float carouselRotationAngle);
- };
-
- private RSMessageHandler mRsMessage = new RSMessageHandler() {
- public void run() {
- if (mCallback == null) return;
- switch (mID) {
- case CMD_CARD_SELECTED:
- mCallback.onCardSelected(mData[0]);
- break;
-
- case CMD_DETAIL_SELECTED:
- mCallback.onDetailSelected(mData[0], mData[1], mData[2]);
- break;
-
- case CMD_CARD_LONGPRESS:
- int touchPosition[] = { mData[1], mData[2] };
- Rect detailCoordinates = new Rect(mData[3], mData[4], mData[5], mData[6]);
- mCallback.onCardLongPress(mData[0], touchPosition, detailCoordinates);
- break;
-
- case CMD_REQUEST_TEXTURE:
- mCallback.onRequestTexture(mData[0]);
- break;
-
- case CMD_INVALIDATE_TEXTURE:
- setTexture(mData[0], null);
- mCallback.onInvalidateTexture(mData[0]);
- break;
-
- case CMD_REQUEST_DETAIL_TEXTURE:
- mCallback.onRequestDetailTexture(mData[0]);
- break;
-
- case CMD_INVALIDATE_DETAIL_TEXTURE:
- setDetailTexture(mData[0], 0.0f, 0.0f, 0.0f, 0.0f, null);
- mCallback.onInvalidateDetailTexture(mData[0]);
- break;
-
- case CMD_REQUEST_GEOMETRY:
- mCallback.onRequestGeometry(mData[0]);
- break;
-
- case CMD_INVALIDATE_GEOMETRY:
- setGeometry(mData[0], null);
- mCallback.onInvalidateGeometry(mData[0]);
- break;
-
- case CMD_ANIMATION_STARTED:
- mCallback.onAnimationStarted();
- break;
-
- case CMD_ANIMATION_FINISHED:
- mCallback.onAnimationFinished(Float.intBitsToFloat(mData[0]));
- break;
-
- case CMD_PING:
- if (DBG) Log.v(TAG, "PING...");
- break;
-
- default:
- Log.e(TAG, "Unknown RSMessage: " + mID);
- }
- }
- };
-
- public CarouselRS(RenderScriptGL rs, Resources res, int resId) {
- mRS = rs;
- mRes = res;
-
- // create the script object
- mScript = new ScriptC_carousel(mRS, mRes, resId);
- mRS.setMessageHandler(mRsMessage);
- initProgramStore();
- initFragmentProgram();
- initRasterProgram();
- initVertexProgram();
- setSlotCount(DEFAULT_SLOT_COUNT);
- setVisibleSlots(DEFAULT_VISIBLE_SLOTS);
- setRowCount(DEFAULT_ROW_COUNT);
- createCards(DEFAULT_CARD_COUNT);
- setStartAngle(0.0f);
- setCarouselRotationAngle(0.0f);
- setRadius(1.0f);
- setLookAt(mEyePoint, mAtPoint, mUp);
- setRadius(20.0f);
- // Fov: 25
- }
-
- public void setLookAt(float[] eye, float[] at, float[] up) {
- for (int i = 0; i < 3; i++) {
- mEyePoint[i] = eye[i];
- mAtPoint[i] = at[i];
- mUp[i] = up[i];
- }
- mScript.invoke_lookAt(eye[0], eye[1], eye[2], at[0], at[1], at[2], up[0], up[1], up[2]);
- }
-
- public void setRadius(float radius) {
- mScript.invoke_setRadius(radius);
- }
-
- public void setCardRotation(float cardRotation) {
- mScript.set_cardRotation(cardRotation);
- }
-
- public void setCardsFaceTangent(boolean faceTangent) {
- mScript.set_cardsFaceTangent(faceTangent);
- }
-
- public void setSwaySensitivity(float swaySensitivity) {
- mScript.set_swaySensitivity(swaySensitivity);
- }
-
- public void setFrictionCoefficient(float frictionCoeff) {
- mScript.set_frictionCoeff(frictionCoeff);
- }
-
- public void setDragFactor(float dragFactor) {
- mScript.set_dragFactor(dragFactor);
- }
-
- public void setDragModel(int model) {
- mScript.set_dragModel(model);
- }
-
- public void setFillDirection(int direction) {
- mScript.set_fillDirection(direction);
- }
-
- private Matrix4f matrixFromFloat(float[] matrix) {
- int dimensions;
- if (matrix == null || matrix.length == 0) {
- dimensions = 0;
- } else if (matrix.length == 16) {
- dimensions = 4;
- } else if (matrix.length == 9) {
- dimensions = 3;
- } else {
- throw new IllegalArgumentException("matrix length not 0,9 or 16");
- }
-
- Matrix4f rsMatrix = new Matrix4f(); // initialized as identity.
- for (int i = 0; i < dimensions; i++) {
- for (int j = 0; j < dimensions; j++) {
- rsMatrix.set(i, j, matrix[i*dimensions + j]);
- }
- }
-
- return rsMatrix;
- }
-
- public void setDefaultCardMatrix(float[] matrix) {
- mScript.set_defaultCardMatrix(matrixFromFloat(matrix));
- }
-
- private void initVertexProgram() {
- ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
- mVertexProgram = pvb.create();
- ProgramVertexFixedFunction.Constants pva = new ProgramVertexFixedFunction.Constants(mRS);
- ((ProgramVertexFixedFunction)mVertexProgram).bindConstants(pva);
- Matrix4f proj = new Matrix4f();
- proj.loadProjectionNormalized(1, 1);
- pva.setProjection(proj);
- mScript.set_vertexProgram(mVertexProgram);
- }
-
- private void initRasterProgram() {
- ProgramRaster.Builder programRasterBuilder = new ProgramRaster.Builder(mRS);
- mRasterProgram = programRasterBuilder.create();
- //mRasterProgram.setCullMode(CullMode.NONE);
- mScript.set_rasterProgram(mRasterProgram);
- }
-
- private void initFragmentProgram() {
- //
- // Single texture program
- //
- ProgramFragment.Builder pfbSingle = new ProgramFragment.Builder(mRS);
- // Specify the resource that contains the shader string
- pfbSingle.setShader(mSingleTextureShader);
- // Tell the builder how many textures we have
- pfbSingle.addTexture(Program.TextureType.TEXTURE_2D);
- mSingleTextureFragmentProgram = pfbSingle.create();
- // Bind the source of constant data
- mSingleTextureFragmentProgram.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
-
- //
- // Single texture program, plus blending
- //
- mFSConst = new ScriptField_FragmentShaderConstants_s(mRS, 1);
- mScript.bind_shaderConstants(mFSConst);
- ProgramFragment.Builder pfbSingleBlend = new ProgramFragment.Builder(mRS);
- // Specify the resource that contains the shader string
- pfbSingleBlend.setShader(mSingleTextureBlendingShader);
- // Tell the builder how many textures we have
- pfbSingleBlend.addTexture(Program.TextureType.TEXTURE_2D);
- // Define the constant input layout
- pfbSingleBlend.addConstant(mFSConst.getAllocation().getType());
- mSingleTextureBlendingFragmentProgram = pfbSingleBlend.create();
- // Bind the source of constant data
- mSingleTextureBlendingFragmentProgram.bindConstants(mFSConst.getAllocation(), 0);
- mSingleTextureBlendingFragmentProgram.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
-
- //
- // Multi texture program
- //
- ProgramFragment.Builder pfbMulti = new ProgramFragment.Builder(mRS);
- // Specify the resource that contains the shader string
- pfbMulti.setShader(mMultiTextureShader);
- // Tell the builder how many textures we have
- pfbMulti.addTexture(Program.TextureType.TEXTURE_2D);
- pfbMulti.addTexture(Program.TextureType.TEXTURE_2D);
- // Define the constant input layout
- pfbMulti.addConstant(mFSConst.getAllocation().getType());
- mMultiTextureFragmentProgram = pfbMulti.create();
- // Bind the source of constant data
- mMultiTextureFragmentProgram.bindConstants(mFSConst.getAllocation(), 0);
- mMultiTextureFragmentProgram.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
- mMultiTextureFragmentProgram.bindSampler(Sampler.CLAMP_LINEAR(mRS), 1);
-
- //
- // Multi texture program, plus blending
- //
- ProgramFragment.Builder pfbMultiBlend = new ProgramFragment.Builder(mRS);
- // Specify the resource that contains the shader string
- pfbMultiBlend.setShader(mMultiTextureBlendingShader);
- // Tell the builder how many textures we have
- pfbMultiBlend.addTexture(Program.TextureType.TEXTURE_2D);
- pfbMultiBlend.addTexture(Program.TextureType.TEXTURE_2D);
- // Define the constant input layout
- pfbMultiBlend.addConstant(mFSConst.getAllocation().getType());
- mMultiTextureBlendingFragmentProgram = pfbMultiBlend.create();
- // Bind the source of constant data
- mMultiTextureBlendingFragmentProgram.bindConstants(mFSConst.getAllocation(), 0);
- mMultiTextureBlendingFragmentProgram.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
- mMultiTextureBlendingFragmentProgram.bindSampler(Sampler.CLAMP_LINEAR(mRS), 1);
-
- mScript.set_linearClamp(Sampler.CLAMP_LINEAR(mRS));
- mScript.set_singleTextureFragmentProgram(mSingleTextureFragmentProgram);
- mScript.set_singleTextureBlendingFragmentProgram(mSingleTextureBlendingFragmentProgram);
- mScript.set_multiTextureFragmentProgram(mMultiTextureFragmentProgram);
- mScript.set_multiTextureBlendingFragmentProgram(mMultiTextureBlendingFragmentProgram);
- }
-
- private void initProgramStore() {
- resizeProgramStoresCard(1);
-
- final boolean dither = true;
- final ProgramStore.DepthFunc depthFunc = mForceBlendCardsWithZ ?
- ProgramStore.DepthFunc.LESS : ProgramStore.DepthFunc.ALWAYS;
-
- // Background: Alpha disabled, depth optional
- mScript.set_programStoreBackground(new ProgramStore.Builder(mRS)
- .setBlendFunc(ProgramStore.BlendSrcFunc.ONE, ProgramStore.BlendDstFunc.ZERO)
- .setDitherEnabled(dither)
- .setDepthFunc(depthFunc)
- .setDepthMaskEnabled(mForceBlendCardsWithZ)
- .create());
-
- // Card: Alpha enabled, depth optional
- setProgramStoreCard(0, new ProgramStore.Builder(mRS)
- .setBlendFunc(ProgramStore.BlendSrcFunc.ONE,
- ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA)
- .setDitherEnabled(dither)
- .setDepthFunc(depthFunc)
- .setDepthMaskEnabled(mForceBlendCardsWithZ)
- .create());
-
- // Detail: Alpha enabled, depth disabled
- mScript.set_programStoreDetail(new ProgramStore.Builder(mRS)
- .setBlendFunc(ProgramStore.BlendSrcFunc.ONE,
- ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA)
- .setDitherEnabled(dither)
- .setDepthFunc(ProgramStore.DepthFunc.ALWAYS)
- .setDepthMaskEnabled(false)
- .create());
- }
-
- public void createCards(int count)
- {
- // Because RenderScript can't have allocations with 0 dimensions, we always create
- // an allocation of at least one card. This relies on invoke_createCards() to keep
- // track of when the allocation is not valid.
- if (mCards != null && count > 0) {
- // resize the array
- int oldSize = mCards.getAllocation().getType().getX();
- mCards.resize(count);
- mScript.invoke_createCards(oldSize, count);
- } else {
- // create array from scratch
- mCards = new ScriptField_Card(mRS, count > 0 ? count : 1);
- mScript.bind_cards(mCards);
- mScript.invoke_createCards(0, count);
- }
- }
-
- public void setVisibleSlots(int count)
- {
- mVisibleSlots = count;
- mScript.set_visibleSlotCount(count);
- }
-
- public void setVisibleDetails(int count) {
- mScript.set_visibleDetailCount(count);
- }
-
- public void setRowCount(int count) {
- mRowCount = count;
- mScript.set_rowCount(count);
- }
-
- public void setRowSpacing(float spacing) {
- mScript.set_rowSpacing(spacing);
- }
-
- public void setOverscrollSlots(float slots) {
- mScript.set_overscrollSlots(slots);
- }
-
- public void setFirstCardTop(boolean first) {
- mScript.set_firstCardTop(first);
- }
-
- public void setPrefetchCardCount(int count) {
- mPrefetchCardCount = count;
- mScript.set_prefetchCardCount(count);
- }
-
- public void setDetailTextureAlignment(int alignment) {
- mScript.set_detailTextureAlignment(alignment);
- }
-
- private void resizeProgramStoresCard(int count) {
- // enableResize works around a Renderscript bug that keeps resizes from being propagated.
- // TODO(jshuma): Remove enableResize once the Renderscript bug is fixed
- final boolean enableResize = false;
-
- if (mProgramStoresCard != null && enableResize) {
- int newSize = count > 0 ? count : 1;
- mProgramStoresCard.resize(newSize);
- } else {
- mProgramStoresCard = new ScriptField_ProgramStore_s(mRS, count > 0 ? count : 1);
- mScript.bind_programStoresCard(mProgramStoresCard);
- }
- }
-
- private void setProgramStoreCard(int n, ProgramStore programStore) {
- ScriptField_ProgramStore_s.Item item = mProgramStoresCard.get(n);
- if (item == null) {
- item = new ScriptField_ProgramStore_s.Item();
- }
- item.programStore = programStore;
- mProgramStoresCard.set(item, n, false);
- mScript.invoke_setProgramStoresCard(n, programStore);
- }
-
- public void setStoreConfigs(int configs[]) {
- if (configs == null) {
- initProgramStore();
- return;
- }
-
- final int count = configs.length;
-
- resizeProgramStoresCard(count);
- for (int i=0; i<count; ++i) {
- final int config = configs[i];
-
- final boolean alpha = (config & CarouselController.STORE_CONFIG_ALPHA) != 0;
- final boolean depthReads = (config & CarouselController.STORE_CONFIG_DEPTH_READS) != 0;
- final boolean depthWrites =
- (config & CarouselController.STORE_CONFIG_DEPTH_WRITES) != 0;
-
- final boolean dither = true;
- final ProgramStore.BlendDstFunc dstFunc = alpha ?
- ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA :
- ProgramStore.BlendDstFunc.ZERO;
- final ProgramStore.DepthFunc depthFunc = depthReads ?
- ProgramStore.DepthFunc.LESS :
- ProgramStore.DepthFunc.ALWAYS;
-
- final ProgramStore ps = new ProgramStore.Builder(mRS)
- .setBlendFunc(ProgramStore.BlendSrcFunc.ONE, dstFunc)
- .setDitherEnabled(dither)
- .setDepthFunc(depthFunc)
- .setDepthMaskEnabled(depthWrites)
- .create();
-
- setProgramStoreCard(i, ps);
- }
- }
-
- /**
- * Sets whether the background texture and default card geometry are to be drawn with respect
- * to the depth buffer (both reading from it and writing to it).
- *
- * This method is a specialization of functionality that can be done with greater flexibility
- * by setStoreConfigs. Calling setForceBlendCardsWithZ() after calling setStoreConfigs()
- * results in the values set in setStoreConfigs() being discarded.
- *
- * @param enabled true to read from and write to the depth buffer, false to ignore it
- */
- public void setForceBlendCardsWithZ(boolean enabled) {
- mForceBlendCardsWithZ = enabled;
- initProgramStore();
- }
-
- public void setDrawRuler(boolean drawRuler) {
- mScript.set_drawRuler(drawRuler);
- }
-
- public void setDefaultBitmap(Bitmap bitmap)
- {
- mScript.set_defaultTexture(allocationFromBitmap(bitmap, MIPMAP));
- }
-
- public void setLoadingBitmap(Bitmap bitmap)
- {
- mScript.set_loadingTexture(allocationFromBitmap(bitmap, MIPMAP));
- }
-
- public void setDefaultGeometry(Mesh mesh)
- {
- mScript.set_defaultGeometry(mesh);
- }
-
- public void setLoadingGeometry(Mesh mesh)
- {
- mScript.set_loadingGeometry(mesh);
- }
-
- public void setStartAngle(float theta)
- {
- mScript.set_startAngle(theta);
- }
-
- public void setCarouselRotationAngle(float theta) {
- mScript.invoke_setCarouselRotationAngle(theta);
- }
-
- public void setCarouselRotationAngle(float endAngle, int milliseconds, int interpolationMode,
- float maxAnimatedArc) {
- mScript.invoke_setCarouselRotationAngle2(endAngle, milliseconds, interpolationMode,
- maxAnimatedArc);
- }
-
- public void setCallback(CarouselCallback callback)
- {
- mCallback = callback;
- }
-
- private Allocation allocationFromBitmap(Bitmap bitmap, Allocation.MipmapControl mipmap)
- {
- if (bitmap == null) return null;
- Allocation allocation = Allocation.createFromBitmap(mRS, bitmap,
- mipmap, Allocation.USAGE_GRAPHICS_TEXTURE);
- return allocation;
- }
-
- private Allocation allocationFromPool(int n, Bitmap bitmap, Allocation.MipmapControl mipmap)
- {
- int count = (mVisibleSlots + 2*mPrefetchCardCount) * mRowCount;
- if (mAllocationPool == null || mAllocationPool.length != count) {
- Allocation[] tmp = new Allocation[count];
- int oldsize = mAllocationPool == null ? 0 : mAllocationPool.length;
- for (int i = 0; i < Math.min(count, oldsize); i++) {
- tmp[i] = mAllocationPool[i];
- }
- mAllocationPool = tmp;
- }
- Allocation allocation = mAllocationPool[n % count];
- if (allocation == null) {
- allocation = allocationFromBitmap(bitmap, mipmap);
- mAllocationPool[n % count] = allocation;
- } else if (bitmap != null) {
- if (bitmap.getWidth() == allocation.getType().getX()
- && bitmap.getHeight() == allocation.getType().getY()) {
- allocation.copyFrom(bitmap);
- } else {
- Log.v(TAG, "Warning, bitmap has different size. Taking slow path");
- allocation = allocationFromBitmap(bitmap, mipmap);
- mAllocationPool[n % count] = allocation;
- }
- }
- return allocation;
- }
-
- private ScriptField_Card.Item getCard(int n) {
- ScriptField_Card.Item item;
- try {
- item = mCards.get(n);
- }
- catch (ArrayIndexOutOfBoundsException e) {
- if (DBG) Log.v(TAG, "getCard(): no item at index " + n);
- item = null;
- }
- return item;
- }
-
- private ScriptField_Card.Item getOrCreateCard(int n) {
- ScriptField_Card.Item item = getCard(n);
- if (item == null) {
- if (DBG) Log.v(TAG, "getOrCreateCard(): no item at index " + n + "; creating new");
- item = new ScriptField_Card.Item();
- }
- return item;
- }
-
- private void setCard(int n, ScriptField_Card.Item item) {
- try {
- mCards.set(item, n, false); // This is primarily used for reference counting.
- }
- catch (ArrayIndexOutOfBoundsException e) {
- // The specified index didn't exist. This can happen when a stale invalidate
- // request outlived an array resize request. Something might be getting dropped,
- // but there's not much we can do about this at this point to recover.
- Log.w(TAG, "setCard(" + n + "): Texture " + n + " doesn't exist");
- }
- }
-
- public void setTexture(int n, Bitmap bitmap)
- {
- if (n < 0) throw new IllegalArgumentException("Index cannot be negative");
-
- synchronized(this) {
- ScriptField_Card.Item item = getOrCreateCard(n);
- if (bitmap != null) {
- item.texture = allocationFromPool(n, bitmap, MIPMAP);
- } else {
- if (item.texture != null) {
- if (DBG) Log.v(TAG, "unloading texture " + n);
- item.texture = null;
- }
- }
- setCard(n, item);
- mScript.invoke_setTexture(n, item.texture);
- }
- }
-
- void setDetailTexture(int n, float offx, float offy, float loffx, float loffy, Bitmap bitmap)
- {
- if (n < 0) throw new IllegalArgumentException("Index cannot be negative");
-
- synchronized(this) {
- ScriptField_Card.Item item = getOrCreateCard(n);
- float width = 0.0f;
- float height = 0.0f;
- if (bitmap != null) {
- item.detailTexture = allocationFromBitmap(bitmap, MIPMAP);
- width = bitmap.getWidth();
- height = bitmap.getHeight();
- } else {
- if (item.detailTexture != null) {
- if (DBG) Log.v(TAG, "unloading detail texture " + n);
- // Don't wait for GC to free native memory.
- // Only works if textures are not shared.
- item.detailTexture.destroy();
- item.detailTexture = null;
- }
- }
- setCard(n, item);
- mScript.invoke_setDetailTexture(n, offx, offy, loffx, loffy, item.detailTexture);
- }
- }
-
- void invalidateTexture(int n, boolean eraseCurrent)
- {
- if (n < 0) throw new IllegalArgumentException("Index cannot be negative");
-
- synchronized(this) {
- ScriptField_Card.Item item = getCard(n);
- if (item == null) {
- // This card was never created, so there's nothing to invalidate.
- return;
- }
- if (eraseCurrent && item.texture != null) {
- if (DBG) Log.v(TAG, "unloading texture " + n);
- // Don't wait for GC to free native memory.
- // Only works if textures are not shared.
- item.texture.destroy();
- item.texture = null;
- }
- setCard(n, item);
- mScript.invoke_invalidateTexture(n, eraseCurrent);
- }
- }
-
- void invalidateDetailTexture(int n, boolean eraseCurrent)
- {
- if (n < 0) throw new IllegalArgumentException("Index cannot be negative");
-
- synchronized(this) {
- ScriptField_Card.Item item = getCard(n);
- if (item == null) {
- // This card was never created, so there's nothing to invalidate.
- return;
- }
- if (eraseCurrent && item.detailTexture != null) {
- if (DBG) Log.v(TAG, "unloading detail texture " + n);
- // Don't wait for GC to free native memory.
- // Only works if textures are not shared.
- item.detailTexture.destroy();
- item.detailTexture = null;
- }
- setCard(n, item);
- mScript.invoke_invalidateDetailTexture(n, eraseCurrent);
- }
- }
-
- public void setGeometry(int n, Mesh geometry)
- {
- if (n < 0) throw new IllegalArgumentException("Index cannot be negative");
-
- synchronized(this) {
- final boolean mipmap = false;
- ScriptField_Card.Item item = getOrCreateCard(n);
- if (geometry != null) {
- item.geometry = geometry;
- } else {
- if (DBG) Log.v(TAG, "unloading geometry " + n);
- if (item.geometry != null) {
- // item.geometry.destroy();
- item.geometry = null;
- }
- }
- setCard(n, item);
- mScript.invoke_setGeometry(n, item.geometry);
- }
- }
-
- public void setMatrix(int n, float[] matrix) {
- if (n < 0) throw new IllegalArgumentException("Index cannot be negative");
-
- synchronized(this) {
- final boolean mipmap = false;
- ScriptField_Card.Item item = getOrCreateCard(n);
- if (matrix != null) {
- item.matrix = matrixFromFloat(matrix);
- } else {
- if (DBG) Log.v(TAG, "unloading matrix " + n);
- item.matrix = null;
- }
- setCard(n, item);
- mScript.invoke_setMatrix(n, item.matrix);
- }
- }
-
- public void setBackgroundColor(Float4 color) {
- mScript.set_backgroundColor(color);
- }
-
- public void setBackgroundTexture(Bitmap bitmap) {
- Allocation texture = null;
- if (bitmap != null) {
- texture = Allocation.createFromBitmap(mRS, bitmap,
- MIPMAP, Allocation.USAGE_GRAPHICS_TEXTURE);
- }
- mScript.set_backgroundTexture(texture);
- }
-
- public void setDetailLineTexture(Bitmap bitmap) {
- Allocation texture = null;
- if (bitmap != null) {
- texture = Allocation.createFromBitmap(mRS, bitmap,
- MIPMAP, Allocation.USAGE_GRAPHICS_TEXTURE);
- }
- mScript.set_detailLineTexture(texture);
- }
-
- public void setDetailLoadingTexture(Bitmap bitmap) {
- Allocation texture = null;
- if (bitmap != null) {
- texture = Allocation.createFromBitmap(mRS, bitmap,
- MIPMAP, Allocation.USAGE_GRAPHICS_TEXTURE);
- }
- mScript.set_detailLoadingTexture(texture);
- }
-
- public void pauseRendering() {
- // Used to update multiple states at once w/o redrawing for each.
- mRS.bindRootScript(null);
- }
-
- public void resumeRendering() {
- mRS.bindRootScript(mScript);
- }
-
- public void doLongPress() {
- mScript.invoke_doLongPress();
- }
-
- public void doMotion(float x, float y, long t) {
- mScript.invoke_doMotion(x, y, t);
- }
-
- public void doStart(float x, float y, long t) {
- mScript.invoke_doStart(x, y, t);
- }
-
- public void doStop(float x, float y, long t) {
- mScript.invoke_doStop(x, y, t);
- }
-
- public void setSlotCount(int n) {
- mScript.set_slotCount(n);
- }
-
- public void setRezInCardCount(float alpha) {
- mScript.set_rezInCardCount(alpha);
- }
-
- public void setFadeInDuration(long t) {
- mScript.set_fadeInDuration((int)t); // TODO: Remove cast when RS supports exporting longs
- }
-
- public void setCardCreationFadeDuration(long t) {
- mScript.set_cardCreationFadeDuration((int)t);
- }
-
- private Element elementForBitmap(Bitmap bitmap, Bitmap.Config defaultConfig) {
- Bitmap.Config config = bitmap.getConfig();
- if (config == null) {
- config = defaultConfig;
- }
- if (config == Bitmap.Config.ALPHA_8) {
- return A_8(mRS);
- } else if (config == Bitmap.Config.RGB_565) {
- return RGB_565(mRS);
- } else if (config == Bitmap.Config.ARGB_4444) {
- return RGBA_4444(mRS);
- } else if (config == Bitmap.Config.ARGB_8888) {
- return RGBA_8888(mRS);
- } else {
- throw new IllegalArgumentException("Unknown configuration");
- }
- }
-
- public Mesh loadGeometry(int resId) {
- if (resId == 0) {
- return null;
- }
- FileA3D model = FileA3D.createFromResource(mRS, mRes, resId);
- if (model == null) {
- return null;
- }
- FileA3D.IndexEntry entry = model.getIndexEntry(0);
- if(entry == null || entry.getEntryType() != FileA3D.EntryType.MESH) {
- return null;
- }
- return (Mesh) entry.getObject();
- }
-}
diff --git a/carousel/java/com/android/ex/carousel/CarouselView.java b/carousel/java/com/android/ex/carousel/CarouselView.java
deleted file mode 100644
index 25c7366..0000000
--- a/carousel/java/com/android/ex/carousel/CarouselView.java
+++ /dev/null
@@ -1,605 +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.
- */
-
-package com.android.ex.carousel;
-
-import android.view.View;
-import com.android.ex.carousel.CarouselRS.CarouselCallback;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.renderscript.Float4;
-import android.renderscript.Mesh;
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScriptGL;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.SurfaceHolder;
-
-/**
- * <p>
- * This class represents the basic building block for using a 3D Carousel. The Carousel is
- * basically a scene of cards and slots. The spacing between cards is dictated by the number
- * of slots and the radius. The number of visible cards dictates how far the Carousel can be moved.
- * If the number of cards exceeds the number of slots, then the Carousel will continue to go
- * around until the last card can be seen.
- */
-public abstract class CarouselView extends RSSurfaceView {
- private static final boolean USE_DEPTH_BUFFER = true;
- private static final String TAG = "CarouselView";
- private CarouselRS mRenderScript;
- private RenderScriptGL mRS;
- private Context mContext;
- private boolean mTracking;
-
- CarouselController mController;
-
- // Drag relative to x coordinate of motion on screen
- public static final int DRAG_MODEL_SCREEN_DELTA = CarouselRS.DRAG_MODEL_SCREEN_DELTA;
- // Drag relative to projected point on plane of carousel
- public static final int DRAG_MODEL_PLANE = CarouselRS.DRAG_MODEL_PLANE;
- // Drag relative to projected point on inside (far point) of cylinder centered around carousel
- public static final int DRAG_MODEL_CYLINDER_INSIDE = CarouselRS.DRAG_MODEL_CYLINDER_INSIDE;
- // Drag relative to projected point on outside (near point) of cylinder centered around carousel
- public static final int DRAG_MODEL_CYLINDER_OUTSIDE = CarouselRS.DRAG_MODEL_CYLINDER_OUTSIDE;
-
- // Draw cards counterclockwise around the carousel
- public static final int FILL_DIRECTION_CCW = CarouselRS.FILL_DIRECTION_CCW;
- // Draw cards clockwise around the carousel
- public static final int FILL_DIRECTION_CW = CarouselRS.FILL_DIRECTION_CW;
-
- // Note: remember to update carousel.rs when changing the values below
- public static class InterpolationMode {
- /** y= x **/
- public static final int LINEAR = 0;
- /** The quadratic curve y= 1 - (1 - x)^2 moves quickly towards the target
- * while decelerating constantly. **/
- public static final int DECELERATE_QUADRATIC = 1;
- /** The cubic curve y= (3-2x)*x^2 gradually accelerates at the origin,
- * and decelerates near the target. **/
- public static final int ACCELERATE_DECELERATE_CUBIC = 2;
- }
-
- // Note: remember to update carousel.rs when changing the values below
- public static class DetailAlignment {
- /** Detail is centered vertically with respect to the card **/
- public static final int CENTER_VERTICAL = 1;
- /** Detail is aligned with the top edge of the carousel view **/
- public static final int VIEW_TOP = 1 << 1;
- /** Detail is aligned with the bottom edge of the carousel view (not yet implemented) **/
- public static final int VIEW_BOTTOM = 1 << 2;
- /** Detail is positioned above the card (not yet implemented) **/
- public static final int ABOVE = 1 << 3;
- /** Detail is positioned below the card **/
- public static final int BELOW = 1 << 4;
- /** Mask that selects those bits that control vertical alignment **/
- public static final int VERTICAL_ALIGNMENT_MASK = 0xff;
-
- /**
- * Detail is centered horizontally with respect to either the top or bottom
- * extent of the card, depending on whether the detail is above or below the card.
- */
- public static final int CENTER_HORIZONTAL = 1 << 8;
- /**
- * Detail is aligned with the left edge of either the top or the bottom of
- * the card, depending on whether the detail is above or below the card.
- */
- public static final int LEFT = 1 << 9;
- /**
- * Detail is aligned with the right edge of either the top or the bottom of
- * the card, depending on whether the detail is above or below the card.
- * (not yet implemented)
- */
- public static final int RIGHT = 1 << 10;
- /** Mask that selects those bits that control horizontal alignment **/
- public static final int HORIZONTAL_ALIGNMENT_MASK = 0xff00;
- }
-
- public static class Info {
- public Info(int _resId) { resId = _resId; }
- public int resId; // resource for renderscript resource (e.g. R.raw.carousel)
- }
-
- public abstract Info getRenderScriptInfo();
-
- public CarouselView(Context context) {
- this(context, new CarouselController());
- }
-
- public CarouselView(Context context, CarouselController controller) {
- this(context, null, controller);
- }
-
- /**
- * Constructor used when this widget is created from a layout file.
- */
- public CarouselView(Context context, AttributeSet attrs) {
- this(context, attrs, new CarouselController());
- }
-
- public CarouselView(Context context, AttributeSet attrs, CarouselController controller) {
- super(context, attrs);
- mContext = context;
- mController = controller;
- boolean useDepthBuffer = true;
- ensureRenderScript();
- // TODO: add parameters to layout
-
- setOnLongClickListener(new View.OnLongClickListener() {
- public boolean onLongClick(View v) {
- if (interpretLongPressEvents()) {
- mController.onLongPress();
- return true;
- } else {
- return false;
- }
- }
- });
- }
-
- private void ensureRenderScript() {
- if (mRS == null) {
- RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
- if (USE_DEPTH_BUFFER) {
- sc.setDepth(16, 24);
- }
- mRS = createRenderScriptGL(sc);
- }
- if (mRenderScript == null) {
- mRenderScript = new CarouselRS(mRS, mContext.getResources(),
- getRenderScriptInfo().resId);
- mRenderScript.resumeRendering();
- }
- mController.setRS(mRS, mRenderScript);
- }
-
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
- super.surfaceChanged(holder, format, w, h);
- // setZOrderOnTop(true);
- mController.onSurfaceChanged();
- }
-
- public CarouselController getController() {
- return mController;
- }
-
- public void setController(CarouselController controller) {
- mController = controller;
- mController.setRS(mRS, mRenderScript);
- }
-
- /**
- * Do I want to interpret the long-press gesture? If so, long-presses will cancel the
- * current selection and call the appropriate callbacks. Otherwise, a long press will
- * not be handled any way other than as a continued drag.
- *
- * @return True if we interpret long-presses
- */
- public boolean interpretLongPressEvents() {
- return false;
- }
-
- /**
- * Loads geometry from a resource id.
- *
- * @param resId
- * @return the loaded mesh or null if it cannot be loaded
- */
- public Mesh loadGeometry(int resId) {
- return mController.loadGeometry(resId);
- }
-
- /**
- * Set the geometry for a given item.
- * @param n
- * @param mesh
- */
- public void setGeometryForItem(int n, Mesh mesh) {
- mController.setGeometryForItem(n, mesh);
- }
-
- /**
- * Set the matrix for a given item.
- * @param n
- * @param matrix the requested matrix; null to just use the default
- */
- public void setMatrixForItem(int n, float[] matrix) {
- mController.setMatrixForItem(n, matrix);
- }
-
- /**
- * Set the number of slots around the Carousel. Basically equivalent to the poles horses
- * might attach to on a real Carousel.
- *
- * @param n the number of slots
- */
- public void setSlotCount(int n) {
- mController.setSlotCount(n);
- }
-
- /**
- * Sets the number of visible slots around the Carousel. This is primarily used as a cheap
- * form of clipping. The Carousel will never show more than this many cards.
- * @param n the number of visible slots
- */
- public void setVisibleSlots(int n) {
- mController.setVisibleSlots(n);
- }
-
- /**
- * Set the number of cards to pre-load that are outside of the visible region, as determined by
- * setVisibleSlots(). This number gets added to the number of visible slots and used to
- * determine when resources for cards should be loaded. This number should be small (n <= 4)
- * for systems with limited texture memory or views that show more than half dozen cards in the
- * view.
- *
- * @param n the number of cards; should be even, so the count is the same on each side
- */
- public void setPrefetchCardCount(int n) {
- mController.setPrefetchCardCount(n);
- }
-
- /**
- * Sets the number of rows of cards to show in each slot.
- */
- public void setRowCount(int n) {
- mController.setRowCount(n);
- }
-
- /**
- * Sets the spacing between each row of cards when rowCount > 1.
- */
- public void setRowSpacing(float s) {
- mController.setRowSpacing(s);
- }
-
- /**
- * Sets the position of the first card when rowCount > 1.
- */
- public void setFirstCardTop(boolean f) {
- mController.setFirstCardTop(f);
- }
-
- /**
- * Sets the amount of allowed overscroll (in slots)
- */
- public void setOverscrollSlots(float slots) {
- mController.setOverscrollSlots(slots);
- }
-
- /**
- * Set the number of detail textures that can be visible at one time.
- *
- * @param n the number of slots
- */
- public void setVisibleDetails(int n) {
- mController.setVisibleDetails(n);
- }
-
- /**
- * Sets how detail textures are aligned with respect to the card.
- *
- * @param alignment a bitmask of DetailAlignment flags.
- */
- public void setDetailTextureAlignment(int alignment) {
- mController.setDetailTextureAlignment(alignment);
- }
-
- /**
- * Set whether depth is enabled while blending. Generally, this is discouraged because
- * it causes bad artifacts. Careful attention to geometry and alpha transparency of
- * textures can mitigate much of this. For example, geometry for an item must be drawn
- * back-to-front if any edges overlap.
- *
- * @param enabled True to enable depth while blending, and false to disable it.
- */
- public void setForceBlendCardsWithZ(boolean enabled) {
- mController.setForceBlendCardsWithZ(enabled);
- }
-
- /**
- * Set whether to draw a ruler from the card to the detail texture
- *
- * @param drawRuler True to draw a ruler, false to draw nothing where the ruler would go.
- */
- public void setDrawRuler(boolean drawRuler) {
- mController.setDrawRuler(drawRuler);
- }
-
- /**
- * This dictates how many cards are in the deck. If the number of cards is greater than the
- * number of slots, then the Carousel goes around n / slot_count times.
- *
- * Can be called again to increase or decrease the number of cards.
- *
- * @param n the number of cards to create.
- */
- public void createCards(int n) {
- mController.createCards(n);
- }
-
- public int getCardCount() {
- return mController.getCardCount();
- }
-
- /**
- * This sets the texture on card n. It should only be called in response to
- * {@link CarouselCallback#onRequestTexture(int)}. Since there's no guarantee
- * that a given texture is still on the screen, replacing this texture should be done
- * by first setting it to null and then waiting for the next
- * {@link CarouselCallback#onRequestTexture(int)} to swap it with the new one.
- *
- * @param n the card given by {@link CarouselCallback#onRequestTexture(int)}
- * @param bitmap the bitmap image to show
- */
- public void setTextureForItem(int n, Bitmap bitmap) {
- mController.setTextureForItem(n, bitmap);
- }
-
- /**
- * This sets the detail texture that floats above card n. It should only be called in response
- * to {@link CarouselCallback#onRequestDetailTexture(int)}. Since there's no guarantee
- * that a given texture is still on the screen, replacing this texture should be done
- * by first setting it to null and then waiting for the next
- * {@link CarouselCallback#onRequestDetailTexture(int)} to swap it with the new one.
- *
- * @param n the card to set detail texture for
- * @param offx an optional offset to apply to the texture (in pixels) from top of detail line
- * @param offy an optional offset to apply to the texture (in pixels) from top of detail line
- * @param loffx an optional offset to apply to the line (in pixels) from left edge of card
- * @param loffy an optional offset to apply to the line (in pixels) from top of screen
- * @param bitmap the bitmap to show as the detail
- */
- public void setDetailTextureForItem(int n, float offx, float offy, float loffx, float loffy,
- Bitmap bitmap) {
- mController.setDetailTextureForItem(n, offx, offy, loffx, loffy, bitmap);
- }
-
- /**
- * Sets the bitmap to show on a card when the card draws the very first time.
- * Generally, this bitmap will only be seen during the first few frames of startup
- * or when the number of cards are changed. It can be ignored in most cases,
- * as the cards will generally only be in the loading or loaded state.
- *
- * @param bitmap
- */
- public void setDefaultBitmap(Bitmap bitmap) {
- mController.setDefaultBitmap(bitmap);
- }
-
- /**
- * Sets the bitmap to show on the card while the texture is loading. It is set to this
- * value just before {@link CarouselCallback#onRequestTexture(int)} is called and changed
- * when {@link CarouselView#setTextureForItem(int, Bitmap)} is called. It is shared by all
- * cards.
- *
- * @param bitmap
- */
- public void setLoadingBitmap(Bitmap bitmap) {
- mController.setLoadingBitmap(bitmap);
- }
-
- /**
- * Sets background to specified color. If a background texture is specified with
- * {@link CarouselView#setBackgroundBitmap(Bitmap)}, then this call has no effect.
- *
- * @param red the amount of red
- * @param green the amount of green
- * @param blue the amount of blue
- * @param alpha the amount of alpha
- */
- public void setBackgroundColor(float red, float green, float blue, float alpha) {
- mController.setBackgroundColor(red, green, blue, alpha);
- }
-
- /**
- * Can be used to optionally set the background to a bitmap. When set to something other than
- * null, this overrides {@link CarouselView#setBackgroundColor(Float4)}.
- *
- * @param bitmap
- */
- public void setBackgroundBitmap(Bitmap bitmap) {
- mController.setBackgroundBitmap(bitmap);
- }
-
- /**
- * Can be used to optionally set a "loading" detail bitmap. Typically, this is just a black
- * texture with alpha = 0 to allow details to slowly fade in.
- *
- * @param bitmap
- */
- public void setDetailLoadingBitmap(Bitmap bitmap) {
- mController.setDetailLoadingBitmap(bitmap);
- }
-
- /**
- * This texture is used to draw a line from the card alongside the texture detail. The line
- * will be as wide as the texture. It can be used to give the line glow effects as well as
- * allowing other blending effects. It is typically one dimensional, e.g. 3x1.
- *
- * @param bitmap
- */
- public void setDetailLineBitmap(Bitmap bitmap) {
- mController.setDetailLineBitmap(bitmap);
- }
-
- /**
- * This geometry will be shown when no geometry has been loaded for a given slot. If not set,
- * a quad will be drawn in its place. It is shared for all cards. If something other than
- * simple planar geometry is used, consider enabling depth test with
- * {@link CarouselView#setForceBlendCardsWithZ(boolean)}
- *
- * @param resId
- */
- public void setDefaultGeometry(int resId) {
- mController.setDefaultGeometry(resId);
- }
-
- /**
- * Sets the matrix used to transform card geometries. By default, this
- * is the identity matrix, but you can specify a different matrix if you
- * want to scale, translate and / or rotate the card before drawing.
- *
- * @param matrix array of 9 or 16 floats representing a 3x3 or 4x4 matrix,
- * or null as a shortcut for an identity matrix.
- */
- public void setDefaultCardMatrix(float[] matrix) {
- mController.setDefaultCardMatrix(matrix);
- }
-
- /**
- * This is an intermediate version of the object to show while geometry is loading. If not set,
- * a quad will be drawn in its place. It is shared for all cards. If something other than
- * simple planar geometry is used, consider enabling depth test with
- * {@link CarouselView#setForceBlendCardsWithZ(boolean)}
- *
- * @param resId
- */
- public void setLoadingGeometry(int resId) {
- mController.setLoadingGeometry(resId);
- }
-
- /**
- * Sets the callback for receiving events from RenderScript.
- *
- * @param callback
- */
- public void setCallback(CarouselCallback callback)
- {
- mController.setCallback(callback);
- }
-
- /**
- * Sets the startAngle for the Carousel. The start angle is the first position of the first
- * slot draw. Cards will be drawn from this angle in a counter-clockwise manner around the
- * Carousel.
- *
- * @param angle the angle, in radians.
- */
- public void setStartAngle(float angle)
- {
- mController.setStartAngle(angle);
- }
-
- public void setRadius(float radius) {
- mController.setRadius(radius);
- }
-
- public void setCardRotation(float cardRotation) {
- mController.setCardRotation(cardRotation);
- }
-
- public void setCardsFaceTangent(boolean faceTangent) {
- mController.setCardsFaceTangent(faceTangent);
- }
-
- public void setSwaySensitivity(float swaySensitivity) {
- mController.setSwaySensitivity(swaySensitivity);
- }
-
- public void setFrictionCoefficient(float frictionCoefficient) {
- mController.setFrictionCoefficient(frictionCoefficient);
- }
-
- public void setDragFactor(float dragFactor) {
- mController.setDragFactor(dragFactor);
- }
-
- public void setDragModel(int model) {
- mController.setDragModel(model);
- }
-
- public void setLookAt(float[] eye, float[] at, float[] up) {
- mController.setLookAt(eye, at, up);
- }
-
- /**
- * This sets the number of cards in the distance that will be shown "rezzing in".
- * These alpha values will be faded in from the background to the foreground over
- * 'n' cards. A floating point value is used to allow subtly changing the rezzing in
- * position.
- *
- * @param n the number of cards to rez in.
- */
- public void setRezInCardCount(float n) {
- mController.setRezInCardCount(n);
- }
-
- /**
- * This sets the duration (in ms) that a card takes to fade in when loaded via a call
- * to {@link CarouselView#setTextureForItem(int, Bitmap)}. The timer starts the
- * moment {@link CarouselView#setTextureForItem(int, Bitmap)} is called and continues
- * until all of the cards have faded in. Note: using large values will extend the
- * animation until all cards have faded in.
- *
- * @param t
- */
- public void setFadeInDuration(long t) {
- mController.setFadeInDuration(t);
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- mRenderScript = null;
- if (mRS != null) {
- mRS = null;
- destroyRenderScriptGL();
- }
- mController.setRS(mRS, mRenderScript);
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- ensureRenderScript();
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- super.onTouchEvent(event);
- final int action = event.getAction();
-
- if (mRenderScript == null) {
- return true;
- }
-
- switch (action) {
- case MotionEvent.ACTION_DOWN:
- mTracking = true;
- mController.onTouchStarted(event.getX(), event.getY(), event.getEventTime());
- break;
-
- case MotionEvent.ACTION_MOVE:
- if (mTracking) {
- for (int i = 0; i < event.getHistorySize(); i++) {
- mController.onTouchMoved(event.getHistoricalX(i), event.getHistoricalY(i),
- event.getHistoricalEventTime(i));
- }
- mController.onTouchMoved(event.getX(), event.getY(), event.getEventTime());
- }
- break;
-
- case MotionEvent.ACTION_UP:
- mController.onTouchStopped(event.getX(), event.getY(), event.getEventTime());
- mTracking = false;
- break;
- }
-
- return true;
- }
-}
diff --git a/carousel/java/com/android/ex/carousel/CarouselViewHelper.java b/carousel/java/com/android/ex/carousel/CarouselViewHelper.java
deleted file mode 100644
index ef05ba9..0000000
--- a/carousel/java/com/android/ex/carousel/CarouselViewHelper.java
+++ /dev/null
@@ -1,305 +0,0 @@
-package com.android.ex.carousel;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Matrix;
-import android.graphics.Rect;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.renderscript.Matrix4f;
-import android.renderscript.Mesh;
-import android.util.Log;
-
-import com.android.ex.carousel.CarouselRS.CarouselCallback;
-
-/**
- * CarouselViewHelper wraps all of the threading and event handling of the CarouselView,
- * providing a simpler interface. Most users will just need to implement a handful of
- * methods to get an application working.
- *
- */
-public class CarouselViewHelper implements CarouselCallback {
- private static final String TAG = "CarouselViewHelper";
- private static final int SET_TEXTURE_N = 1;
- private static final int SET_DETAIL_TEXTURE_N = 2;
- private static final int SET_GEOMETRY_N = 3;
- private static final int SET_MATRIX_N = 4;
-
- // This is an ordered list of base message ids to allow removal of a single item from the
- // list for a particular card. The implementation currently supports up to a million cards.
- private static final int REQUEST_TEXTURE_N = 1000000;
- private static final int REQUEST_DETAIL_TEXTURE_N = 2000000;
- private static final int REQUEST_GEOMETRY_N = 3000000;
- private static final int REQUEST_END = 4000000;
-
- private HandlerThread mHandlerThread;
- private Context mContext;
- private CarouselView mCarouselView;
- private boolean DBG = false;
- private long HOLDOFF_DELAY = 100;
- private Handler mAsyncHandler; // Background thread handler for reading textures, geometry, etc.
- private Handler mSyncHandler; // Synchronous handler for interacting with UI elements.
-
- public static class TextureParameters {
- public TextureParameters() { matrix = new Matrix4f(); }
- public TextureParameters(Matrix4f _matrix) { matrix = _matrix; }
- public Matrix4f matrix;
- };
-
- public static class DetailTextureParameters {
- public DetailTextureParameters(float textureOffsetX, float textureOffsetY) {
- this.textureOffsetX = textureOffsetX;
- this.textureOffsetY = textureOffsetY;
- this.lineOffsetX = 0.0f;
- this.lineOffsetY = 0.0f;
- }
- public DetailTextureParameters(
- float textureOffsetX, float textureOffsetY,
- float lineOffsetX, float lineOffsetY) {
- this.textureOffsetX = textureOffsetX;
- this.textureOffsetY = textureOffsetY;
- this.lineOffsetX = lineOffsetX;
- this.lineOffsetY = lineOffsetY;
- }
- public float textureOffsetX;
- public float textureOffsetY;
- public float lineOffsetX;
- public float lineOffsetY;
- };
-
- public void setCarouselView(CarouselView carouselView) {
- mCarouselView = carouselView;
- mCarouselView.setCallback(this);
- }
-
- public CarouselViewHelper(Context context, CarouselView carouselView) {
- this(context);
- setCarouselView(carouselView);
- }
-
- public CarouselViewHelper(Context context) {
- mContext = context;
-
- mHandlerThread = new HandlerThread(TAG + ".handler");
- mHandlerThread.start();
-
- mAsyncHandler = new AsyncHandler(mHandlerThread.getLooper());
- mSyncHandler = new SyncHandler(); // runs in calling thread
- }
-
- class AsyncHandler extends Handler {
- AsyncHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- int id = msg.arg1;
- if (id >= mCarouselView.getCardCount()) {
- Log.e(TAG, "Index out of range for get, card:" + id);
- return;
- }
- if (msg.what < REQUEST_TEXTURE_N || msg.what > REQUEST_END) {
- Log.e(TAG, "Unknown message: " + id);
- return;
- }
- if (msg.what < REQUEST_DETAIL_TEXTURE_N) {
- // REQUEST_TEXTURE_N
- final Bitmap bitmap = getTexture(id);
- if (bitmap != null) {
- mSyncHandler.obtainMessage(SET_TEXTURE_N, id, 0, bitmap).sendToTarget();
- }
-
- TextureParameters params = getTextureParameters(id);
- if (params != null) {
- mSyncHandler.obtainMessage(SET_MATRIX_N, id, 0,
- params.matrix.getArray()).sendToTarget();
- }
- } else if (msg.what < REQUEST_GEOMETRY_N) {
- // REQUEST_DETAIL_TEXTURE_N
- final Bitmap bitmap = getDetailTexture(id);
- if (bitmap != null) {
- mSyncHandler.obtainMessage(SET_DETAIL_TEXTURE_N, id, 0, bitmap).sendToTarget();
- }
- } else if (msg.what < REQUEST_END) {
- // REQUEST_GEOMETRY_N
- Mesh mesh = getGeometry(id);
- if (mesh != null) {
- mSyncHandler.obtainMessage(SET_GEOMETRY_N, id, 0, mesh).sendToTarget();
- }
- }
- }
- };
-
- class SyncHandler extends Handler {
- @Override
- public void handleMessage(Message msg) {
- int id = msg.arg1;
- if (id >= mCarouselView.getCardCount()) {
- Log.e(TAG, "Index out of range for set, card:" + id);
- return;
- }
-
- switch (msg.what) {
- case SET_TEXTURE_N:
- mCarouselView.setTextureForItem(id, (Bitmap) msg.obj);
- break;
-
- case SET_DETAIL_TEXTURE_N:
- DetailTextureParameters params = getDetailTextureParameters(id);
- float x = params != null ? params.textureOffsetX : 0.0f;
- float y = params != null ? params.textureOffsetY : 0.0f;
- float lx = params != null ? params.lineOffsetX : 0.0f;
- float ly = params != null ? params.lineOffsetY : 0.0f;
- mCarouselView.setDetailTextureForItem(id, x, y, lx, ly, (Bitmap) msg.obj);
- break;
-
- case SET_GEOMETRY_N:
- mCarouselView.setGeometryForItem(id, (Mesh) msg.obj);
- break;
-
- case SET_MATRIX_N:
- mCarouselView.setMatrixForItem(id, (float[]) msg.obj);
- break;
- }
- }
- };
-
- /**
- * Implement this method if you want to load a texture for
- * the given card. Most subclasses will implement this. Note: this will generally
- * <b>not</b> be called in the UI thread, so proper locking should be ensured.
- *
- * @param id of the texture to load
- * @return a valid bitmap
- */
- public Bitmap getTexture(int id) {
- return null;
- }
-
- /**
- * Implement this method if you want to load a detail texture for
- * the given card. Most subclasses will implement this. Note: this will generally
- * <b>not</b> be called in the UI thread, so proper locking should be ensured.
- *
- * @param id
- * @return
- */
- public Bitmap getDetailTexture(int id) {
- return null;
- }
-
- /**
- * Implement this method if you want to load geometry for the given card. Most subclasses
- * will implement this. Note: this will generally <b>not</b> be called in the UI thread,
- * so proper locking should be ensured.
- *
- * @param id
- * @return
- */
- public Mesh getGeometry(int id) {
- return null;
- }
-
- /**
- * Implement this method if you want custom texture parameters for
- * the given id. Note: this will generally
- * <b>not</b> be called in the UI thread, so proper locking should be ensured.
- *
- * @param id
- * @return texture parameters
- */
- public TextureParameters getTextureParameters(int id) {
- return null;
- }
-
- /**
- * Implement this method if you want custom detail texture parameters for
- * the given id. Note: this will generally
- * <b>not</b> be called in the UI thread, so proper locking should be ensured.
- *
- * @param id the id of the texture being requested
- * @return detail texture parameters
- */
- public DetailTextureParameters getDetailTextureParameters(int id) {
- return null;
- }
-
- public void onRequestTexture(int id) {
- if (DBG) Log.v(TAG, "onRequestTexture(" + id + ")" );
- mAsyncHandler.removeMessages(REQUEST_TEXTURE_N + id);
- Message message = mAsyncHandler.obtainMessage(REQUEST_TEXTURE_N + id, id, 0);
- mAsyncHandler.sendMessageDelayed(message, HOLDOFF_DELAY);
- }
-
- public void onInvalidateTexture(final int id) {
- if (DBG) Log.v(TAG, "onInvalidateTexture(" + id + ")");
- mAsyncHandler.removeMessages(REQUEST_TEXTURE_N + id);
- }
-
- public void onRequestGeometry(int id) {
- if (DBG) Log.v(TAG, "onRequestGeometry(" + id + ")");
- mAsyncHandler.removeMessages(REQUEST_GEOMETRY_N + id);
- mAsyncHandler.sendMessage(mAsyncHandler.obtainMessage(REQUEST_GEOMETRY_N + id, id, 0));
- }
-
- public void onInvalidateGeometry(int id) {
- if (DBG) Log.v(TAG, "onInvalidateGeometry(" + id + ")");
- mAsyncHandler.removeMessages(REQUEST_GEOMETRY_N + id);
- }
-
- public void onRequestDetailTexture(int id) {
- if (DBG) Log.v(TAG, "onRequestDetailTexture(" + id + ")" );
- mAsyncHandler.removeMessages(REQUEST_DETAIL_TEXTURE_N + id);
- Message message = mAsyncHandler.obtainMessage(REQUEST_DETAIL_TEXTURE_N + id, id, 0);
- mAsyncHandler.sendMessageDelayed(message, HOLDOFF_DELAY);
- }
-
- public void onInvalidateDetailTexture(int id) {
- if (DBG) Log.v(TAG, "onInvalidateDetailTexture(" + id + ")");
- mAsyncHandler.removeMessages(REQUEST_DETAIL_TEXTURE_N + id);
- }
-
- public void onCardSelected(int n) {
- if (DBG) Log.v(TAG, "onCardSelected(" + n + ")");
- }
-
- public void onDetailSelected(int n, int x, int y) {
- if (DBG) Log.v(TAG, "onDetailSelected(" + n + ", " + x + ", " + y + ")");
- }
-
- public void onCardLongPress(int n, int touchPosition[], Rect detailCoordinates) {
- if (DBG) Log.v(TAG, "onCardLongPress(" + n + ", (" + touchPosition + "), (" +
- detailCoordinates +") )");
- }
-
- public void onAnimationStarted() {
-
- }
-
- public void onAnimationFinished(float carouselRotationAngle) {
-
- }
-
- public void onResume() {
- mCarouselView.resume();
- }
-
- public void onPause() {
- mCarouselView.pause();
- }
-
- public void onDestroy() {
- mHandlerThread.quit();
- }
-
- protected Handler getAsyncHandler() {
- return mAsyncHandler;
- }
-
- protected CarouselView getCarouselView() {
- return mCarouselView;
- }
-}
diff --git a/carousel/java/com/android/ex/carousel/CarouselViewUtilities.java b/carousel/java/com/android/ex/carousel/CarouselViewUtilities.java
deleted file mode 100644
index 8b53734..0000000
--- a/carousel/java/com/android/ex/carousel/CarouselViewUtilities.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.android.ex.carousel;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.media.MediaScannerConnection;
-import android.os.Environment;
-import android.util.Log;
-
-public class CarouselViewUtilities {
- /**
- * Debug utility to write the given bitmap to a file.
- *
- * @param context calling context
- * @param bitmap the bitmap to write
- * @param filename the name of the file to write
- * @return
- */
- public static boolean writeBitmapToFile(Context context, Bitmap bitmap, String filename) {
- File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
- File file = new File(path, filename);
- boolean result = false;
- try {
- path.mkdirs();
- OutputStream os = new FileOutputStream(file);
- MediaScannerConnection.scanFile(context, new String[] { file.toString() }, null, null);
- bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
- result = true;
- } catch (IOException e) {
- Log.w("ExternalStorage", "Error writing " + file, e);
- }
- return result;
- }
-
-}
diff --git a/carousel/java/com/android/ex/carousel/carousel.rs b/carousel/java/com/android/ex/carousel/carousel.rs
deleted file mode 100644
index e4dcc65..0000000
--- a/carousel/java/com/android/ex/carousel/carousel.rs
+++ /dev/null
@@ -1,1884 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(com.android.ex.carousel);
-#pragma rs set_reflect_license()
-
-#include "rs_graphics.rsh"
-
-typedef struct __attribute__((aligned(4))) Card {
- // *** Update initCard if you add/remove fields here.
- rs_allocation texture; // basic card texture
- rs_allocation detailTexture; // screen-aligned detail texture
- float2 detailTextureOffset; // offset to add, in screen coordinates
- float2 detailLineOffset; // offset to add to detail line, in screen coordinates
- float2 detailTexturePosition[2]; // screen coordinates of detail texture, computed at draw time
- rs_mesh geometry;
- rs_matrix4x4 matrix; // custom transform for this card/geometry
- int textureState; // whether or not the primary card texture is loaded.
- int detailTextureState; // whether or not the detail for the card is loaded.
- int geometryState; // whether or not geometry is loaded
- int cardVisible; // not bool because of packing bug?
- int detailVisible; // not bool because of packing bug?
- int shouldPrefetch; // not bool because of packing bug?
- int64_t textureTimeStamp; // time when this texture was last updated, in ms
- int64_t detailTextureTimeStamp; // time when this texture was last updated, in ms
- int64_t geometryTimeStamp; // time when the card itself was last updated, in ms
-} Card_t;
-
-typedef struct Ray_s {
- float3 position;
- float3 direction;
-} Ray;
-
-typedef struct Plane_s {
- float3 point;
- float3 normal;
- float constant;
-} Plane;
-
-typedef struct Cylinder_s {
- float3 center; // center of a y-axis-aligned infinite cylinder
- float radius;
-} Cylinder;
-
-typedef struct PerspectiveCamera_s {
- float3 from;
- float3 at;
- float3 up;
- float fov;
- float aspect;
- float near;
- float far;
-} PerspectiveCamera;
-
-typedef struct ProgramStore_s {
- rs_program_store programStore;
-} ProgramStore_t;
-
-typedef struct FragmentShaderConstants_s {
- float fadeAmount;
- float overallAlpha;
-} FragmentShaderConstants;
-
-// Request states. Used for loading 3D object properties from the Java client.
-// Typical properties: texture, geometry and matrices.
-enum {
- STATE_INVALID = 0, // item hasn't been loaded
- STATE_LOADING, // we've requested an item but are waiting for it to load
- STATE_STALE, // we have an old item, but should request an update
- STATE_UPDATING, // we've requested an update, and will display the old one in the meantime
- STATE_LOADED // item was delivered
-};
-
-// Interpolation modes ** THIS LIST MUST MATCH THOSE IN CarouselView.java ***
-enum {
- INTERPOLATION_LINEAR = 0,
- INTERPOLATION_DECELERATE_QUADRATIC = 1,
- INTERPOLATION_ACCELERATE_DECELERATE_CUBIC = 2,
-};
-
-// Detail texture alignments ** THIS LIST MUST MATCH THOSE IN CarouselView.java ***
-enum {
- /** Detail is centered vertically with respect to the card **/
- CENTER_VERTICAL = 1,
- /** Detail is aligned with the top edge of the carousel view **/
- VIEW_TOP = 1 << 1,
- /** Detail is aligned with the bottom edge of the carousel view (not yet implemented) **/
- VIEW_BOTTOM = 1 << 2,
- /** Detail is positioned above the card (not yet implemented) **/
- ABOVE = 1 << 3,
- /** Detail is positioned below the card **/
- BELOW = 1 << 4,
- /** Mask that selects those bits that control vertical alignment **/
- VERTICAL_ALIGNMENT_MASK = 0xff,
-
- /**
- * Detail is centered horizontally with respect to either the top or bottom
- * extent of the card, depending on whether the detail is above or below the card.
- */
- CENTER_HORIZONTAL = 1 << 8,
- /**
- * Detail is aligned with the left edge of either the top or the bottom of
- * the card, depending on whether the detail is above or below the card.
- */
- LEFT = 1 << 9,
- /**
- * Detail is aligned with the right edge of either the top or the bottom of
- * the card, depending on whether the detail is above or below the card.
- * (not yet implemented)
- */
- RIGHT = 1 << 10,
- /** Mask that selects those bits that control horizontal alignment **/
- HORIZONTAL_ALIGNMENT_MASK = 0xff00,
-};
-
-// Client messages *** THIS LIST MUST MATCH THOSE IN CarouselRS.java. ***
-static const int CMD_CARD_SELECTED = 100;
-static const int CMD_DETAIL_SELECTED = 105;
-static const int CMD_CARD_LONGPRESS = 110;
-static const int CMD_REQUEST_TEXTURE = 200;
-static const int CMD_INVALIDATE_TEXTURE = 210;
-static const int CMD_REQUEST_GEOMETRY = 300;
-static const int CMD_INVALIDATE_GEOMETRY = 310;
-static const int CMD_ANIMATION_STARTED = 400;
-static const int CMD_ANIMATION_FINISHED = 500;
-static const int CMD_REQUEST_DETAIL_TEXTURE = 600;
-static const int CMD_INVALIDATE_DETAIL_TEXTURE = 610;
-static const int CMD_PING = 1000;
-
-// Drag model *** THIS LIST MUST MATCH THOSE IN CarouselRS.java. ***
-static const int DRAG_MODEL_SCREEN_DELTA = 0; // Drag relative to x coordinate of motion vector
-static const int DRAG_MODEL_PLANE = 1; // Drag relative to projected point on plane of carousel
-static const int DRAG_MODEL_CYLINDER_INSIDE = 2; // Drag relative to point on inside of cylinder
-static const int DRAG_MODEL_CYLINDER_OUTSIDE = 3; // Drag relative to point on outside of cylinder
-
-// Constants
-static const int ANIMATION_DELAY_TIME = 125; // hold off scale animation until this time
-static const int ANIMATION_SCALE_UP_TIME = 200; // Time it takes to animate selected card, in ms
-static const int ANIMATION_SCALE_DOWN_TIME = 200; // Time it takes to animate selected card, in ms
-static const float3 SELECTED_SCALE_FACTOR = { 0.1f, 0.1f, 0.1f }; // increase by this %
-static const int VELOCITY_HISTORY_MAX = 10; // # recent velocity samples used to calculate average
-static const int VISIBLE_SLOT_PADDING = 2; // # slots to draw on either side of visible slots
-
-// Constants affecting tilt overscroll. Some of these should be parameters.
-static const int TILT_SLOT_NUMBER = 5;
-static const float TILT_MIN_ANGLE = M_PI / 315.0f;
-static const float TILT_MAX_BIAS = M_PI / 8.0f;
-static const float TILT_MAX_ANGLE = M_PI / 8.0f;
-static const float MAX_DELTA_BIAS = 0.008f;
-
-// Debug flags
-const bool debugCamera = false; // dumps ray/camera coordinate stuff
-const bool debugSelection = false; // logs selection events
-const bool debugTextureLoading = false; // for debugging texture load/unload
-const bool debugGeometryLoading = false; // for debugging geometry load/unload
-const bool debugDetails = false; // for debugging detail texture geometry
-const bool debugRendering = false; // flashes display when the frame changes
-const bool debugRays = false; // shows visual depiction of hit tests, See renderWithRays().
-
-// Exported variables. These will be reflected to Java set_* variables.
-Card_t *cards; // array of cards to draw
-float startAngle; // position of initial card, in radians
-int slotCount; // number of positions where a card can be
-int cardCount; // number of cards in stack
-int programStoresCardCount; // number of program fragment stores
-int visibleSlotCount; // number of visible slots (for culling)
-int visibleDetailCount; // number of visible detail textures to show
-int prefetchCardCount; // how many cards to keep in memory
-int detailTextureAlignment; // How to align detail texture with respect to card
-bool drawRuler; // whether to draw a ruler from the card to the detail texture
-float radius; // carousel radius. Cards will be centered on a circle with this radius
-float cardRotation; // rotation of card in XY plane relative to Z=1
-bool cardsFaceTangent; // whether cards are rotated to face along a tangent to the circle
-float swaySensitivity; // how much to rotate cards in relation to the rotation velocity
-float frictionCoeff; // how much to slow down the carousel over time
-float dragFactor; // a scale factor for how sensitive the carousel is to user dragging
-int fadeInDuration; // amount of time (in ms) for smoothly switching out textures
-int cardCreationFadeDuration; // amount of time (in ms) to fade while initially showing a card
-float rezInCardCount; // this controls how rapidly distant card textures will be rez-ed in
-float detailFadeRate; // rate at which details fade as they move into the distance
-float4 backgroundColor;
-int rowCount; // number of rows of cards in a given slot, default 1
-float rowSpacing; // spacing between rows of cards
-bool firstCardTop; // set true for first card on top row when multiple rows used
-float overscrollSlots; // amount of allowed overscroll (in slots)
-
-int dragModel = DRAG_MODEL_SCREEN_DELTA;
-int fillDirection; // the order in which to lay out cards: +1 for CCW (default), -1 for CW
-ProgramStore_t *programStoresCard;
-rs_program_store programStoreBackground;
-rs_program_store programStoreDetail;
-rs_program_fragment singleTextureFragmentProgram;
-rs_program_fragment singleTextureBlendingFragmentProgram;
-rs_program_fragment multiTextureFragmentProgram;
-rs_program_fragment multiTextureBlendingFragmentProgram;
-rs_program_vertex vertexProgram;
-rs_program_raster rasterProgram;
-rs_allocation defaultTexture; // shown when no other texture is assigned
-rs_allocation loadingTexture; // progress texture (shown when app is fetching the texture)
-rs_allocation backgroundTexture; // drawn behind everything, if set
-rs_allocation detailLineTexture; // used to draw detail line (as a quad, of course)
-rs_allocation detailLoadingTexture; // used when detail texture is loading
-rs_mesh defaultGeometry; // shown when no geometry is loaded
-rs_mesh loadingGeometry; // shown when geometry is loading
-rs_matrix4x4 defaultCardMatrix;
-rs_matrix4x4 projectionMatrix;
-rs_matrix4x4 modelviewMatrix;
-FragmentShaderConstants* shaderConstants;
-rs_sampler linearClamp;
-
-// Local variables
-static float bias; // rotation bias, in radians. Used for animation and dragging.
-static float overscrollBias; // Track overscroll bias separately for tilt effect.
-static bool updateCamera; // force a recompute of projection and lookat matrices
-static const float FLT_MAX = 1.0e37;
-static int animatedSelection = -1;
-static int currentFirstCard = -1;
-static int64_t touchTime = -1; // time of first touch (see doStart())
-static int64_t releaseTime = 0L; // when touch was released
-static float touchBias = 0.0f; // bias on first touch
-static float2 touchPosition; // position of first touch, as defined by last call to doStart(x,y)
-static float velocity = 0.0f; // angular velocity in radians/s
-static bool isOverScrolling = false; // whether we're in the overscroll animation
-static bool isAutoScrolling = false; // whether we're in the autoscroll animation
-static bool isDragging = false; // true while the user is dragging the carousel
-static float selectionRadius = 50.0f; // movement greater than this will result in no selection
-static bool enableSelection = false; // enabled until the user drags outside of selectionRadius
-static float tiltAngle = 0.0f;
-
-// Default plane of the carousel. Used for angular motion estimation in view.
-static Plane carouselPlane = {
- { 0.0f, 0.0f, 0.0f }, // point
- { 0.0f, 1.0f, 0.0f }, // normal
- 0.0f // plane constant (= -dot(P, N))
-};
-
-static Cylinder carouselCylinder = {
- {0.0f, 0.0f, 0.0f }, // center
- 1.0f // radius - update with carousel radius.
-};
-
-// Because allocations can't have 0 dimensions, we have to track whether or not
-// cards and program stores are valid separately.
-// TODO: Remove this dependency once allocations can have a zero dimension.
-static bool cardAllocationValid = false;
-static bool programStoresAllocationValid = false;
-
-// Default geometry when card.geometry is not set.
-static const float3 cardVertices[4] = {
- { -1.0, -1.0, 0.0 },
- { 1.0, -1.0, 0.0 },
- { 1.0, 1.0, 0.0 },
- {-1.0, 1.0, 0.0 }
-};
-
-// Default camera
-static PerspectiveCamera camera = {
- {2,2,2}, // from
- {0,0,0}, // at
- {0,1,0}, // up
- 25.0f, // field of view
- 1.0f, // aspect
- 0.1f, // near
- 100.0f // far
-};
-
-// Forward references
-static int intersectGeometry(Ray* ray, float *bestTime);
-static int intersectDetailTexture(float x, float y, float2 *tapCoordinates);
-static bool __attribute__((overloadable))
- makeRayForPixelAt(Ray* ray, PerspectiveCamera* cam, float x, float y);
-static bool __attribute__((overloadable))
- makeRayForPixelAt(Ray* ray, rs_matrix4x4* model, rs_matrix4x4* proj, float x, float y);
-static float deltaTimeInSeconds(int64_t current);
-static bool rayPlaneIntersect(Ray* ray, Plane* plane, float* tout);
-static bool rayCylinderIntersect(Ray* ray, Cylinder* cylinder, float* tout);
-static void stopAutoscroll();
-static bool tiltOverscroll();
-
-void init() {
- // initializers currently have a problem when the variables are exported, so initialize
- // globals here.
- if (debugTextureLoading) rsDebug("Renderscript: init()", 0);
- startAngle = 0.0f;
- slotCount = 10;
- visibleSlotCount = 1;
- visibleDetailCount = 3;
- bias = 0.0f;
- overscrollBias = 0.0f;
- tiltAngle = 0.0f;
- radius = carouselCylinder.radius = 1.0f;
- cardRotation = 0.0f;
- cardsFaceTangent = false;
- updateCamera = true;
- backgroundColor = (float4) { 0.0f, 0.0f, 0.0f, 1.0f };
- cardAllocationValid = false;
- programStoresAllocationValid = false;
- cardCount = 0;
- rowCount = 1;
- rowSpacing = 0.0f;
- firstCardTop = false;
- fadeInDuration = 250;
- rezInCardCount = 0.0f; // alpha will ramp to 1.0f over this many cards (0.0f means disabled)
- detailFadeRate = 0.5f; // fade details over this many slot positions.
- rsMatrixLoadIdentity(&defaultCardMatrix);
-}
-
-static void updateAllocationVars()
-{
- // Cards
- rs_allocation cardAlloc;
- cardAlloc = rsGetAllocation(cards);
- cardCount = (cardAllocationValid && rsIsObject(cardAlloc)) ? rsAllocationGetDimX(cardAlloc) : 0;
-
- // Program stores
- rs_allocation psAlloc;
- psAlloc = rsGetAllocation(programStoresCard);
- programStoresCardCount = (programStoresAllocationValid && rsIsObject(psAlloc) ?
- rsAllocationGetDimX(psAlloc) : 0);
-}
-
-void setRadius(float rad)
-{
- radius = carouselCylinder.radius = rad;
-}
-
-static void initCard(Card_t* card)
-{
- // Object refs are always initilized cleared.
- static const float2 zero = {0.0f, 0.0f};
- card->detailTextureOffset = zero;
- card->detailLineOffset = zero;
- rsMatrixLoad(&card->matrix, &defaultCardMatrix);
- card->textureState = STATE_INVALID;
- card->detailTextureState = STATE_INVALID;
- card->geometryState = STATE_INVALID;
- card->cardVisible = false;
- card->detailVisible = false;
- card->shouldPrefetch = false;
- card->textureTimeStamp = 0;
- card->detailTextureTimeStamp = 0;
- card->geometryTimeStamp = rsUptimeMillis();
-}
-
-void createCards(int start, int total)
-{
- if (!cardAllocationValid) {
- // If the allocation is invalid, it contains a single place-holder
- // card that has not yet been initialized (see CarouselRS.createCards).
- // Here we ensure that it is initialized when growing the total.
- start = 0;
- }
- for (int k = start; k < total; k++) {
- initCard(cards + k);
- }
-
- // Since allocations can't have 0-size, we track validity ourselves based on the call to
- // this method.
- cardAllocationValid = total > 0;
-
- updateAllocationVars();
-}
-
-// Computes an alpha value for a card using elapsed time and constant fadeInDuration
-static float getAnimatedAlpha(int64_t startTime, int64_t currentTime, int64_t duration)
-{
- double timeElapsed = (double) (currentTime - startTime); // in ms
- double alpha = duration > 0 ? (double) timeElapsed / duration : 1.0;
- return min(1.0f, (float) alpha);
-}
-
-// Returns total angle for given number of slots
-static float wedgeAngle(float slots)
-{
- return slots * 2.0f * M_PI / slotCount;
-}
-
-// Return angle of slot in position p.
-static float slotPosition(int p)
-{
- return startAngle + wedgeAngle(p) * fillDirection;
-}
-
-// Return angle for card in position p.
-static float cardPosition(int p)
-{
- return bias + slotPosition(p / rowCount);
-}
-
-// Return the lowest possible bias value, based on the fill direction
-static float minimumBias()
-{
- const int totalSlots = (cardCount + rowCount - 1) / rowCount;
- return (fillDirection > 0) ?
- -max(0.0f, wedgeAngle(totalSlots - visibleDetailCount)) :
- wedgeAngle(0.0f);
-}
-
-// Return the highest possible bias value, based on the fill direction
-static float maximumBias()
-{
- const int totalSlots = (cardCount + rowCount - 1) / rowCount;
- return (fillDirection > 0) ?
- wedgeAngle(0.0f) :
- max(0.0f, wedgeAngle(totalSlots - visibleDetailCount));
-}
-
-
-// convert from carousel rotation angle (in card slot units) to radians.
-static float carouselRotationAngleToRadians(float carouselRotationAngle)
-{
- return -wedgeAngle(carouselRotationAngle);
-}
-
-// convert from radians to carousel rotation angle (in card slot units).
-static float radiansToCarouselRotationAngle(float angle)
-{
- return -angle * slotCount / ( 2.0f * M_PI );
-}
-
-// Set basic camera properties:
-// from - position of the camera in x,y,z
-// at - target we're looking at - used to compute view direction
-// up - a normalized vector indicating up (typically { 0, 1, 0})
-//
-// NOTE: the view direction and up vector cannot be parallel/antiparallel with each other
-void lookAt(float fromX, float fromY, float fromZ,
- float atX, float atY, float atZ,
- float upX, float upY, float upZ)
-{
- camera.from.x = fromX;
- camera.from.y = fromY;
- camera.from.z = fromZ;
- camera.at.x = atX;
- camera.at.y = atY;
- camera.at.z = atZ;
- camera.up.x = upX;
- camera.up.y = upY;
- camera.up.z = upZ;
- updateCamera = true;
-}
-
-// Load a projection matrix for the given parameters. This is equivalent to gluPerspective()
-static void loadPerspectiveMatrix(rs_matrix4x4* matrix, float fovy, float aspect, float near, float far)
-{
- rsMatrixLoadIdentity(matrix);
- float top = near * tan((float) (fovy * M_PI / 360.0f));
- float bottom = -top;
- float left = bottom * aspect;
- float right = top * aspect;
- rsMatrixLoadFrustum(matrix, left, right, bottom, top, near, far);
-}
-
-// Construct a matrix based on eye point, center and up direction. Based on the
-// man page for gluLookat(). Up must be normalized.
-static void loadLookatMatrix(rs_matrix4x4* matrix, float3 eye, float3 center, float3 up)
-{
- float3 f = normalize(center - eye);
- float3 s = normalize(cross(f, up));
- float3 u = cross(s, f);
- float m[16];
- m[0] = s.x;
- m[4] = s.y;
- m[8] = s.z;
- m[12] = 0.0f;
- m[1] = u.x;
- m[5] = u.y;
- m[9] = u.z;
- m[13] = 0.0f;
- m[2] = -f.x;
- m[6] = -f.y;
- m[10] = -f.z;
- m[14] = 0.0f;
- m[3] = m[7] = m[11] = 0.0f;
- m[15] = 1.0f;
- rsMatrixLoad(matrix, m);
- rsMatrixTranslate(matrix, -eye.x, -eye.y, -eye.z);
-}
-
-/*
- * Returns true if a state represents a texture that is loaded enough to draw
- */
-static bool textureEverLoaded(int state) {
- return (state == STATE_LOADED) || (state == STATE_STALE) || (state == STATE_UPDATING);
-}
-
-void setTexture(int n, rs_allocation texture)
-{
- if (n < 0 || n >= cardCount) return;
- cards[n].texture = texture;
- if (cards[n].textureState != STATE_STALE &&
- cards[n].textureState != STATE_UPDATING) {
- cards[n].textureTimeStamp = rsUptimeMillis();
- }
- cards[n].textureState = (texture.p != 0) ? STATE_LOADED : STATE_INVALID;
-}
-
-void setDetailTexture(int n, float offx, float offy, float loffx, float loffy, rs_allocation texture)
-{
- if (n < 0 || n >= cardCount) return;
- cards[n].detailTexture = texture;
- if (cards[n].detailTextureState != STATE_STALE &&
- cards[n].detailTextureState != STATE_UPDATING) {
- cards[n].detailTextureTimeStamp = rsUptimeMillis();
- }
- cards[n].detailTextureOffset.x = offx;
- cards[n].detailTextureOffset.y = offy;
- cards[n].detailLineOffset.x = loffx;
- cards[n].detailLineOffset.y = loffy;
- cards[n].detailTextureState = (texture.p != 0) ? STATE_LOADED : STATE_INVALID;
-}
-
-void invalidateTexture(int n, bool eraseCurrent)
-{
- if (n < 0 || n >= cardCount) return;
- if (eraseCurrent) {
- cards[n].textureState = STATE_INVALID;
- rsClearObject(&cards[n].texture);
- } else {
- cards[n].textureState =
- textureEverLoaded(cards[n].textureState) ? STATE_STALE : STATE_INVALID;
- }
-}
-
-void invalidateDetailTexture(int n, bool eraseCurrent)
-{
- if (n < 0 || n >= cardCount) return;
- if (eraseCurrent) {
- cards[n].detailTextureState = STATE_INVALID;
- rsClearObject(&cards[n].detailTexture);
- } else {
- cards[n].detailTextureState =
- textureEverLoaded(cards[n].detailTextureState) ? STATE_STALE : STATE_INVALID;
- }
-}
-
-void setGeometry(int n, rs_mesh geometry)
-{
- if (n < 0 || n >= cardCount) return;
- cards[n].geometry = geometry;
- if (cards[n].geometry.p != 0)
- cards[n].geometryState = STATE_LOADED;
- else
- cards[n].geometryState = STATE_INVALID;
- cards[n].geometryTimeStamp = rsUptimeMillis();
-}
-
-void setMatrix(int n, rs_matrix4x4 matrix) {
- if (n < 0 || n >= cardCount) return;
- cards[n].matrix = matrix;
-}
-
-void setProgramStoresCard(int n, rs_program_store programStore)
-{
- programStoresCard[n].programStore = programStore;
- programStoresAllocationValid = true;
-}
-
-void setCarouselRotationAngle(float carouselRotationAngle) {
- bias = carouselRotationAngleToRadians(carouselRotationAngle);
-}
-
-// Gets animated scale value for current selected card.
-// If card is currently being animated, returns true, otherwise returns false.
-static bool getAnimatedScaleForSelected(float3* scale)
-{
- static const float3 one = { 1.0f, 1.0f, 1.0f };
- static float fraction = 0.0f;
- bool stillAnimating = false;
- if (isDragging) {
- // "scale up" animation
- int64_t dt = rsUptimeMillis() - touchTime - ANIMATION_DELAY_TIME;
- if (dt > 0L && enableSelection) {
- float s = (float) dt / ANIMATION_SCALE_UP_TIME;
- s = min(s, 1.0f);
- fraction = max(s, fraction);
- }
- stillAnimating = dt < ANIMATION_SCALE_UP_TIME;
- } else {
- // "scale down" animation
- int64_t dt = rsUptimeMillis() - releaseTime;
- if (dt < ANIMATION_SCALE_DOWN_TIME) {
- float s = 1.0f - ((float) dt / ANIMATION_SCALE_DOWN_TIME);
- fraction = min(s, fraction);
- stillAnimating = true;
- } else {
- fraction = 0.0f;
- }
- }
- *scale = one + fraction * SELECTED_SCALE_FACTOR;
- return stillAnimating; // still animating;
-}
-
-// The Verhulst logistic function: http://en.wikipedia.org/wiki/Logistic_function
-// P(t) = 1 / (1 + e^(-t))
-// Parameter t: Any real number
-// Returns: A float in the range (0,1), with P(0.5)=0
-static float logistic(float t) {
- return 1.f / (1.f + exp(-t));
-}
-
-static float getSwayAngleForVelocity(float v, bool enableSway)
-{
- float sway = 0.0f;
-
- if (enableSway) {
- const float range = M_PI * 2./3.; // How far we can deviate from center, peak-to-peak
- sway = range * (logistic(-v * swaySensitivity) - 0.5f);
- }
-
- return sway;
-}
-
-static float getCardTiltAngle(int i) {
- i /= rowCount;
- int totalSlots = (cardCount + rowCount - 1) / rowCount;
- float tiltSlotNumber = TILT_SLOT_NUMBER;
- float deltaTilt = tiltAngle / tiltSlotNumber;
- float cardTiltAngle = 0;
- if (tiltAngle > 0 && i < tiltSlotNumber) {
- // Overscroll for the front cards.
- cardTiltAngle = deltaTilt * (tiltSlotNumber - i);
- } else if (tiltAngle < 0 && i > (totalSlots - tiltSlotNumber)) {
- cardTiltAngle = deltaTilt * (i - totalSlots + tiltSlotNumber + 1);
- }
- return cardTiltAngle;
-}
-
-// Returns the vertical offset for a card in its slot,
-// depending on the number of rows configured.
-static float getVerticalOffsetForCard(int i) {
- if (rowCount == 1) {
- // fast path
- return 0;
- }
- const float cardHeight = (cardVertices[3].y - cardVertices[0].y) *
- rsMatrixGet(&defaultCardMatrix, 1, 1);
- const float totalHeight = rowCount * (cardHeight + rowSpacing) - rowSpacing;
- if (firstCardTop)
- i = rowCount - (i % rowCount) - 1;
- else
- i = i % rowCount;
- const float rowOffset = i * (cardHeight + rowSpacing);
- return (cardHeight - totalHeight) / 2 + rowOffset;
-}
-
-/*
- * Composes a matrix for the given card.
- * matrix: The output matrix.
- * i: The card we're getting the matrix for.
- * enableSway: Whether to enable swaying. (We want it on for cards, and off for detail textures.)
- * enableCardMatrix: Whether to also consider the user-specified card matrix
- *
- * returns true if an animation is being applied to the given card
- */
-static bool getMatrixForCard(rs_matrix4x4* matrix, int i, bool enableSway, bool enableCardMatrix)
-{
- float theta = cardPosition(i);
- float swayAngle = getSwayAngleForVelocity(velocity, enableSway);
- rsMatrixRotate(matrix, degrees(theta), 0, 1, 0);
- rsMatrixTranslate(matrix, radius, getVerticalOffsetForCard(i), 0);
- float tiltAngle = getCardTiltAngle(i);
- float rotation = cardRotation + swayAngle + tiltAngle;
- if (!cardsFaceTangent) {
- rotation -= theta;
- }
- rsMatrixRotate(matrix, degrees(rotation), 0, 1, 0);
- bool stillAnimating = false;
- if (i == animatedSelection) {
- float3 scale;
- stillAnimating = getAnimatedScaleForSelected(&scale);
- rsMatrixScale(matrix, scale.x, scale.y, scale.z);
- }
- // TODO(jshuma): Instead of ignoring this matrix for the detail texture, use card bounding box
- if (enableCardMatrix) {
- rsMatrixLoadMultiply(matrix, matrix, &cards[i].matrix);
- }
- return stillAnimating;
-}
-
-/*
- * Draws the requested mesh, with the appropriate program store in effect.
- */
-static void drawMesh(rs_mesh mesh)
-{
- if (programStoresCardCount == 1) {
- // Draw the entire mesh, with the only available program store
- rsgBindProgramStore(programStoresCard[0].programStore);
- rsgDrawMesh(mesh);
- } else {
- // Draw each primitive in the mesh with the corresponding program store
- for (int i=0; i<programStoresCardCount; ++i) {
- if (programStoresCard[i].programStore.p != 0) {
- rsgBindProgramStore(programStoresCard[i].programStore);
- rsgDrawMesh(mesh, i);
- }
- }
- }
-}
-
-/*
- * Draws cards around the Carousel.
- * Returns true if we're still animating any property of the cards (e.g. fades).
- */
-static bool drawCards(int64_t currentTime)
-{
- const float wedgeAngle = 2.0f * M_PI / slotCount;
- const float endAngle = startAngle + visibleSlotCount * wedgeAngle;
- bool stillAnimating = false;
- for (int i = cardCount-1; i >= 0; i--) {
- if (cards[i].cardVisible) {
- // If this card was recently loaded, this will be < 1.0f until the animation completes
- float animatedAlpha = getAnimatedAlpha(cards[i].textureTimeStamp, currentTime,
- fadeInDuration);
- float overallAlpha = getAnimatedAlpha(cards[i].geometryTimeStamp, currentTime,
- cardCreationFadeDuration);
- if (animatedAlpha < 1.0f || overallAlpha < 1.0f) {
- stillAnimating = true;
- }
-
- // Compute fade out for cards in the distance
- float positionAlpha;
- if (rezInCardCount > 0.0f) {
- positionAlpha = (endAngle - cardPosition(i)) / wedgeAngle;
- positionAlpha = min(1.0f, positionAlpha / rezInCardCount);
- } else {
- positionAlpha = 1.0f;
- }
-
- // Set alpha for blending between the textures
- shaderConstants->fadeAmount = min(1.0f, animatedAlpha * positionAlpha);
- shaderConstants->overallAlpha = overallAlpha;
- rsgAllocationSyncAll(rsGetAllocation(shaderConstants));
-
- // Bind the appropriate shader network. If there's no alpha blend, then
- // switch to single shader for better performance.
- const int state = cards[i].textureState;
- bool loaded = textureEverLoaded(state) && rsIsObject(cards[i].texture);
- if (shaderConstants->fadeAmount == 1.0f || shaderConstants->fadeAmount < 0.01f) {
- if (overallAlpha < 1.0) {
- rsgBindProgramFragment(singleTextureBlendingFragmentProgram);
- rsgBindTexture(singleTextureBlendingFragmentProgram, 0,
- (loaded && shaderConstants->fadeAmount == 1.0f) ?
- cards[i].texture : loadingTexture);
- } else {
- rsgBindProgramFragment(singleTextureFragmentProgram);
- rsgBindTexture(singleTextureFragmentProgram, 0,
- (loaded && shaderConstants->fadeAmount == 1.0f) ?
- cards[i].texture : loadingTexture);
- }
- } else {
- if (overallAlpha < 1.0) {
- rsgBindProgramFragment(multiTextureBlendingFragmentProgram);
- rsgBindTexture(multiTextureBlendingFragmentProgram, 0, loadingTexture);
- rsgBindTexture(multiTextureBlendingFragmentProgram, 1, loaded ?
- cards[i].texture : loadingTexture);
- } else {
- rsgBindProgramFragment(multiTextureFragmentProgram);
- rsgBindTexture(multiTextureFragmentProgram, 0, loadingTexture);
- rsgBindTexture(multiTextureFragmentProgram, 1, loaded ?
- cards[i].texture : loadingTexture);
- }
- }
-
- // Draw geometry
- rs_matrix4x4 matrix = modelviewMatrix;
- stillAnimating |= getMatrixForCard(&matrix, i, true, true);
- rsgProgramVertexLoadModelMatrix(&matrix);
- if (cards[i].geometryState == STATE_LOADED && cards[i].geometry.p != 0) {
- drawMesh(cards[i].geometry);
- } else if (cards[i].geometryState == STATE_LOADING && loadingGeometry.p != 0) {
- drawMesh(loadingGeometry);
- } else if (defaultGeometry.p != 0) {
- drawMesh(defaultGeometry);
- } else {
- // Draw place-holder geometry
- rsgBindProgramStore(programStoresCard[0].programStore);
- rsgDrawQuad(
- cardVertices[0].x, cardVertices[0].y, cardVertices[0].z,
- cardVertices[1].x, cardVertices[1].y, cardVertices[1].z,
- cardVertices[2].x, cardVertices[2].y, cardVertices[2].z,
- cardVertices[3].x, cardVertices[3].y, cardVertices[3].z);
- }
- }
- }
- return stillAnimating;
-}
-
-/**
- * Convert projection from normalized coordinates to pixel coordinates.
- *
- * @return True on success, false on failure.
- */
-static bool convertNormalizedToPixelCoordinates(float4 *screenCoord, float width, float height) {
- // This is probably cheaper than pre-multiplying with another matrix.
- if (screenCoord->w == 0.0f) {
- rsDebug("Bad transform while converting from normalized to pixel coordinates: ",
- screenCoord);
- return false;
- }
- *screenCoord *= 1.0f / screenCoord->w;
- screenCoord->x += 1.0f;
- screenCoord->y += 1.0f;
- screenCoord->z += 1.0f;
- screenCoord->x = round(screenCoord->x * 0.5f * width);
- screenCoord->y = round(screenCoord->y * 0.5f * height);
- screenCoord->z = - 0.5f * screenCoord->z;
- return true;
-}
-
-/*
- * Draws a screen-aligned card with the exact dimensions from the detail texture.
- * This is used to display information about the object being displayed.
- * Returns true if we're still animating any property of the cards (e.g. fades).
- */
-static bool drawDetails(int64_t currentTime)
-{
- const float width = rsgGetWidth();
- const float height = rsgGetHeight();
-
- bool stillAnimating = false;
-
- // We'll be drawing in screen space, sampled on pixel centers
- rs_matrix4x4 projection, model;
- rsMatrixLoadOrtho(&projection, 0.0f, width, 0.0f, height, 0.0f, 1.0f);
- rsgProgramVertexLoadProjectionMatrix(&projection);
- rsMatrixLoadIdentity(&model);
- rsgProgramVertexLoadModelMatrix(&model);
- updateCamera = true; // we messed with the projection matrix. Reload on next pass...
-
- const float yPadding = 5.0f; // draw line this far (in pixels) away from top and geometry
-
- // This can be done once...
- rsgBindTexture(multiTextureFragmentProgram, 0, detailLoadingTexture);
-
- const float wedgeAngle = 2.0f * M_PI / slotCount;
- // Angle where details start fading from 1.0f
- const float startDetailFadeAngle = startAngle + (visibleDetailCount - 1) * wedgeAngle;
- // Angle where detail alpha is 0.0f
- const float endDetailFadeAngle = startDetailFadeAngle + detailFadeRate * wedgeAngle;
-
- for (int i = cardCount-1; i >= 0; --i) {
- if (cards[i].cardVisible) {
- const int state = cards[i].detailTextureState;
- const bool isLoaded = textureEverLoaded(state);
- if (isLoaded && cards[i].detailTexture.p != 0) {
- const float lineWidth = rsAllocationGetDimX(detailLineTexture);
-
- // Compute position in screen space of top corner or bottom corner of card
- rsMatrixLoad(&model, &modelviewMatrix);
- stillAnimating |= getMatrixForCard(&model, i, false, false);
- rs_matrix4x4 matrix;
- rsMatrixLoadMultiply(&matrix, &projectionMatrix, &model);
-
- int indexLeft, indexRight;
- float4 screenCoord;
- if (detailTextureAlignment & BELOW) {
- indexLeft = 0;
- indexRight = 1;
- } else {
- indexLeft = 3;
- indexRight = 2;
- }
- float4 screenCoordLeft = rsMatrixMultiply(&matrix, cardVertices[indexLeft]);
- float4 screenCoordRight = rsMatrixMultiply(&matrix, cardVertices[indexRight]);
- if (screenCoordLeft.w == 0.0f || screenCoordRight.w == 0.0f) {
- // this shouldn't happen
- rsDebug("Bad transform: ", screenCoord);
- continue;
- }
- if (detailTextureAlignment & CENTER_VERTICAL) {
- // If we're centering vertically, we'll need the other vertices too
- if (detailTextureAlignment & BELOW) {
- indexLeft = 3;
- indexRight = 2;
- } else {
- indexLeft = 0;
- indexRight = 1;
- }
- float4 otherScreenLeft = rsMatrixMultiply(&matrix, cardVertices[indexLeft]);
- float4 otherScreenRight = rsMatrixMultiply(&matrix, cardVertices[indexRight]);
- screenCoordRight.y = screenCoordLeft.y = (screenCoordLeft.y + screenCoordRight.y
- + otherScreenLeft.y + otherScreenRight.y) / 4.;
- }
- (void) convertNormalizedToPixelCoordinates(&screenCoordLeft, width, height);
- (void) convertNormalizedToPixelCoordinates(&screenCoordRight, width, height);
- if (debugDetails) {
- RS_DEBUG(screenCoordLeft);
- RS_DEBUG(screenCoordRight);
- }
- screenCoord = screenCoordLeft;
- if (detailTextureAlignment & BELOW) {
- screenCoord.y = min(screenCoordLeft.y, screenCoordRight.y);
- } else if (detailTextureAlignment & CENTER_VERTICAL) {
- screenCoord.y -= round(rsAllocationGetDimY(cards[i].detailTexture) / 2.0f);
- }
- if (detailTextureAlignment & CENTER_HORIZONTAL) {
- screenCoord.x += round((screenCoordRight.x - screenCoordLeft.x) / 2.0f -
- rsAllocationGetDimX(cards[i].detailTexture) / 2.0f);
- }
-
- // Compute alpha for gradually fading in details. Applied to both line and
- // detail texture. TODO: use a separate background texture for line.
- float animatedAlpha = getAnimatedAlpha(cards[i].detailTextureTimeStamp,
- currentTime, fadeInDuration);
- if (animatedAlpha < 1.0f) {
- stillAnimating = true;
- }
-
- // Compute alpha based on position. We fade cards quickly so they cannot overlap
- float positionAlpha = ((float)endDetailFadeAngle - cardPosition(i))
- / (endDetailFadeAngle - startDetailFadeAngle);
- positionAlpha = max(0.0f, positionAlpha);
- positionAlpha = min(1.0f, positionAlpha);
-
- const float blendedAlpha = min(1.0f, animatedAlpha * positionAlpha);
-
- if (blendedAlpha == 0.0f) {
- cards[i].detailVisible = false;
- continue; // nothing to draw
- } else {
- cards[i].detailVisible = true;
- }
- if (blendedAlpha == 1.0f) {
- rsgBindProgramFragment(singleTextureFragmentProgram);
- } else {
- rsgBindProgramFragment(multiTextureFragmentProgram);
- }
-
- // Set alpha for blending between the textures
- shaderConstants->fadeAmount = blendedAlpha;
- rsgAllocationSyncAll(rsGetAllocation(shaderConstants));
-
- // Draw line from the card to the detail texture.
- // The line is drawn from the top or bottom left of the card
- // to either the top of the screen or the top of the detail
- // texture, depending on detailTextureAlignment.
- if (drawRuler) {
- float rulerTop;
- float rulerBottom;
- if (detailTextureAlignment & BELOW) {
- rulerTop = screenCoord.y;
- rulerBottom = 0;
- } else {
- rulerTop = height;
- rulerBottom = screenCoord.y;
- }
- const float halfWidth = lineWidth * 0.5f;
- const float x0 = trunc(cards[i].detailLineOffset.x + screenCoord.x - halfWidth);
- const float x1 = x0 + lineWidth;
- const float y0 = rulerBottom + yPadding;
- const float y1 = rulerTop - yPadding - cards[i].detailLineOffset.y;
-
- if (blendedAlpha == 1.0f) {
- rsgBindTexture(singleTextureFragmentProgram, 0, detailLineTexture);
- } else {
- rsgBindTexture(multiTextureFragmentProgram, 1, detailLineTexture);
- }
- rsgDrawQuad(x0, y0, screenCoord.z, x1, y0, screenCoord.z,
- x1, y1, screenCoord.z, x0, y1, screenCoord.z);
- }
-
- // Draw the detail texture next to it using the offsets provided.
- const float textureWidth = rsAllocationGetDimX(cards[i].detailTexture);
- const float textureHeight = rsAllocationGetDimY(cards[i].detailTexture);
- const float offx = cards[i].detailTextureOffset.x;
- const float offy = -cards[i].detailTextureOffset.y;
- const float textureTop = (detailTextureAlignment & VIEW_TOP)
- ? height : screenCoord.y;
- const float x0 = cards[i].detailLineOffset.x + screenCoord.x + offx;
- const float x1 = cards[i].detailLineOffset.x + screenCoord.x + offx + textureWidth;
- const float y0 = textureTop + offy - textureHeight - cards[i].detailLineOffset.y;
- const float y1 = textureTop + offy - cards[i].detailLineOffset.y;
- cards[i].detailTexturePosition[0].x = x0;
- cards[i].detailTexturePosition[0].y = height - y1;
- cards[i].detailTexturePosition[1].x = x1;
- cards[i].detailTexturePosition[1].y = height - y0;
-
- if (blendedAlpha == 1.0f) {
- rsgBindTexture(singleTextureFragmentProgram, 0, cards[i].detailTexture);
- } else {
- rsgBindTexture(multiTextureFragmentProgram, 1, cards[i].detailTexture);
- }
- rsgDrawQuad(x0, y0, screenCoord.z, x1, y0, screenCoord.z,
- x1, y1, screenCoord.z, x0, y1, screenCoord.z);
- }
- }
- }
- return stillAnimating;
-}
-
-static void drawBackground()
-{
- static bool toggle;
- if (backgroundTexture.p != 0) {
- rsgClearDepth(1.0f);
- rs_matrix4x4 projection, model;
- rsMatrixLoadOrtho(&projection, -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f);
- rsgProgramVertexLoadProjectionMatrix(&projection);
- rsMatrixLoadIdentity(&model);
- rsgProgramVertexLoadModelMatrix(&model);
- rsgBindTexture(singleTextureFragmentProgram, 0, backgroundTexture);
- float z = -0.9999f;
- rsgDrawQuad(
- cardVertices[0].x, cardVertices[0].y, z,
- cardVertices[1].x, cardVertices[1].y, z,
- cardVertices[2].x, cardVertices[2].y, z,
- cardVertices[3].x, cardVertices[3].y, z);
- updateCamera = true; // we mucked with the matrix.
- } else {
- rsgClearDepth(1.0f);
- if (debugRendering) { // for debugging - flash the screen so we know we're still rendering
- rsgClearColor(toggle ? backgroundColor.x : 1.0f,
- toggle ? backgroundColor.y : 0.0f,
- toggle ? backgroundColor.z : 0.0f,
- backgroundColor.w);
- toggle = !toggle;
- } else {
- rsgClearColor(backgroundColor.x, backgroundColor.y, backgroundColor.z,
- backgroundColor.w);
- }
- }
-}
-
-static void updateCameraMatrix(float width, float height)
-{
- float aspect = width / height;
- if (aspect != camera.aspect || updateCamera) {
- camera.aspect = aspect;
- loadPerspectiveMatrix(&projectionMatrix, camera.fov, camera.aspect, camera.near, camera.far);
- rsgProgramVertexLoadProjectionMatrix(&projectionMatrix);
-
- loadLookatMatrix(&modelviewMatrix, camera.from, camera.at, camera.up);
- rsgProgramVertexLoadModelMatrix(&modelviewMatrix);
- updateCamera = false;
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Behavior/Physics
-////////////////////////////////////////////////////////////////////////////////////////////////////
-static int64_t lastTime = 0L; // keep track of how much time has passed between frames
-static float lastAngle = 0.0f;
-static float2 lastPosition;
-static bool animating = false;
-static float stopVelocity = 0.1f * M_PI / 180.0f; // slower than this: carousel stops
-static float selectionVelocity = 15.0f * M_PI / 180.0f; // faster than this: tap won't select
-static float velocityHistory[VELOCITY_HISTORY_MAX];
-static int velocityHistoryCount;
-static float mass = 5.0f; // kg
-
-static const float G = 9.80f; // gravity constant, in m/s
-static const float springConstant = 0.0f;
-
-// Computes a hit angle from the center of the carousel to a point on either a plane
-// or on a cylinder. If neither is hit, returns false.
-static bool hitAngle(float x, float y, float *angle)
-{
- Ray ray;
- makeRayForPixelAt(&ray, &camera, x, y);
- float t = FLT_MAX;
- if (dragModel == DRAG_MODEL_PLANE && rayPlaneIntersect(&ray, &carouselPlane, &t)) {
- const float3 point = (ray.position + t*ray.direction);
- const float3 direction = point - carouselPlane.point;
- *angle = atan2(direction.x, direction.z);
- if (debugSelection) rsDebug("Plane Angle = ", degrees(*angle));
- return true;
- } else if ((dragModel == DRAG_MODEL_CYLINDER_INSIDE || dragModel == DRAG_MODEL_CYLINDER_OUTSIDE)
- && rayCylinderIntersect(&ray, &carouselCylinder, &t)) {
- const float3 point = (ray.position + t*ray.direction);
- const float3 direction = point - carouselCylinder.center;
- *angle = atan2(direction.x, direction.z);
- if (debugSelection) rsDebug("Cylinder Angle = ", degrees(*angle));
- return true;
- }
- return false;
-}
-
-static float dragFunction(float x, float y)
-{
- float result;
- float angle;
- if (hitAngle(x, y, &angle)) {
- result = angle - lastAngle;
- // Handle singularity where atan2 switches between +- PI
- if (result < -M_PI) {
- result += 2.0f * M_PI;
- } else if (result > M_PI) {
- result -= 2.0f * M_PI;
- }
- lastAngle = angle;
- } else {
- // If we didn't hit anything or drag model wasn't plane or cylinder, we use screen delta
- result = dragFactor * ((x - lastPosition.x) / rsgGetWidth()) * M_PI;
- }
- return result;
-}
-
-static float deltaTimeInSeconds(int64_t current)
-{
- return (lastTime > 0L) ? (float) (current - lastTime) / 1000.0f : 0.0f;
-}
-
-static int doSelection(float x, float y)
-{
- Ray ray;
- if (makeRayForPixelAt(&ray, &camera, x, y)) {
- float bestTime = FLT_MAX;
- return intersectGeometry(&ray, &bestTime);
- }
- return -1;
-}
-
-static void sendAnimationStarted() {
- rsSendToClient(CMD_ANIMATION_STARTED);
-}
-
-static void sendAnimationFinished() {
- float data[1];
- data[0] = radiansToCarouselRotationAngle(bias);
- rsSendToClient(CMD_ANIMATION_FINISHED, (int*) data, sizeof(data));
-}
-
-void doStart(float x, float y, long eventTime)
-{
- touchPosition = lastPosition = (float2) { x, y };
- lastAngle = hitAngle(x,y, &lastAngle) ? lastAngle : 0.0f;
- enableSelection = fabs(velocity) < selectionVelocity;
- velocity = 0.0f;
- velocityHistory[0] = 0.0f;
- velocityHistoryCount = 0;
-
- releaseTime = lastTime; // used to disable scale down animation - any time in the past will do
- touchTime = lastTime = eventTime;
- touchBias = bias;
- isDragging = true;
- isOverScrolling = false;
- tiltAngle = 0;
- overscrollBias = bias;
-
- animatedSelection = doSelection(x, y); // used to provide visual feedback on touch
- stopAutoscroll();
-}
-
-static float computeAverageVelocityFromHistory()
-{
- if (velocityHistoryCount > 0) {
- const int count = min(VELOCITY_HISTORY_MAX, velocityHistoryCount);
- float vsum = 0.0f;
- for (int i = 0; i < count; i++) {
- vsum += velocityHistory[i];
- }
- return vsum / count;
- } else {
- return 0.0f;
- }
-}
-
-void doStop(float x, float y, long eventTime)
-{
- updateAllocationVars();
-
- releaseTime = rsUptimeMillis();
-
- if (enableSelection) {
- int data[3];
- int selection;
- float2 point;
-
- if ((selection = intersectDetailTexture(x, y, &point)) != -1) {
- if (debugSelection) rsDebug("Selected detail texture on doStop():", selection);
- data[0] = selection;
- data[1] = point.x;
- data[2] = point.y;
- rsSendToClientBlocking(CMD_DETAIL_SELECTED, data, sizeof(data));
- }
- else if ((selection = doSelection(x, y))!= -1) {
- if (debugSelection) rsDebug("Selected item on doStop():", selection);
- data[0] = selection;
- rsSendToClientBlocking(CMD_CARD_SELECTED, data, sizeof(data));
- }
- animating = false;
- } else {
- velocity = computeAverageVelocityFromHistory();
- if (fabs(velocity) > stopVelocity) {
- animating = true;
- }
- }
- enableSelection = false;
- lastTime = eventTime;
- isDragging = false;
-}
-
-void doLongPress()
-{
- int64_t currentTime = rsUptimeMillis();
- updateAllocationVars();
- // Selection happens for most recent position detected in doMotion()
- if (enableSelection && animatedSelection != -1) {
- if (debugSelection) rsDebug("doLongPress(), selection = ", animatedSelection);
- int data[7];
- data[0] = animatedSelection;
- data[1] = lastPosition.x;
- data[2] = lastPosition.y;
- data[3] = cards[animatedSelection].detailTexturePosition[0].x;
- data[4] = cards[animatedSelection].detailTexturePosition[0].y;
- data[5] = cards[animatedSelection].detailTexturePosition[1].x;
- data[6] = cards[animatedSelection].detailTexturePosition[1].y;
- rsSendToClientBlocking(CMD_CARD_LONGPRESS, data, sizeof(data));
- enableSelection = false;
- }
- lastTime = rsUptimeMillis();
-}
-
-void doMotion(float x, float y, long eventTime)
-{
- const float highBias = maximumBias();
- const float lowBias = minimumBias();
- float deltaOmega = dragFunction(x, y);
- overscrollBias += deltaOmega;
- overscrollBias = clamp(overscrollBias, lowBias - TILT_MAX_BIAS,
- highBias + TILT_MAX_BIAS);
- bias = clamp(overscrollBias, lowBias, highBias);
- isOverScrolling = tiltOverscroll();
-
- const float2 delta = (float2) { x, y } - touchPosition;
- float distance = sqrt(dot(delta, delta));
- bool inside = (distance < selectionRadius);
- enableSelection &= inside;
- lastPosition = (float2) { x, y };
- float dt = deltaTimeInSeconds(eventTime);
- if (dt > 0.0f) {
- float v = deltaOmega / dt;
- velocityHistory[velocityHistoryCount % VELOCITY_HISTORY_MAX] = v;
- velocityHistoryCount++;
- }
- velocity = computeAverageVelocityFromHistory();
- lastTime = eventTime;
-}
-
-bool tiltOverscroll() {
- if (overscrollBias == bias) {
- // No overscroll required.
- return false;
- }
-
- // How much we deviate from the maximum bias.
- float deltaBias = overscrollBias - bias;
- // We clamped, that means we need overscroll.
- tiltAngle = (deltaBias / TILT_MAX_BIAS)
- * TILT_MAX_ANGLE * fillDirection;
-
- return true;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Autoscroll Interpolation
-////////////////////////////////////////////////////////////////////////////////////////////////////
-static int64_t autoscrollStartTime = 0L; //tracks when we actually started interpolating
-static int64_t autoscrollDuration = 0L; //in milli seconds
-static int autoscrollInterpolationMode = INTERPOLATION_LINEAR;
-
-static float autoscrollStopAngle = 0.0f;
-static float autoscrollStartAngle = 0.0f;
-
-void setCarouselRotationAngle2(
- float endAngle,
- int milliseconds,
- int interpolationMode,
- float maxAnimatedArc)
-{
- float actualStart = radiansToCarouselRotationAngle(bias);
-
- if (maxAnimatedArc > 0) {
- //snap the current position to keep end - start under maxAnimatedArc
- if (actualStart <= endAngle) {
- if (actualStart < endAngle - maxAnimatedArc) {
- actualStart = endAngle - maxAnimatedArc;
- }
- }
- else {
- if (actualStart > endAngle + maxAnimatedArc) {
- actualStart = endAngle + maxAnimatedArc;
- }
- }
- }
-
- animating = true;
- isAutoScrolling = true;
- autoscrollDuration = milliseconds;
- autoscrollInterpolationMode = interpolationMode;
- autoscrollStartAngle = carouselRotationAngleToRadians(actualStart);
- autoscrollStopAngle = carouselRotationAngleToRadians(endAngle);
-
- //Make sure the start and stop angles are in the allowed range
- const float highBias = maximumBias();
- const float lowBias = minimumBias();
- autoscrollStartAngle = clamp(autoscrollStartAngle, lowBias, highBias);
- autoscrollStopAngle = clamp(autoscrollStopAngle, lowBias, highBias);
-
- //stop other animation kinds
- isOverScrolling = false;
- velocity = 0.0f;
-}
-
-static void stopAutoscroll()
-{
- isAutoScrolling = false;
- autoscrollStartTime = 0L; //reset for next time
-}
-
-// This method computes the position of all the cards by updating bias based on a
-// simple interpolation model. If the cards are still in motion, returns true.
-static bool doAutoscroll(float currentTime)
-{
- if (autoscrollDuration == 0L) {
- return false;
- }
-
- if (autoscrollStartTime == 0L) {
- autoscrollStartTime = currentTime;
- }
-
- const int64_t interpolationEndTime = autoscrollStartTime + autoscrollDuration;
-
- float timePos = (currentTime - autoscrollStartTime) / (float)autoscrollDuration;
- if (timePos > 1.0f) {
- timePos = 1.0f;
- }
-
- float lambda = timePos; //default to linear
- if (autoscrollInterpolationMode == INTERPOLATION_DECELERATE_QUADRATIC) {
- lambda = 1.0f - (1.0f - timePos) * (1.0f - timePos);
- }
- else if (autoscrollInterpolationMode == INTERPOLATION_ACCELERATE_DECELERATE_CUBIC) {
- lambda = timePos * timePos * (3 - 2 * timePos);
- }
-
- bias = lambda * autoscrollStopAngle + (1.0 - lambda) * autoscrollStartAngle;
-
- if (currentTime > interpolationEndTime) {
- stopAutoscroll();
- return false;
- }
- else {
- return true;
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Hit detection using ray casting.
-////////////////////////////////////////////////////////////////////////////////////////////////////
-static const float EPSILON = 1.0e-6f;
-static const float tmin = 0.0f;
-
-static bool
-rayTriangleIntersect(Ray* ray, float3 p0, float3 p1, float3 p2, float* tout)
-{
- float3 e1 = p1 - p0;
- float3 e2 = p2 - p0;
- float3 s1 = cross(ray->direction, e2);
-
- float div = dot(s1, e1);
- if (div == 0.0f) return false; // ray is parallel to plane.
-
- float3 d = ray->position - p0;
- float invDiv = 1.0f / div;
-
- float u = dot(d, s1) * invDiv;
- if (u < 0.0f || u > 1.0f) return false;
-
- float3 s2 = cross(d, e1);
- float v = dot(ray->direction, s2) * invDiv;
- if ( v < 0.0f || (u+v) > 1.0f) return false;
-
- float t = dot(e2, s2) * invDiv;
- if (t < tmin || t > *tout)
- return false;
- *tout = t;
- return true;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Computes ray/plane intersection. Returns false if no intersection found.
-////////////////////////////////////////////////////////////////////////////////////////////////////
-static bool
-rayPlaneIntersect(Ray* ray, Plane* plane, float* tout)
-{
- float denom = dot(ray->direction, plane->normal);
- if (fabs(denom) > EPSILON) {
- float t = - (plane->constant + dot(ray->position, plane->normal)) / denom;
- if (t > tmin && t < *tout) {
- *tout = t;
- return true;
- }
- }
- return false;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Computes ray/cylindr intersection. There are 0, 1 or 2 hits.
-// Returns true and sets *tout to the closest point or
-// returns false if no intersection found.
-////////////////////////////////////////////////////////////////////////////////////////////////////
-static bool
-rayCylinderIntersect(Ray* ray, Cylinder* cylinder, float* tout)
-{
- const float A = ray->direction.x * ray->direction.x + ray->direction.z * ray->direction.z;
- if (A < EPSILON) return false; // ray misses
-
- // Compute quadratic equation coefficients
- const float B = 2.0f * (ray->direction.x * ray->position.x
- + ray->direction.z * ray->position.z);
- const float C = ray->position.x * ray->position.x
- + ray->position.z * ray->position.z
- - cylinder->radius * cylinder->radius;
- float disc = B*B - 4*A*C;
-
- if (disc < 0.0f) return false; // ray misses
- disc = sqrt(disc);
- const float denom = 2.0f * A;
-
- // Nearest point
- const float t1 = (-B - disc) / denom;
- if (dragModel == DRAG_MODEL_CYLINDER_OUTSIDE && t1 > tmin && t1 < *tout) {
- *tout = t1;
- return true;
- }
-
- // Far point
- const float t2 = (-B + disc) / denom;
- if (dragModel == DRAG_MODEL_CYLINDER_INSIDE && t2 > tmin && t2 < *tout) {
- *tout = t2;
- return true;
- }
- return false;
-}
-
-// Creates a ray for an Android pixel coordinate given a camera, ray and coordinates.
-// Note that the Y coordinate is opposite of GL rendering coordinates.
-static bool __attribute__((overloadable))
-makeRayForPixelAt(Ray* ray, PerspectiveCamera* cam, float x, float y)
-{
- if (debugCamera) {
- rsDebug("------ makeRay() -------", 0);
- rsDebug("Camera.from:", cam->from);
- rsDebug("Camera.at:", cam->at);
- rsDebug("Camera.dir:", normalize(cam->at - cam->from));
- }
-
- // Vector math. This has the potential to be much faster.
- // TODO: pre-compute lowerLeftRay, du, dv to eliminate most of this math.
- const float u = x / rsgGetWidth();
- const float v = 1.0f - (y / rsgGetHeight());
- const float aspect = (float) rsgGetWidth() / rsgGetHeight();
- const float tanfov2 = 2.0f * tan(radians(cam->fov / 2.0f));
- float3 dir = normalize(cam->at - cam->from);
- float3 du = tanfov2 * normalize(cross(dir, cam->up));
- float3 dv = tanfov2 * normalize(cross(du, dir));
- du *= aspect;
- float3 lowerLeftRay = dir - (0.5f * du) - (0.5f * dv);
- const float3 rayPoint = cam->from;
- const float3 rayDir = normalize(lowerLeftRay + u*du + v*dv);
- if (debugCamera) {
- rsDebug("Ray direction (vector math) = ", rayDir);
- }
-
- ray->position = rayPoint;
- ray->direction = rayDir;
- return true;
-}
-
-// Creates a ray for an Android pixel coordinate given a model view and projection matrix.
-// Note that the Y coordinate is opposite of GL rendering coordinates.
-static bool __attribute__((overloadable))
-makeRayForPixelAt(Ray* ray, rs_matrix4x4* model, rs_matrix4x4* proj, float x, float y)
-{
- rs_matrix4x4 pm = *model;
- rsMatrixLoadMultiply(&pm, proj, model);
- if (!rsMatrixInverse(&pm)) {
- rsDebug("ERROR: SINGULAR PM MATRIX", 0);
- return false;
- }
- const float width = rsgGetWidth();
- const float height = rsgGetHeight();
- const float winx = 2.0f * x / width - 1.0f;
- const float winy = 2.0f * y / height - 1.0f;
-
- float4 eye = { 0.0f, 0.0f, 0.0f, 1.0f };
- float4 at = { winx, winy, 1.0f, 1.0f };
-
- eye = rsMatrixMultiply(&pm, eye);
- eye *= 1.0f / eye.w;
-
- at = rsMatrixMultiply(&pm, at);
- at *= 1.0f / at.w;
-
- const float3 rayPoint = { eye.x, eye.y, eye.z };
- const float3 atPoint = { at.x, at.y, at.z };
- const float3 rayDir = normalize(atPoint - rayPoint);
- if (debugCamera) {
- rsDebug("winx: ", winx);
- rsDebug("winy: ", winy);
- rsDebug("Ray position (transformed) = ", eye);
- rsDebug("Ray direction (transformed) = ", rayDir);
- }
- ray->position = rayPoint;
- ray->direction = rayDir;
- return true;
-}
-
-static int intersectDetailTexture(float x, float y, float2 *tapCoordinates)
-{
- for (int id = 0; id < cardCount; id++) {
- if (cards[id].detailVisible) {
- const int x0 = cards[id].detailTexturePosition[0].x;
- const int y0 = cards[id].detailTexturePosition[0].y;
- const int x1 = cards[id].detailTexturePosition[1].x;
- const int y1 = cards[id].detailTexturePosition[1].y;
- if (x >= x0 && x <= x1 && y >= y0 && y <= y1) {
- float2 point = { x - x0, y - y0 };
- *tapCoordinates = point;
- return id;
- }
- }
- }
- return -1;
-}
-
-static int intersectGeometry(Ray* ray, float *bestTime)
-{
- int hit = -1;
- for (int id = 0; id < cardCount; id++) {
- if (cards[id].cardVisible) {
- rs_matrix4x4 matrix;
- float3 p[4];
-
- // Transform card vertices to world space
- rsMatrixLoadIdentity(&matrix);
- getMatrixForCard(&matrix, id, true, true);
- for (int vertex = 0; vertex < 4; vertex++) {
- float4 tmp = rsMatrixMultiply(&matrix, cardVertices[vertex]);
- if (tmp.w != 0.0f) {
- p[vertex].x = tmp.x;
- p[vertex].y = tmp.y;
- p[vertex].z = tmp.z;
- p[vertex] *= 1.0f / tmp.w;
- } else {
- rsDebug("Bad w coord: ", tmp);
- }
- }
-
- // Intersect card geometry
- if (rayTriangleIntersect(ray, p[0], p[1], p[2], bestTime)
- || rayTriangleIntersect(ray, p[2], p[3], p[0], bestTime)) {
- hit = id;
- }
- }
- }
- return hit;
-}
-
-// This method computes the position of all the cards by updating bias based on a
-// simple physics model. If the cards are still in motion, returns true.
-static bool doPhysics(float dt)
-{
- const float minStepTime = 1.0f / 300.0f; // ~5 steps per frame
- const int N = (dt > minStepTime) ? (1 + round(dt / minStepTime)) : 1;
- dt /= N;
- for (int i = 0; i < N; i++) {
- // Force friction - always opposes motion
- const float Ff = -frictionCoeff * velocity;
-
- // Restoring force to match cards with slots
- const float theta = startAngle + bias;
- const float dtheta = 2.0f * M_PI / slotCount;
- const float position = theta / dtheta;
- const float fraction = position - floor(position); // fractional position between slots
- float x;
- if (fraction > 0.5f) {
- x = - (1.0f - fraction);
- } else {
- x = fraction;
- }
- const float Fr = - springConstant * x;
-
- // compute velocity
- const float momentum = mass * velocity + (Ff + Fr)*dt;
- velocity = momentum / mass;
- bias += velocity * dt;
- }
- return fabs(velocity) > stopVelocity;
-}
-
-static float easeOut(float x)
-{
- return x;
-}
-
-// Computes the next value for bias using the current animation (physics/overscroll/autoscrolling)
-static bool updateNextPosition(int64_t currentTime)
-{
- static const float biasMin = 1e-4f; // close enough if we're within this margin of result
-
- float dt = deltaTimeInSeconds(currentTime);
-
- if (dt <= 0.0f) {
- if (debugRendering) rsDebug("Time delta was <= 0", dt);
- return true;
- }
-
- const float firstBias = maximumBias();
- const float lastBias = minimumBias();
- bool stillAnimating = false;
- if (isOverScrolling) {
- if (tiltAngle > TILT_MIN_ANGLE) {
- tiltAngle -= dt * TILT_MAX_ANGLE;
- stillAnimating = true;
- } else if (tiltAngle < -TILT_MIN_ANGLE) {
- tiltAngle += dt * TILT_MAX_ANGLE;
- stillAnimating = true;
- } else {
- isOverScrolling = false;
- tiltAngle = false;
- velocity = 0.0f;
- }
- } else if (isAutoScrolling) {
- stillAnimating = doAutoscroll(currentTime);
- } else {
- stillAnimating = doPhysics(dt);
- isOverScrolling = tiltAngle != 0;
- if (isOverScrolling) {
- velocity = 0.0f; // prevent bouncing due to v > 0 after overscroll animation.
- stillAnimating = true;
- }
- }
- bias = clamp(bias, lastBias, firstBias);
- return stillAnimating;
-}
-
-// Cull cards based on visibility and visibleSlotCount.
-// If visibleSlotCount is > 0, then only show those slots and cull the rest.
-// Otherwise, it should cull based on bounds of geometry.
-static void cullCards()
-{
- // Calculate the first and last angles of visible slots. We include
- // VISIBLE_SLOT_PADDING slots on either side of visibleSlotCount to allow
- // cards to slide in / out at either side, and rely on the view frustrum
- // for accurate clipping.
- const float visibleFirst = slotPosition(-VISIBLE_SLOT_PADDING);
- const float visibleLast = slotPosition(visibleSlotCount + VISIBLE_SLOT_PADDING);
-
- // We'll load but not draw prefetchCardCountPerSide cards
- // from either side of the visible slots.
- const int prefetchCardCountPerSide = max(prefetchCardCount / 2, VISIBLE_SLOT_PADDING);
- const float prefetchFirst = slotPosition(-prefetchCardCountPerSide);
- const float prefetchLast = slotPosition(visibleSlotCount + prefetchCardCountPerSide);
- for (int i = 0; i < cardCount; i++) {
- if (visibleSlotCount > 0) {
- // If visibleSlotCount is specified then only show cards between visibleFirst and visibleLast
- float p = cardPosition(i);
- if ((p >= prefetchFirst && p < prefetchLast)
- || (p <= prefetchFirst && p > prefetchLast)) {
- cards[i].shouldPrefetch = true;
- cards[i].cardVisible = (p >= visibleFirst && p < visibleLast)
- || (p <= visibleFirst && p > visibleLast);
- // cards[i].detailVisible will be set at draw time
- } else {
- cards[i].shouldPrefetch = false;
- cards[i].cardVisible = false;
- cards[i].detailVisible = false;
- }
- } else {
- // Cull the rest of the cards using bounding box of geometry.
- // TODO
- cards[i].cardVisible = true;
- // cards[i].detailVisible will be set at draw time
- }
- }
-}
-
-// Request missing texture/geometry for a single card
-static void requestCardResources(int i) {
- if (debugTextureLoading) rsDebug("*** Texture stamp: ", (int)cards[i].textureTimeStamp);
- int data[1] = { i };
-
- // request texture from client if not loaded
- if (cards[i].textureState == STATE_INVALID) {
- if (debugTextureLoading) rsDebug("Requesting card because state is STATE_INVALID", i);
- bool enqueued = rsSendToClient(CMD_REQUEST_TEXTURE, data, sizeof(data));
- if (enqueued) {
- cards[i].textureState = STATE_LOADING;
- } else {
- if (debugTextureLoading) rsDebug("Couldn't send CMD_REQUEST_TEXTURE", i);
- }
- } else if (cards[i].textureState == STATE_STALE) {
- if (debugTextureLoading) rsDebug("Requesting card because state is STATE_STALE", i);
- bool enqueued = rsSendToClient(CMD_REQUEST_TEXTURE, data, sizeof(data));
- if (enqueued) {
- cards[i].textureState = STATE_UPDATING;
- } else {
- if (debugTextureLoading) rsDebug("Couldn't send CMD_REQUEST_TEXTURE", i);
- }
- }
-
- // request detail texture from client if not loaded
- if (cards[i].detailTextureState == STATE_INVALID) {
- bool enqueued = rsSendToClient(CMD_REQUEST_DETAIL_TEXTURE, data, sizeof(data));
- if (enqueued) {
- cards[i].detailTextureState = STATE_LOADING;
- } else {
- if (debugTextureLoading) rsDebug("Couldn't send CMD_REQUEST_DETAIL_TEXTURE", i);
- }
- } else if (cards[i].detailTextureState == STATE_STALE) {
- bool enqueued = rsSendToClient(CMD_REQUEST_DETAIL_TEXTURE, data, sizeof(data));
- if (enqueued) {
- cards[i].detailTextureState = STATE_UPDATING;
- } else {
- if (debugTextureLoading) rsDebug("Couldn't send CMD_REQUEST_DETAIL_TEXTURE", i);
- }
- }
-
- // request geometry from client if not loaded
- if (cards[i].geometryState == STATE_INVALID) {
- bool enqueued = rsSendToClient(CMD_REQUEST_GEOMETRY, data, sizeof(data));
- if (enqueued) {
- cards[i].geometryState = STATE_LOADING;
- } else {
- if (debugGeometryLoading) rsDebug("Couldn't send CMD_REQUEST_GEOMETRY", i);
- }
- }
-}
-
-// Request texture/geometry for items that have come into view
-// or doesn't have a texture yet.
-static void updateCardResources(int64_t currentTime)
-{
- // First process any visible cards
- for (int i = cardCount-1; i >= 0; --i) {
- if (cards[i].cardVisible) {
- requestCardResources(i);
- }
- }
-
- // Then the rest
- for (int i = cardCount-1; i >= 0; --i) {
- if (cards[i].cardVisible) {
- // already requested above
- } else if (cards[i].shouldPrefetch) {
- requestCardResources(i);
- } else {
- // ask the host to remove the texture
- int data[1];
- if (cards[i].textureState != STATE_INVALID) {
- data[0] = i;
- bool enqueued = rsSendToClient(CMD_INVALIDATE_TEXTURE, data, sizeof(data));
- if (enqueued) {
- cards[i].textureState = STATE_INVALID;
- cards[i].textureTimeStamp = currentTime;
- } else {
- if (debugTextureLoading) rsDebug("Couldn't send CMD_INVALIDATE_TEXTURE", 0);
- }
- }
- // ask the host to remove the detail texture
- if (cards[i].detailTextureState != STATE_INVALID) {
- data[0] = i;
- bool enqueued = rsSendToClient(CMD_INVALIDATE_DETAIL_TEXTURE, data, sizeof(data));
- if (enqueued) {
- cards[i].detailTextureState = STATE_INVALID;
- cards[i].detailTextureTimeStamp = currentTime;
- } else {
- if (debugTextureLoading) rsDebug("Can't send CMD_INVALIDATE_DETAIL_TEXTURE", 0);
- }
- }
- // ask the host to remove the geometry
- if (cards[i].geometryState != STATE_INVALID) {
- data[0] = i;
- bool enqueued = rsSendToClient(CMD_INVALIDATE_GEOMETRY, data, sizeof(data));
- if (enqueued) {
- cards[i].geometryState = STATE_INVALID;
- } else {
- if (debugGeometryLoading) rsDebug("Couldn't send CMD_INVALIDATE_GEOMETRY", 0);
- }
- }
- }
- }
-}
-
-// Places dots on geometry to visually inspect that objects can be seen by rays.
-// NOTE: the color of the dot is somewhat random, as it depends on texture of previously-rendered
-// card.
-static void renderWithRays()
-{
- const float w = rsgGetWidth();
- const float h = rsgGetHeight();
- const int skip = 8;
-
- rsgProgramFragmentConstantColor(singleTextureFragmentProgram, 1.0f, 0.0f, 0.0f, 1.0f);
- for (int j = 0; j < (int) h; j+=skip) {
- float posY = (float) j;
- for (int i = 0; i < (int) w; i+=skip) {
- float posX = (float) i;
- Ray ray;
- if (makeRayForPixelAt(&ray, &camera, posX, posY)) {
- float bestTime = FLT_MAX;
- if (intersectGeometry(&ray, &bestTime) != -1) {
- rsgDrawSpriteScreenspace(posX, h - posY - 1, 0.0f, 2.0f, 2.0f);
- }
- }
- }
- }
-}
-
-int root() {
- int64_t currentTime = rsUptimeMillis();
-
- rsgBindProgramVertex(vertexProgram);
- rsgBindProgramRaster(rasterProgram);
- rsgBindSampler(singleTextureFragmentProgram, 0, linearClamp);
- rsgBindSampler(multiTextureFragmentProgram, 0, linearClamp);
- rsgBindSampler(multiTextureFragmentProgram, 1, linearClamp);
-
- updateAllocationVars();
-
- rsgBindProgramFragment(singleTextureFragmentProgram);
- // rsgClearDepth() currently follows the value of glDepthMask(), so it's disabled when
- // the mask is disabled. We may want to change the following to always draw w/o Z for
- // the background if we can guarantee the depth buffer will get cleared and
- // there's a performance advantage.
- rsgBindProgramStore(programStoreBackground);
- drawBackground();
-
- updateCameraMatrix(rsgGetWidth(), rsgGetHeight());
-
- bool stillAnimating = (currentTime - touchTime) <= ANIMATION_SCALE_UP_TIME;
-
- if (!isDragging && animating) {
- stillAnimating = updateNextPosition(currentTime);
- }
-
- lastTime = currentTime;
-
- cullCards();
-
- updateCardResources(currentTime);
-
- // Draw cards opaque only if requested, and always draw detail textures with blending.
- stillAnimating |= drawCards(currentTime);
- rsgBindProgramStore(programStoreDetail);
- stillAnimating |= drawDetails(currentTime);
-
- if (stillAnimating != animating) {
- if (stillAnimating) {
- // we just started animating
- sendAnimationStarted();
- } else {
- // we were animating but stopped animating just now
- sendAnimationFinished();
- }
- animating = stillAnimating;
- }
-
- if (debugRays) {
- renderWithRays();
- }
-
- //rsSendToClient(CMD_PING);
-
- return animating ? 1 : 0;
-}
diff --git a/carousel/test/Android.mk b/carousel/test/Android.mk
deleted file mode 100644
index e00c83c..0000000
--- a/carousel/test/Android.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files) \
- $(call all-renderscript-files-under, src) \
- ../../../../frameworks/ex/carousel/java/com/android/ex/carousel/carousel.rs
-
-LOCAL_STATIC_JAVA_LIBRARIES := android-common-carousel
-
-LOCAL_PACKAGE_NAME := CarouselWidgetTests
-LOCAL_CERTIFICATE := platform
-
-include $(BUILD_PACKAGE)
diff --git a/carousel/test/AndroidManifest.xml b/carousel/test/AndroidManifest.xml
deleted file mode 100644
index 78b819d..0000000
--- a/carousel/test/AndroidManifest.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (C) 2009 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.carouseltest">
-
- <uses-permission android:name="android.permission.GET_TASKS" />
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
- <application>
-
- <activity
- android:name="MusicDemoActivity"
- android:label="@string/music_demo_activity_label"
- android:theme="@android:style/Theme.NoTitleBar"
- android:configChanges="orientation">
-
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
-
- </activity>
-
- <activity
- android:name="CarouselTestActivity"
- android:label="@string/carousel_test_activity_label"
- android:theme="@android:style/Theme.NoTitleBar"
- android:configChanges="orientation">
-
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
-
- </activity>
-
- <activity
- android:name="TaskSwitcherActivity"
- android:label="@string/task_switcher_activity_label"
- android:theme="@android:style/Theme.NoTitleBar"
- android:configChanges="orientation">
-
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
-
- </activity>
-
- </application>
-</manifest>
diff --git a/carousel/test/res/anim/zoom_enter.xml b/carousel/test/res/anim/zoom_enter.xml
deleted file mode 100644
index f037208..0000000
--- a/carousel/test/res/anim/zoom_enter.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2009, 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.
-*/
--->
-
-<!-- Special window zoom animation: this is the element that enters the screen,
- it starts at 200% and scales down. Goes with zoom_exit.xml. -->
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:anim/decelerate_interpolator">
- <scale android:fromXScale="0.0" android:toXScale="1.0"
- android:fromYScale="0.0" android:toYScale="1.0"
- android:pivotX="50%p" android:pivotY="50%p"
- android:duration="500" />
- <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
- android:duration="500"/>
-</set>
diff --git a/carousel/test/res/anim/zoom_exit.xml b/carousel/test/res/anim/zoom_exit.xml
deleted file mode 100644
index 207f570..0000000
--- a/carousel/test/res/anim/zoom_exit.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2009, 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.
-*/
--->
-
-<!-- Special window zoom animation: this is the element that exits the
- screen, it is forced above the entering element and starts at its
- normal size (filling the screen) and scales down while fading out.
- This goes with zoom_enter.xml. -->
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:anim/decelerate_interpolator"
- android:zAdjustment="top">
- <scale android:fromXScale="1.0" android:toXScale="4.0"
- android:fromYScale="1.0" android:toYScale="4.0"
- android:pivotX="50%p" android:pivotY="50%p"
- android:duration="500" />
- <alpha android:fromAlpha="1.0" android:toAlpha="0"
- android:duration="500"/>
-</set>
diff --git a/carousel/test/res/drawable/background.png b/carousel/test/res/drawable/background.png
deleted file mode 100644
index 511f620..0000000
--- a/carousel/test/res/drawable/background.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/drawable/blank_album.png b/carousel/test/res/drawable/blank_album.png
deleted file mode 100644
index 76331d5..0000000
--- a/carousel/test/res/drawable/blank_album.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/drawable/border.png b/carousel/test/res/drawable/border.png
deleted file mode 100644
index 723b5a0..0000000
--- a/carousel/test/res/drawable/border.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/drawable/emo_im_angel.png b/carousel/test/res/drawable/emo_im_angel.png
deleted file mode 100644
index 10742a6..0000000
--- a/carousel/test/res/drawable/emo_im_angel.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/drawable/emo_im_cool.png b/carousel/test/res/drawable/emo_im_cool.png
deleted file mode 100644
index e3c8654..0000000
--- a/carousel/test/res/drawable/emo_im_cool.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/drawable/emo_im_crying.png b/carousel/test/res/drawable/emo_im_crying.png
deleted file mode 100644
index b23791c..0000000
--- a/carousel/test/res/drawable/emo_im_crying.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/drawable/emo_im_foot_in_mouth.png b/carousel/test/res/drawable/emo_im_foot_in_mouth.png
deleted file mode 100644
index 050b7be..0000000
--- a/carousel/test/res/drawable/emo_im_foot_in_mouth.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/drawable/emo_im_happy.png b/carousel/test/res/drawable/emo_im_happy.png
deleted file mode 100644
index 69e3bed..0000000
--- a/carousel/test/res/drawable/emo_im_happy.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/drawable/emo_im_kissing.png b/carousel/test/res/drawable/emo_im_kissing.png
deleted file mode 100644
index 0cca68e..0000000
--- a/carousel/test/res/drawable/emo_im_kissing.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/drawable/emo_im_laughing.png b/carousel/test/res/drawable/emo_im_laughing.png
deleted file mode 100644
index 8406ad0..0000000
--- a/carousel/test/res/drawable/emo_im_laughing.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/drawable/emo_im_lips_are_sealed.png b/carousel/test/res/drawable/emo_im_lips_are_sealed.png
deleted file mode 100644
index 222f175..0000000
--- a/carousel/test/res/drawable/emo_im_lips_are_sealed.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/drawable/emo_im_money_mouth.png b/carousel/test/res/drawable/emo_im_money_mouth.png
deleted file mode 100644
index d711bfb..0000000
--- a/carousel/test/res/drawable/emo_im_money_mouth.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/drawable/emo_im_sad.png b/carousel/test/res/drawable/emo_im_sad.png
deleted file mode 100644
index 40017f1..0000000
--- a/carousel/test/res/drawable/emo_im_sad.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/drawable/emo_im_surprised.png b/carousel/test/res/drawable/emo_im_surprised.png
deleted file mode 100644
index 4b2af7a..0000000
--- a/carousel/test/res/drawable/emo_im_surprised.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/drawable/emo_im_tongue_sticking_out.png b/carousel/test/res/drawable/emo_im_tongue_sticking_out.png
deleted file mode 100644
index 42ac80d..0000000
--- a/carousel/test/res/drawable/emo_im_tongue_sticking_out.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/drawable/emo_im_undecided.png b/carousel/test/res/drawable/emo_im_undecided.png
deleted file mode 100644
index 2cf5bd2..0000000
--- a/carousel/test/res/drawable/emo_im_undecided.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/drawable/emo_im_winking.png b/carousel/test/res/drawable/emo_im_winking.png
deleted file mode 100644
index a3a0876..0000000
--- a/carousel/test/res/drawable/emo_im_winking.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/drawable/emo_im_wtf.png b/carousel/test/res/drawable/emo_im_wtf.png
deleted file mode 100644
index 86c4bda..0000000
--- a/carousel/test/res/drawable/emo_im_wtf.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/drawable/emo_im_yelling.png b/carousel/test/res/drawable/emo_im_yelling.png
deleted file mode 100644
index cfd991a..0000000
--- a/carousel/test/res/drawable/emo_im_yelling.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/drawable/glossy_overlay.png b/carousel/test/res/drawable/glossy_overlay.png
deleted file mode 100644
index 4dfa3d9..0000000
--- a/carousel/test/res/drawable/glossy_overlay.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/drawable/specularmap.png b/carousel/test/res/drawable/specularmap.png
deleted file mode 100644
index 6b1c0d9..0000000
--- a/carousel/test/res/drawable/specularmap.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/drawable/unknown.png b/carousel/test/res/drawable/unknown.png
deleted file mode 100644
index 74bead5..0000000
--- a/carousel/test/res/drawable/unknown.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/drawable/wait.png b/carousel/test/res/drawable/wait.png
deleted file mode 100644
index e3f892f..0000000
--- a/carousel/test/res/drawable/wait.png
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/layout/carousel_test.xml b/carousel/test/res/layout/carousel_test.xml
deleted file mode 100644
index 86aa2e2..0000000
--- a/carousel/test/res/layout/carousel_test.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
- <View
- android:layout_width="match_parent"
- android:layout_height="100dip"
- android:background="#ff800000"
- android:visibility="gone"/>
-
- <com.android.carouseltest.MyCarouselView
- android:id="@+id/carousel"
- android:layout_width="match_parent"
- android:layout_height="0dip"
- android:layout_weight="1"
- android:layout_gravity="center">
- </com.android.carouseltest.MyCarouselView>
-
- <View
- android:layout_width="match_parent"
- android:layout_height="100dip"
- android:background="#ff008000"
- android:visibility="gone"/>
-
-</LinearLayout>
diff --git a/carousel/test/res/layout/music_demo.xml b/carousel/test/res/layout/music_demo.xml
deleted file mode 100644
index ba3e628..0000000
--- a/carousel/test/res/layout/music_demo.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
- <com.android.carouseltest.MyCarouselView
- android:id="@+id/carousel"
- android:layout_width="match_parent"
- android:layout_height="0dip"
- android:layout_weight="1">
- </com.android.carouseltest.MyCarouselView>>
-
-</LinearLayout>
diff --git a/carousel/test/res/layout/taskswitcher.xml b/carousel/test/res/layout/taskswitcher.xml
deleted file mode 100644
index 2d07d54..0000000
--- a/carousel/test/res/layout/taskswitcher.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
- <!-- Title -->
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="#80FFFFFF"
- android:textStyle="bold"
- android:singleLine="true"
- android:text="@string/recent_tasks_title"
- android:visibility="gone"/>
-
- <!-- This is only intended to be visible when carousel is invisible -->
- <TextView
- android:id="@+id/no_applications_message"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:text="@string/no_recent_tasks"
- android:visibility="gone"/>
-
- <com.android.carouseltest.MyCarouselView
- android:id="@+id/carousel"
- android:layout_width="match_parent"
- android:layout_height="0dip"
- android:layout_weight="1">
- </com.android.carouseltest.MyCarouselView>>
-
-</LinearLayout>
diff --git a/carousel/test/res/raw/book.a3d b/carousel/test/res/raw/book.a3d
deleted file mode 100644
index 8dcfa61..0000000
--- a/carousel/test/res/raw/book.a3d
+++ /dev/null
Binary files differ
diff --git a/carousel/test/res/values-af/strings.xml b/carousel/test/res/values-af/strings.xml
deleted file mode 100644
index 88a3538..0000000
--- a/carousel/test/res/values-af/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"\'n Program wat wys hoe om Carousel te gebruik"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Onlangse programme"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Geen onlangse take nie"</string>
-</resources>
diff --git a/carousel/test/res/values-am/strings.xml b/carousel/test/res/values-am/strings.xml
deleted file mode 100644
index f1e8da2..0000000
--- a/carousel/test/res/values-am/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"የሙዚቃ Carousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"የCarousel ፍተሻ"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"የCarouselን ጥቅም የሚያሳይ መተግበሪያ"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"ክንውን ቀያያሪ"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"የቅርብ ጊዜ ትግበራዎች"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"ምንም የቅርብ ጊዜ ክንውን የለም"</string>
-</resources>
diff --git a/carousel/test/res/values-ar/strings.xml b/carousel/test/res/values-ar/strings.xml
deleted file mode 100644
index ba2a7be..0000000
--- a/carousel/test/res/values-ar/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"مكتبة الموسيقى"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"اختبار المكتبة"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"تطبيق لعرض استخدام المكتبة"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"مبدّل المهام"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"التطبيقات الأخيرة"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"لا توجد مهام حديثة"</string>
-</resources>
diff --git a/carousel/test/res/values-az-rAZ/strings.xml b/carousel/test/res/values-az-rAZ/strings.xml
deleted file mode 100644
index 634f926..0000000
--- a/carousel/test/res/values-az-rAZ/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Carousel istifadəsini göstərmək üçün tətbiq"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Son Tətbiqlər"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Son tapşırıqlar yoxdur"</string>
-</resources>
diff --git a/carousel/test/res/values-bg/strings.xml b/carousel/test/res/values-bg/strings.xml
deleted file mode 100644
index 41cf776..0000000
--- a/carousel/test/res/values-bg/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Приложение, което показва използването на въртележката"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Скорошни приложения"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Няма скорошни задачи"</string>
-</resources>
diff --git a/carousel/test/res/values-bn-rBD/strings.xml b/carousel/test/res/values-bn-rBD/strings.xml
deleted file mode 100644
index 1f63829..0000000
--- a/carousel/test/res/values-bn-rBD/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"সঙ্গীত ক্যারোসেল"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"ক্যারোসেল পরীক্ষা"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"ক্যারোসেলের ব্যবহার দেখানোর জন্য একটি অ্যাপ্লিকেশান"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"কার্য পরিবর্তনকারী"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"সাম্প্রতিক অ্যাপ্লিকেশানগুলি"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"কোনো সাম্প্রতিক কার্য নেই"</string>
-</resources>
diff --git a/carousel/test/res/values-ca/strings.xml b/carousel/test/res/values-ca/strings.xml
deleted file mode 100644
index 9f85f5e..0000000
--- a/carousel/test/res/values-ca/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Una aplicació per mostrar com es fa servir l\'expositor giratori"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Aplicacions usades recentment"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"No hi ha tasques recents"</string>
-</resources>
diff --git a/carousel/test/res/values-cs/strings.xml b/carousel/test/res/values-cs/strings.xml
deleted file mode 100644
index a9be826..0000000
--- a/carousel/test/res/values-cs/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Aplikace na ukázku použití režimu Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Nedávné aplikace"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Žádné nedávné úkoly"</string>
-</resources>
diff --git a/carousel/test/res/values-da/strings.xml b/carousel/test/res/values-da/strings.xml
deleted file mode 100644
index 4e7bf9d..0000000
--- a/carousel/test/res/values-da/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"Musikkarrusel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"Karruseltest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"En applikation, som viser brugen af karrusellen"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Seneste applikationer"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Ingen seneste opgaver"</string>
-</resources>
diff --git a/carousel/test/res/values-de/strings.xml b/carousel/test/res/values-de/strings.xml
deleted file mode 100644
index 3dd5491..0000000
--- a/carousel/test/res/values-de/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Eine App, um die Verwendung des Karussells zu demonstrieren"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"Aufgabenwechsel"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Kürzlich geöffnete Apps"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Keine neuen Aufgaben"</string>
-</resources>
diff --git a/carousel/test/res/values-el/strings.xml b/carousel/test/res/values-el/strings.xml
deleted file mode 100644
index 872c9f5..0000000
--- a/carousel/test/res/values-el/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Αίτηση για την εμφάνιση της χρήσης του Καρουζέλ"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Πρόσφατες Εφαρμογές"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Δεν υπάρχουν πρόσφατες εργασίες"</string>
-</resources>
diff --git a/carousel/test/res/values-en-rGB/strings.xml b/carousel/test/res/values-en-rGB/strings.xml
deleted file mode 100644
index 86ea2cb..0000000
--- a/carousel/test/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"Music Carousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"Carousel Test"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"An application to show the use of Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"Task Switcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Recent Applications"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"No recent tasks"</string>
-</resources>
diff --git a/carousel/test/res/values-en-rIN/strings.xml b/carousel/test/res/values-en-rIN/strings.xml
deleted file mode 100644
index 86ea2cb..0000000
--- a/carousel/test/res/values-en-rIN/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"Music Carousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"Carousel Test"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"An application to show the use of Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"Task Switcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Recent Applications"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"No recent tasks"</string>
-</resources>
diff --git a/carousel/test/res/values-es-rUS/strings.xml b/carousel/test/res/values-es-rUS/strings.xml
deleted file mode 100644
index 43f83fa..0000000
--- a/carousel/test/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Una aplicación para mostrar el uso de Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Aplicaciones recientes"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"No hay tareas recientes"</string>
-</resources>
diff --git a/carousel/test/res/values-es/strings.xml b/carousel/test/res/values-es/strings.xml
deleted file mode 100644
index 4e9e63f..0000000
--- a/carousel/test/res/values-es/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"Carrusel de música"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"Prueba de carrusel"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Una aplicación para mostrar cómo se usa el carrusel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"Cambio de tarea"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Aplicaciones recientes"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"No hay tareas recientes."</string>
-</resources>
diff --git a/carousel/test/res/values-et-rEE/strings.xml b/carousel/test/res/values-et-rEE/strings.xml
deleted file mode 100644
index 59f0b5c..0000000
--- a/carousel/test/res/values-et-rEE/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Rakendus, mis näitab karusselli kasutust"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Hiljutised rakendused"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Hiljutised ülesanded puuduvad"</string>
-</resources>
diff --git a/carousel/test/res/values-eu-rES/strings.xml b/carousel/test/res/values-eu-rES/strings.xml
deleted file mode 100644
index 95fc697..0000000
--- a/carousel/test/res/values-eu-rES/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"Musikaren menu birakaria"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"Menu birakariaren proba"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Menu birakariaren erabilera erakusteko aplikazio bat"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"Zeregin-aldatzailea"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Azken aplikazioak"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Ez dago azkenaldiko zereginik"</string>
-</resources>
diff --git a/carousel/test/res/values-fa/strings.xml b/carousel/test/res/values-fa/strings.xml
deleted file mode 100644
index 88aae52..0000000
--- a/carousel/test/res/values-fa/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"گردونه موسیقی"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"برنامهای برای نشان دادن استفاده از گردونه"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"برنامههای اخیر"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"کار جدیدی موجود نیست"</string>
-</resources>
diff --git a/carousel/test/res/values-fi/strings.xml b/carousel/test/res/values-fi/strings.xml
deleted file mode 100644
index e5434a6..0000000
--- a/carousel/test/res/values-fi/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Sovellus opastaa karusellin käytössä"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Viimeisimmät sovellukset"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Ei viimeisimpiä tehtäviä"</string>
-</resources>
diff --git a/carousel/test/res/values-fr-rCA/strings.xml b/carousel/test/res/values-fr-rCA/strings.xml
deleted file mode 100644
index 87aeb34..0000000
--- a/carousel/test/res/values-fr-rCA/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Une application expliquant l\'utilisation de Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Applications récentes"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Aucune tâche récente"</string>
-</resources>
diff --git a/carousel/test/res/values-fr/strings.xml b/carousel/test/res/values-fr/strings.xml
deleted file mode 100644
index 87aeb34..0000000
--- a/carousel/test/res/values-fr/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Une application expliquant l\'utilisation de Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Applications récentes"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Aucune tâche récente"</string>
-</resources>
diff --git a/carousel/test/res/values-gl-rES/strings.xml b/carousel/test/res/values-gl-rES/strings.xml
deleted file mode 100644
index 5d41718..0000000
--- a/carousel/test/res/values-gl-rES/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Unha aplicación para mostrar o uso do expositor xiratorio"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Aplicacións recentes"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Non hai tarefas recentes"</string>
-</resources>
diff --git a/carousel/test/res/values-hi/strings.xml b/carousel/test/res/values-hi/strings.xml
deleted file mode 100644
index b931761..0000000
--- a/carousel/test/res/values-hi/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Carousel का उपयोग बताने के लिए एप्लिकेशन"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"हाल ही के एप्लिकेशन"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"कोई हाल ही के कार्य नहीं"</string>
-</resources>
diff --git a/carousel/test/res/values-hr/strings.xml b/carousel/test/res/values-hr/strings.xml
deleted file mode 100644
index 8fe4b5f..0000000
--- a/carousel/test/res/values-hr/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Aplikacija koja pokazuje kako se upotrebljava Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Nedavne aplikacije"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Nema nedavnih zadataka"</string>
-</resources>
diff --git a/carousel/test/res/values-hu/strings.xml b/carousel/test/res/values-hu/strings.xml
deleted file mode 100644
index 102e4e9..0000000
--- a/carousel/test/res/values-hu/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"ZeneKörhinta"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"KörhintaTeszt"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"A Körhinta használatát megjelenítő alkalmazás"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"FeladatVáltó"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"A legújabb alkalmazások"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Nincsenek esedékes feladatok"</string>
-</resources>
diff --git a/carousel/test/res/values-hy-rAM/strings.xml b/carousel/test/res/values-hy-rAM/strings.xml
deleted file mode 100644
index 39bf205..0000000
--- a/carousel/test/res/values-hy-rAM/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Հավելված` Carousel-ի օգտագործումը ցույց տալու համար"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Վերջին հավելվածները"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Վերջին առաջադրանքներ չկան"</string>
-</resources>
diff --git a/carousel/test/res/values-in/strings.xml b/carousel/test/res/values-in/strings.xml
deleted file mode 100644
index 06c8812..0000000
--- a/carousel/test/res/values-in/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"KaruselMusik"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"UjiKarusel"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Aplikasi untuk menampilkan penggunaan Korsel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"PengubahTugas"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Aplikasi Terbaru"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Tidak ada tugas terbaru"</string>
-</resources>
diff --git a/carousel/test/res/values-is-rIS/strings.xml b/carousel/test/res/values-is-rIS/strings.xml
deleted file mode 100644
index 8971edf..0000000
--- a/carousel/test/res/values-is-rIS/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"Tónlistarvalræma"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"Valræmuprófun"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Forrit til að sýna notkun valræmu"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"Verkefnaskiptir"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Nýleg forrit"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Engin nýleg verkefni"</string>
-</resources>
diff --git a/carousel/test/res/values-it/strings.xml b/carousel/test/res/values-it/strings.xml
deleted file mode 100644
index 86e5516..0000000
--- a/carousel/test/res/values-it/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Un\'applicazione per mostrare l\'uso della sequenza"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Applicazioni recenti"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Nessuna attività recente"</string>
-</resources>
diff --git a/carousel/test/res/values-iw/strings.xml b/carousel/test/res/values-iw/strings.xml
deleted file mode 100644
index a4163c5..0000000
--- a/carousel/test/res/values-iw/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"אפליקציה להצגת השימוש בקרוסלה"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"אפליקציות אחרונות"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"אין משימות אחרונות"</string>
-</resources>
diff --git a/carousel/test/res/values-ja/strings.xml b/carousel/test/res/values-ja/strings.xml
deleted file mode 100644
index 9b2cf5b..0000000
--- a/carousel/test/res/values-ja/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Carouselの使用を表示するアプリケーション"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"最近のアプリケーション"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"最近のタスクはありません"</string>
-</resources>
diff --git a/carousel/test/res/values-ka-rGE/strings.xml b/carousel/test/res/values-ka-rGE/strings.xml
deleted file mode 100644
index 0764f3f..0000000
--- a/carousel/test/res/values-ka-rGE/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Carousel-ის გამოყენების მაჩვენებელი აპლიკაცია"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"ბოლოდროინდელი აპლიკაციები"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"ბოლოდროინდელი ამოცანები არ არის."</string>
-</resources>
diff --git a/carousel/test/res/values-kk-rKZ/strings.xml b/carousel/test/res/values-kk-rKZ/strings.xml
deleted file mode 100644
index 8192813..0000000
--- a/carousel/test/res/values-kk-rKZ/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"МузыкаКарусель"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"КарусельТест"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Карусельді қолдану жолын көрсететін қолданба"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"ТапсырмаАуыстырғыш"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Соңғы қолданбалар"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Соңғы тапсырмалар жоқ"</string>
-</resources>
diff --git a/carousel/test/res/values-km-rKH/strings.xml b/carousel/test/res/values-km-rKH/strings.xml
deleted file mode 100644
index 5bb198d..0000000
--- a/carousel/test/res/values-km-rKH/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"កម្មវិធីត្រូវបង្ហាញការប្រើ Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"កម្មវិធីថ្មីៗ"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"គ្មានភារកិច្ចថ្មីៗ"</string>
-</resources>
diff --git a/carousel/test/res/values-kn-rIN/strings.xml b/carousel/test/res/values-kn-rIN/strings.xml
deleted file mode 100644
index 6b62867..0000000
--- a/carousel/test/res/values-kn-rIN/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"ಕರೋಸೆಲ್ ಬಳಕೆಯನ್ನು ತೋರಿಸುವ ಅಪ್ಲಿಕೇಶನ್"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"ಇತ್ತೀಚಿನ ಅಪ್ಲಿಕೇಶನ್ಗಳು"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"ಇತ್ತೀಚಿನ ಕಾರ್ಯಗಳಿಲ್ಲ"</string>
-</resources>
diff --git a/carousel/test/res/values-ko/strings.xml b/carousel/test/res/values-ko/strings.xml
deleted file mode 100644
index eeb5b66..0000000
--- a/carousel/test/res/values-ko/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"음악 캐러셀"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"캐러셀 테스트"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"캐러셀 사용을 표시하는 애플리케이션"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"작업 전환"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"최신 애플리케이션"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"최근 작업이 없습니다."</string>
-</resources>
diff --git a/carousel/test/res/values-ky-rKG/strings.xml b/carousel/test/res/values-ky-rKG/strings.xml
deleted file mode 100644
index ddca10f..0000000
--- a/carousel/test/res/values-ky-rKG/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"МузыкалыкАйланкөчөк"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"АйланкөчөктүСыноо"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Колдонмо көргөзүүдө Айланкөчөк ыкмасын колдонот"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"ТапшырмаКоторгуч"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Акыркы колдонмолор"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Акыркы тапшырмалар табылган жок"</string>
-</resources>
diff --git a/carousel/test/res/values-lo-rLA/strings.xml b/carousel/test/res/values-lo-rLA/strings.xml
deleted file mode 100644
index 83a4cbd..0000000
--- a/carousel/test/res/values-lo-rLA/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"ແອັບພລິເຄຊັນທີ່ໃຊ້ສະແດງປະໂຫຍດຂອງ Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"ແອັບຯພລິເຄຊັນທີ່ຫາກໍໃຊ້"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"ບໍ່ມີວຽກເມື່ອໄວໆນີ້ເທື່ອ"</string>
-</resources>
diff --git a/carousel/test/res/values-lt/strings.xml b/carousel/test/res/values-lt/strings.xml
deleted file mode 100644
index 5fd9993..0000000
--- a/carousel/test/res/values-lt/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"Muzikos karuselė"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"Karuselės testas"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Programa, rodanti karuselės naudojimą"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"Užduočių jungiklis"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Naujausios programos"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Nė vienos pastaruoju metu pateiktos užduoties"</string>
-</resources>
diff --git a/carousel/test/res/values-lv/strings.xml b/carousel/test/res/values-lv/strings.xml
deleted file mode 100644
index ba5f6f1..0000000
--- a/carousel/test/res/values-lv/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Lietojumprogramma karuseļa lietošanas demonstrēšanai"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Nesen lietotās lietojumprogrammas"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Nav neviena nesen veikta uzdevuma."</string>
-</resources>
diff --git a/carousel/test/res/values-mk-rMK/strings.xml b/carousel/test/res/values-mk-rMK/strings.xml
deleted file mode 100644
index b7c1834..0000000
--- a/carousel/test/res/values-mk-rMK/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Апликација да се покаже употребата на Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Последни апликации"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Нема понови задачи"</string>
-</resources>
diff --git a/carousel/test/res/values-ml-rIN/strings.xml b/carousel/test/res/values-ml-rIN/strings.xml
deleted file mode 100644
index 73254d6..0000000
--- a/carousel/test/res/values-ml-rIN/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"കറൗസലിന്റെ ഉപയോഗം ദൃശ്യമാക്കാനുള്ള ഒരു അപ്ലിക്കേഷൻ"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"സമീപകാല അപ്ളിക്കേഷനുകൾ"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"സമീപകാല ടാസ്ക്കുകളൊന്നുമില്ല"</string>
-</resources>
diff --git a/carousel/test/res/values-mn-rMN/strings.xml b/carousel/test/res/values-mn-rMN/strings.xml
deleted file mode 100644
index 20d9f8d..0000000
--- a/carousel/test/res/values-mn-rMN/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"Хөгжмийн тойруулга"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"Тойруулга тест"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Тойруулга ашиглалтыг харуулах аппликешн"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"Даалгавар солигч"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Сүүлийн аппликешн"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Сүүлийн даалгавар хоосон"</string>
-</resources>
diff --git a/carousel/test/res/values-mr-rIN/strings.xml b/carousel/test/res/values-mr-rIN/strings.xml
deleted file mode 100644
index aa0b2e6..0000000
--- a/carousel/test/res/values-mr-rIN/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"कॅरोझेलचा वापर दर्शविण्यासाठी अनुप्रयोग"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"अलीकडील अनुप्रयोग"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"अलीकडील कोणतीही कार्ये नाहीत"</string>
-</resources>
diff --git a/carousel/test/res/values-ms-rMY/strings.xml b/carousel/test/res/values-ms-rMY/strings.xml
deleted file mode 100644
index ab9381a..0000000
--- a/carousel/test/res/values-ms-rMY/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Satu aplikasi untuk menunjukkan penggunaan Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Aplikasi Terbaru"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Tiada tugasan terbaru"</string>
-</resources>
diff --git a/carousel/test/res/values-my-rMM/strings.xml b/carousel/test/res/values-my-rMM/strings.xml
deleted file mode 100644
index 11bf0d8..0000000
--- a/carousel/test/res/values-my-rMM/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"Carouselဂီတ"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"Carouselစမ်းသပ်ခြင်း"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Carouselအားအသုံးပြုရန်ပြသော အပ်ပလီကေးရှင်း"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"လုပ်ငန်းစဉ်ဖလှယ်မှု"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"လတ်တလောအသုံးပြုသော အပ်ပလီကေးရှင်းများ"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"လတ်တလောလုပ်ဆောင်ချက်မရှိပါ"</string>
-</resources>
diff --git a/carousel/test/res/values-nb/strings.xml b/carousel/test/res/values-nb/strings.xml
deleted file mode 100644
index 751baf9..0000000
--- a/carousel/test/res/values-nb/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"En app som viser bruken av Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Nylige apper"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Ingen nylige oppgaver"</string>
-</resources>
diff --git a/carousel/test/res/values-ne-rNP/strings.xml b/carousel/test/res/values-ne-rNP/strings.xml
deleted file mode 100644
index 838502f..0000000
--- a/carousel/test/res/values-ne-rNP/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"संगीत करउसेल"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"करउसेल परीक्षण"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"कारउसेलको प्रयोग देखाउन एउटा अनुप्रयोग"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"कार्य स्विच गर्ने"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"भर्खरैका अनुप्रयोगहरू"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"कुनै भरखरका कार्यहरू छैनन्।"</string>
-</resources>
diff --git a/carousel/test/res/values-nl/strings.xml b/carousel/test/res/values-nl/strings.xml
deleted file mode 100644
index 3ec92ed..0000000
--- a/carousel/test/res/values-nl/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Een app die het gebruik van Carousel illustreert"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Recente apps"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Geen recente taken"</string>
-</resources>
diff --git a/carousel/test/res/values-pl/strings.xml b/carousel/test/res/values-pl/strings.xml
deleted file mode 100644
index c811c04..0000000
--- a/carousel/test/res/values-pl/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Aplikacja prezentująca zastosowanie karuzeli"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Ostatnie aplikacje"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Brak ostatnich zadań"</string>
-</resources>
diff --git a/carousel/test/res/values-pt-rPT/strings.xml b/carousel/test/res/values-pt-rPT/strings.xml
deleted file mode 100644
index 11104d4..0000000
--- a/carousel/test/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Uma aplicação para demonstrar a utilização do Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Aplicações Recentes"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Sem tarefas recentes"</string>
-</resources>
diff --git a/carousel/test/res/values-pt/strings.xml b/carousel/test/res/values-pt/strings.xml
deleted file mode 100644
index f98edde..0000000
--- a/carousel/test/res/values-pt/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Um aplicativo para mostrar o uso do Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Aplicativos recentes"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Nenhuma tarefa recente"</string>
-</resources>
diff --git a/carousel/test/res/values-ro/strings.xml b/carousel/test/res/values-ro/strings.xml
deleted file mode 100644
index 9c8df37..0000000
--- a/carousel/test/res/values-ro/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"O aplicaţie care afişează cum se utilizează Caruselul"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Aplicaţii recente"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Nicio activitate recentă"</string>
-</resources>
diff --git a/carousel/test/res/values-ru/strings.xml b/carousel/test/res/values-ru/strings.xml
deleted file mode 100644
index af64195..0000000
--- a/carousel/test/res/values-ru/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"Музыкальная карусель"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"Тестирование карусели"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Приложение для отображения карусели"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"Смена задач"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Последние приложения"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Нет новых задач"</string>
-</resources>
diff --git a/carousel/test/res/values-si-rLK/strings.xml b/carousel/test/res/values-si-rLK/strings.xml
deleted file mode 100644
index 5a1aa48..0000000
--- a/carousel/test/res/values-si-rLK/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"සංගීත Carousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"Carousel පරීක්ෂණය"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Carousel භාවිතය පෙන්වීමට යෙදුමකි"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"කාර්ය ස්විචය"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"මෑත කාලීන යෙදුම්"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"මෑත කාර්යයන් නැත"</string>
-</resources>
diff --git a/carousel/test/res/values-sk/strings.xml b/carousel/test/res/values-sk/strings.xml
deleted file mode 100644
index e6e8aa1..0000000
--- a/carousel/test/res/values-sk/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Aplikácia na ukážku použitia režimu Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Nedávne aplikácie"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Žiadne nedávne úlohy"</string>
-</resources>
diff --git a/carousel/test/res/values-sl/strings.xml b/carousel/test/res/values-sl/strings.xml
deleted file mode 100644
index ca10e66..0000000
--- a/carousel/test/res/values-sl/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"Glasbeni vrtiljak"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"Preskus vrtiljaka"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Program za prikaz uporabe pogleda vrtiljaka"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"Izbirnik opravil"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Nedavni programi"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Ni nedavnih opravil"</string>
-</resources>
diff --git a/carousel/test/res/values-sr/strings.xml b/carousel/test/res/values-sr/strings.xml
deleted file mode 100644
index 312fc41..0000000
--- a/carousel/test/res/values-sr/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Апликација којом се приказује коришћење Carousel-а"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Недавно коришћене апликације"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Нема недавних задатака"</string>
-</resources>
diff --git a/carousel/test/res/values-sv/strings.xml b/carousel/test/res/values-sv/strings.xml
deleted file mode 100644
index ca070e3..0000000
--- a/carousel/test/res/values-sv/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"Musikkarusell"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"Karuselltest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"En app om hur du använder Karusell"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Nya appar"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Inga nya aktiviteter"</string>
-</resources>
diff --git a/carousel/test/res/values-sw/strings.xml b/carousel/test/res/values-sw/strings.xml
deleted file mode 100644
index 350664f..0000000
--- a/carousel/test/res/values-sw/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"Jaribio la Carousel"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Programu ya kuonyesha matumizi ya Karuseli"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Programu za Hivi karibuni"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Hakuna kazi za hivi karibuni"</string>
-</resources>
diff --git a/carousel/test/res/values-ta-rIN/strings.xml b/carousel/test/res/values-ta-rIN/strings.xml
deleted file mode 100644
index 7ae9434..0000000
--- a/carousel/test/res/values-ta-rIN/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Carousel இன் பயன்பாட்டைக் காட்டுவதற்கான பயன்பாடு"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"சமீபத்திய பயன்பாடுகள்"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"செயல் ஏதுமில்லை"</string>
-</resources>
diff --git a/carousel/test/res/values-te-rIN/strings.xml b/carousel/test/res/values-te-rIN/strings.xml
deleted file mode 100644
index b7a6218..0000000
--- a/carousel/test/res/values-te-rIN/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"తిరిగే సంగీత పట్టిక"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"తిరిగే పట్టిక పరీక్ష"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"తిరిగే పట్టిక ఉపయోగాన్ని చూపే అనువర్తనం"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"విధి స్విచ్చర్"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"ఇటీవలి అనువర్తనాలు"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"ఇటీవలి విధులు లేవు"</string>
-</resources>
diff --git a/carousel/test/res/values-th/strings.xml b/carousel/test/res/values-th/strings.xml
deleted file mode 100644
index fa448a6..0000000
--- a/carousel/test/res/values-th/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"แอปพลิเคชันที่แสดงการใช้งาน Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"แอปพลิเคชันล่าสุด"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"ไม่มีงานล่าสุด"</string>
-</resources>
diff --git a/carousel/test/res/values-tl/strings.xml b/carousel/test/res/values-tl/strings.xml
deleted file mode 100644
index a074480..0000000
--- a/carousel/test/res/values-tl/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Isang application upang ipakita ang gamit ng Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Mga Kamakailang Application"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Walang kamakailang mga gawain"</string>
-</resources>
diff --git a/carousel/test/res/values-tr/strings.xml b/carousel/test/res/values-tr/strings.xml
deleted file mode 100644
index 38c217b..0000000
--- a/carousel/test/res/values-tr/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"Müzik Atlı Karıncası"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"Atlı Karınca Testi"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Atlı Karınca\'nın kullanımını göstermek için bir uygulama"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"Görev Değiştirici"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Son Uygulamalar"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Hiç son görev yok"</string>
-</resources>
diff --git a/carousel/test/res/values-uk/strings.xml b/carousel/test/res/values-uk/strings.xml
deleted file mode 100644
index 41fc7ac..0000000
--- a/carousel/test/res/values-uk/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Програма для демонстрації режиму каруселі"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Останні програми"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Немає останніх завдань"</string>
-</resources>
diff --git a/carousel/test/res/values-ur-rPK/strings.xml b/carousel/test/res/values-ur-rPK/strings.xml
deleted file mode 100644
index 2eb1e3d..0000000
--- a/carousel/test/res/values-ur-rPK/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"کیراسیل کا استعمال دکھانے کیلئے ایک ایپلیکیشن"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"حالیہ ایپلیکیشنز"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"کوئی حالیہ ٹاسکس نہیں ہیں"</string>
-</resources>
diff --git a/carousel/test/res/values-uz-rUZ/strings.xml b/carousel/test/res/values-uz-rUZ/strings.xml
deleted file mode 100644
index 9c8c83e..0000000
--- a/carousel/test/res/values-uz-rUZ/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"\"Carousel\"dan foydalanib ko‘rsatish uchun dastur"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"So‘nggi foydalanilgan dasturlar"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"So‘nggi vazifalar mavjud emas"</string>
-</resources>
diff --git a/carousel/test/res/values-vi/strings.xml b/carousel/test/res/values-vi/strings.xml
deleted file mode 100644
index 2ac1dbc..0000000
--- a/carousel/test/res/values-vi/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Ứng dụng thể hiện việc sử dụng Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Ứng dụng gần đây"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Không có tác vụ nào gần đây"</string>
-</resources>
diff --git a/carousel/test/res/values-zh-rCN/strings.xml b/carousel/test/res/values-zh-rCN/strings.xml
deleted file mode 100644
index 2273e8f..0000000
--- a/carousel/test/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"音乐轮播"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"轮播测试"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"介绍轮播用法的应用"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"任务切换器"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"最近用过的应用"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"无任何近期任务"</string>
-</resources>
diff --git a/carousel/test/res/values-zh-rHK/strings.xml b/carousel/test/res/values-zh-rHK/strings.xml
deleted file mode 100644
index 193cb4a..0000000
--- a/carousel/test/res/values-zh-rHK/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"展示輪轉使用方法的應用程式"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"最近使用的應用程式"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"最近沒有任務"</string>
-</resources>
diff --git a/carousel/test/res/values-zh-rTW/strings.xml b/carousel/test/res/values-zh-rTW/strings.xml
deleted file mode 100644
index 85940cf..0000000
--- a/carousel/test/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"示範輪轉介面使用方法的應用程式"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"最近用過的應用程式"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"沒有近期的工作"</string>
-</resources>
diff --git a/carousel/test/res/values-zu/strings.xml b/carousel/test/res/values-zu/strings.xml
deleted file mode 100644
index bd5be32..0000000
--- a/carousel/test/res/values-zu/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="music_demo_activity_label" msgid="4382090808250495841">"i-MusicCarousel"</string>
- <string name="carousel_test_activity_label" msgid="6014624482213318747">"I-CarouselTest"</string>
- <string name="carousel_test_activity_description" msgid="1632693812604375483">"Isisetshenziswa sokukhombisa ukusetshenziswa kwe-Carousel"</string>
- <string name="task_switcher_activity_label" msgid="714620143340933546">"i-TaskSwitcher"</string>
- <string name="recent_tasks_title" msgid="1030287226205477117">"Izisetshenziswa zamaduze nje"</string>
- <string name="no_recent_tasks" msgid="6884096266670555780">"Ayikho imisebenzi yamanje"</string>
-</resources>
diff --git a/carousel/test/res/values/strings.xml b/carousel/test/res/values/strings.xml
deleted file mode 100644
index c0b5ce6..0000000
--- a/carousel/test/res/values/strings.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-* Copyright (C) 2009 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- General --><skip />
- <string name="music_demo_activity_label">MusicCarousel</string>
- <string name="carousel_test_activity_label">CarouselTest</string>
- <string name="carousel_test_activity_description">An application to show the use of Carousel</string>
- <string name="task_switcher_activity_label">TaskSwitcher</string>
-
- <string name="recent_tasks_title">Recent Applications</string>
- <string name="no_recent_tasks">No recent tasks</string>
-
-</resources>
diff --git a/carousel/test/src/com/android/carouseltest/CarouselTestActivity.java b/carousel/test/src/com/android/carouseltest/CarouselTestActivity.java
deleted file mode 100644
index 18adc5e..0000000
--- a/carousel/test/src/com/android/carouseltest/CarouselTestActivity.java
+++ /dev/null
@@ -1,184 +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.
- */
-
-package com.android.carouseltest;
-
-import com.android.ex.carousel.CarouselView;
-import com.android.ex.carousel.CarouselViewHelper;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.util.Log;
-
-public class CarouselTestActivity extends Activity {
- private static final String TAG = "CarouselTestActivity";
- private static final int CARD_SLOTS = 56;
- private static final int TOTAL_CARDS = 100;
- private static final int TEXTURE_HEIGHT = 256;
- private static final int TEXTURE_WIDTH = 256;
- private static final int SLOTS_VISIBLE = 7;
-
- protected static final boolean DBG = false;
- private static final int DETAIL_TEXTURE_WIDTH = 200;
- private static final int DETAIL_TEXTURE_HEIGHT = 80;
- private static final int VISIBLE_DETAIL_COUNT = 3;
- private static boolean INCREMENTAL_ADD = false; // To debug incrementally adding cards
- private CarouselView mView;
- private Paint mPaint = new Paint();
- private CarouselViewHelper mHelper;
- private Bitmap mGlossyOverlay;
- private Bitmap mBorder;
-
- class LocalCarouselViewHelper extends CarouselViewHelper {
- private static final int PIXEL_BORDER = 3;
- private DetailTextureParameters mDetailTextureParameters
- = new DetailTextureParameters(5.0f, 5.0f, 3.0f, 10.0f);
-
- LocalCarouselViewHelper(Context context) {
- super(context);
- }
-
- @Override
- public void onCardSelected(final int id) {
- postMessage("Selection", "Card " + id + " was selected");
- }
-
- @Override
- public void onDetailSelected(final int id, int x, int y) {
- postMessage("Selection", "Detail for card " + id + " was selected");
- }
-
- @Override
- public void onCardLongPress(int n, int touchPosition[], Rect detailCoordinates) {
- postMessage("Selection", "Long press on card " + n);
- }
-
- @Override
- public DetailTextureParameters getDetailTextureParameters(int id) {
- return mDetailTextureParameters;
- }
-
- @Override
- public Bitmap getTexture(int n) {
- Bitmap bitmap = Bitmap.createBitmap(TEXTURE_WIDTH, TEXTURE_HEIGHT,
- Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(bitmap);
- canvas.drawARGB(0, 0, 0, 0);
- mPaint.setColor(0x40808080);
- canvas.drawRect(2, 2, TEXTURE_WIDTH-2, TEXTURE_HEIGHT-2, mPaint);
- mPaint.setTextSize(100.0f);
- mPaint.setAntiAlias(true);
- mPaint.setColor(0xffffffff);
- canvas.drawText("" + n, 2, TEXTURE_HEIGHT-10, mPaint);
- canvas.drawBitmap(mGlossyOverlay, null,
- new Rect(PIXEL_BORDER, PIXEL_BORDER,
- TEXTURE_WIDTH - PIXEL_BORDER, TEXTURE_HEIGHT - PIXEL_BORDER), mPaint);
- return bitmap;
- }
-
- @Override
- public Bitmap getDetailTexture(int n) {
- Bitmap bitmap = Bitmap.createBitmap(DETAIL_TEXTURE_WIDTH, DETAIL_TEXTURE_HEIGHT,
- Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(bitmap);
- canvas.drawARGB(32, 10, 10, 10);
- mPaint.setTextSize(15.0f);
- mPaint.setAntiAlias(true);
- canvas.drawText("Detail text for card " + n, 0, DETAIL_TEXTURE_HEIGHT/2, mPaint);
- return bitmap;
- }
- };
-
- @Override
- public CharSequence onCreateDescription() {
- return getText(R.string.carousel_test_activity_description);
- }
-
- private Runnable mAddCardRunnable = new Runnable() {
- public void run() {
- if (mView.getCardCount() < TOTAL_CARDS) {
- mView.createCards(mView.getCardCount() + 1);
- mView.postDelayed(mAddCardRunnable, 2000);
- }
- }
- };
-
- void postMessage(final CharSequence title, final CharSequence msg) {
- runOnUiThread(new Runnable() {
- public void run() {
- new AlertDialog.Builder(CarouselTestActivity.this)
- .setTitle(title)
- .setMessage(msg)
- .setPositiveButton("OK", null)
- .create()
- .show();
- }
- });
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.carousel_test);
- mView = (CarouselView) findViewById(R.id.carousel);
- mView.getHolder().setFormat(PixelFormat.RGBA_8888);
- mPaint.setColor(0xffffffff);
- final Resources res = getResources();
-
- mHelper = new LocalCarouselViewHelper(this);
- mHelper.setCarouselView(mView);
- mView.setSlotCount(CARD_SLOTS);
- mView.createCards(INCREMENTAL_ADD ? 1: TOTAL_CARDS);
- mView.setVisibleSlots(SLOTS_VISIBLE);
- mView.setStartAngle((float) -(2.0f*Math.PI * 5 / CARD_SLOTS));
- mBorder = BitmapFactory.decodeResource(res, R.drawable.border);
- mView.setDefaultBitmap(mBorder);
- mView.setLoadingBitmap(mBorder);
- mView.setBackgroundColor(0.25f, 0.25f, 0.5f, 0.5f);
- mView.setRezInCardCount(3.0f);
- mView.setFadeInDuration(250);
- mView.setVisibleDetails(VISIBLE_DETAIL_COUNT);
- mView.setDragModel(CarouselView.DRAG_MODEL_PLANE);
- if (INCREMENTAL_ADD) {
- mView.postDelayed(mAddCardRunnable, 2000);
- }
-
- mGlossyOverlay = BitmapFactory.decodeResource(res, R.drawable.glossy_overlay);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- mHelper.onResume();
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- mHelper.onPause();
- }
-
-}
diff --git a/carousel/test/src/com/android/carouseltest/MusicDemoActivity.java b/carousel/test/src/com/android/carouseltest/MusicDemoActivity.java
deleted file mode 100644
index 0ed4993..0000000
--- a/carousel/test/src/com/android/carouseltest/MusicDemoActivity.java
+++ /dev/null
@@ -1,113 +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.
- */
-
-package com.android.carouseltest;
-
-import com.android.ex.carousel.CarouselView;
-import com.android.ex.carousel.CarouselViewHelper;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.os.Bundle;
-import android.util.Log;
-
-public class MusicDemoActivity extends Activity {
- private static final String TAG = "MusicDemoActivity";
- private static final int CD_GEOMETRY = R.raw.book;
- private static final int VISIBLE_SLOTS = 7;
- private static final int CARD_SLOTS = 56;
- private static final int TOTAL_CARDS = 10000;
- private CarouselView mView;
- private int mImageResources[] = {
- R.drawable.emo_im_angel,
- R.drawable.emo_im_cool,
- R.drawable.emo_im_crying,
- R.drawable.emo_im_foot_in_mouth,
- R.drawable.emo_im_happy,
- R.drawable.emo_im_kissing,
- R.drawable.emo_im_laughing,
- R.drawable.emo_im_lips_are_sealed,
- R.drawable.emo_im_money_mouth,
- R.drawable.emo_im_sad,
- R.drawable.emo_im_surprised,
- R.drawable.emo_im_tongue_sticking_out,
- R.drawable.emo_im_undecided,
- R.drawable.emo_im_winking,
- R.drawable.emo_im_wtf,
- R.drawable.emo_im_yelling
- };
-
- private LocalCarouselViewHelper mHelper;
-
- class LocalCarouselViewHelper extends CarouselViewHelper {
-
- LocalCarouselViewHelper(Context context) {
- super(context);
- }
-
- @Override
- public void onCardSelected(int id) {
- Log.v(TAG, "Yay, item " + id + " was selected!");
- }
-
- @Override
- public Bitmap getTexture(int n) {
- return BitmapFactory.decodeResource(getResources(),
- mImageResources[n % mImageResources.length]);
- }
-
- @Override
- public Bitmap getDetailTexture(int n) {
- return null;
- }
- };
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- final Resources res = getResources();
- setContentView(R.layout.music_demo);
- mView = (CarouselView) findViewById(R.id.carousel);
- mHelper = new LocalCarouselViewHelper(this);
- mHelper.setCarouselView(mView);
- mView.setSlotCount(CARD_SLOTS);
- mView.createCards(TOTAL_CARDS);
- mView.setVisibleSlots(VISIBLE_SLOTS);
- mView.setStartAngle((float) -(2.0f*Math.PI * 5 / CARD_SLOTS));
- mView.setDefaultBitmap(BitmapFactory.decodeResource(res, R.drawable.wait));
- mView.setLoadingBitmap(BitmapFactory.decodeResource(res, R.drawable.blank_album));
- mView.setBackgroundBitmap(BitmapFactory.decodeResource(res, R.drawable.background));
- mView.setDefaultGeometry(CD_GEOMETRY);
- mView.setFadeInDuration(250);
- mView.setRezInCardCount(3.0f);
- mView.setForceBlendCardsWithZ(false);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- mHelper.onResume();
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- mHelper.onPause();
- }
-}
diff --git a/carousel/test/src/com/android/carouseltest/MyCarouselView.java b/carousel/test/src/com/android/carouseltest/MyCarouselView.java
deleted file mode 100644
index 973a9bc..0000000
--- a/carousel/test/src/com/android/carouseltest/MyCarouselView.java
+++ /dev/null
@@ -1,49 +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.
- */
-
-package com.android.carouseltest;
-
-import android.content.Context;
-import android.util.AttributeSet;
-
-import com.android.ex.carousel.CarouselController;
-import com.android.ex.carousel.CarouselView;
-import com.android.ex.carousel.CarouselView.Info;
-
-public class MyCarouselView extends CarouselView {
-
- public MyCarouselView(Context context, CarouselController controller) {
- this(context, null, controller);
- }
-
- public MyCarouselView(Context context, AttributeSet attrs) {
- this(context, attrs, new CarouselController());
- }
-
- public MyCarouselView(Context context, AttributeSet attrs, CarouselController controller) {
- super(context, attrs, controller);
- }
-
- public Info getRenderScriptInfo() {
- return new Info(R.raw.carousel);
- }
-
- @Override
- public boolean interpretLongPressEvents() {
- return true;
- }
-
-}
diff --git a/carousel/test/src/com/android/carouseltest/TaskSwitcherActivity.java b/carousel/test/src/com/android/carouseltest/TaskSwitcherActivity.java
deleted file mode 100644
index 0a76ecc..0000000
--- a/carousel/test/src/com/android/carouseltest/TaskSwitcherActivity.java
+++ /dev/null
@@ -1,300 +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.
- */
-
-
-package com.android.carouseltest;
-
-import java.util.ArrayList;
-import java.util.List;
-import com.android.carouseltest.R;
-
-import com.android.ex.carousel.CarouselController;
-import com.android.ex.carousel.CarouselViewHelper;
-
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.app.IThumbnailReceiver;
-import android.app.ActivityManager.RunningTaskInfo;
-import android.content.ActivityNotFoundException;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Bitmap.Config;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-import android.view.View;
-
-public class TaskSwitcherActivity extends Activity {
- private static final String TAG = "TaskSwitcherActivity";
- private static final int CARD_SLOTS = 56;
- private static final int MAX_TASKS = 20;
- private static final int VISIBLE_SLOTS = 7;
- protected static final boolean DBG = false;
- private ActivityManager mActivityManager;
- private List<RunningTaskInfo> mRunningTaskList;
- private boolean mPortraitMode = true;
- private ArrayList<ActivityDescription> mActivityDescriptions
- = new ArrayList<ActivityDescription>();
- private CarouselController mController;
- private MyCarouselView mView;
- private Bitmap mBlankBitmap = Bitmap.createBitmap(128, 128, Config.RGB_565);
- private LocalCarouselViewHelper mHelper;
-
- static class ActivityDescription {
- int id;
- Bitmap thumbnail;
- Drawable icon;
- CharSequence label;
- CharSequence description;
- Intent intent;
- Matrix matrix;
-
- public ActivityDescription(Bitmap _thumbnail,
- Drawable _icon, String _label, String _desc, int _id)
- {
- thumbnail = _thumbnail;
- icon = _icon;
- label = _label;
- description = _desc;
- id = _id;
- }
-
- public void clear() {
- icon = null;
- thumbnail = null;
- label = null;
- description = null;
- intent = null;
- matrix = null;
- id = -1;
- }
- };
-
- private ActivityDescription findActivityDescription(int id) {
- for (int i = 0; i < mActivityDescriptions.size(); i++) {
- ActivityDescription item = mActivityDescriptions.get(i);
- if (item != null && item.id == id) {
- return item;
- }
- }
- return null;
- }
-
- class LocalCarouselViewHelper extends CarouselViewHelper {
- private static final int DETAIL_TEXTURE_WIDTH = 256;
- private static final int DETAIL_TEXTURE_HEIGHT = 80;
- private Paint mPaint = new Paint();
- private DetailTextureParameters mDetailTextureParameters
- = new DetailTextureParameters(5.0f, 5.0f);
-
- public LocalCarouselViewHelper(Context context) {
- super(context);
- }
-
- @Override
- public DetailTextureParameters getDetailTextureParameters(int id) {
- return mDetailTextureParameters;
- }
-
- @Override
- public void onCardSelected(int n) {
- if (n < mActivityDescriptions.size()) {
- ActivityDescription item = mActivityDescriptions.get(n);
- // prepare a launch intent and send it
- if (item.intent != null) {
- item.intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
- try {
- Log.v(TAG, "Starting intent " + item.intent);
- startActivity(item.intent);
- overridePendingTransition(R.anim.zoom_enter, R.anim.zoom_exit);
- } catch (ActivityNotFoundException e) {
- Log.w("Recent", "Unable to launch recent task", e);
- }
- finish();
- }
- }
- }
-
- @Override
- public Bitmap getTexture(int n) {
- ActivityDescription desc = mActivityDescriptions.get(n);
- Bitmap bitmap = desc.thumbnail == null ? mBlankBitmap : desc.thumbnail;
- return bitmap;
- }
-
- @Override
- public Bitmap getDetailTexture(int n) {
- Bitmap bitmap = null;
- if (n < mActivityDescriptions.size()) {
- ActivityDescription item = mActivityDescriptions.get(n);
- bitmap = Bitmap.createBitmap(DETAIL_TEXTURE_WIDTH, DETAIL_TEXTURE_HEIGHT,
- Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(bitmap);
- canvas.drawARGB(128,128,128,255);
- mPaint.setTextSize(15.0f);
- mPaint.setColor(0xffffffff);
- mPaint.setAntiAlias(true);
- canvas.drawText(item.label.toString(),0, DETAIL_TEXTURE_HEIGHT/2, mPaint);
- }
- return bitmap;
- }
- };
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- final Resources res = getResources();
- final View decorView = getWindow().getDecorView();
-
- mController = new CarouselController();
- mView = new MyCarouselView(this, mController);
- mHelper = new LocalCarouselViewHelper(this);
- mHelper.setCarouselView(mView);
- mView.setSlotCount(CARD_SLOTS);
- mView.setVisibleSlots(VISIBLE_SLOTS);
- mView.createCards(1);
- mView.setStartAngle((float) -(2.0f*Math.PI * 5 / CARD_SLOTS));
- mView.setDefaultBitmap(BitmapFactory.decodeResource(res, R.drawable.wait));
- mView.setLoadingBitmap(BitmapFactory.decodeResource(res, R.drawable.wait));
- mView.setBackgroundColor(0.1f, 0.1f, 0.1f, 1.0f);
-
- mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
- mPortraitMode = decorView.getHeight() > decorView.getWidth();
-
- refresh();
- setContentView(mView);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- mHelper.onResume();
- refresh();
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- mHelper.onPause();
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- mPortraitMode = newConfig.orientation == Configuration.ORIENTATION_PORTRAIT;
- Log.v(TAG, "CONFIG CHANGE, mPortraitMode = " + mPortraitMode);
- refresh();
- }
-
- void updateRunningTasks() {
- mRunningTaskList = mActivityManager.getRunningTasks(MAX_TASKS + 2);
- Log.v(TAG, "Portrait: " + mPortraitMode);
- for (RunningTaskInfo r : mRunningTaskList) {
- if (r.thumbnail != null) {
- int thumbWidth = r.thumbnail.getWidth();
- int thumbHeight = r.thumbnail.getHeight();
- Log.v(TAG, "Got thumbnail " + thumbWidth + "x" + thumbHeight);
- ActivityDescription desc = findActivityDescription(r.id);
- if (desc != null) {
- desc.thumbnail = r.thumbnail;
- desc.description = r.description;
- if ((mPortraitMode && thumbWidth > thumbHeight)
- || (!mPortraitMode && thumbWidth < thumbHeight)) {
- Matrix matrix = new Matrix();
- matrix.setRotate(90.0f, (float) thumbWidth / 2, (float) thumbHeight / 2);
- desc.matrix = matrix;
- }
- } else {
- Log.v(TAG, "Couldn't find ActivityDesc for id=" + r.id);
- }
- } else {
- Log.v(TAG, "*** RUNNING THUMBNAIL WAS NULL ***");
- }
- }
- // HACK refresh carousel
- mView.createCards(mActivityDescriptions.size());
- }
-
- private void updateRecentTasks() {
- final PackageManager pm = getPackageManager();
- final ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
-
- final List<ActivityManager.RecentTaskInfo> recentTasks =
- am.getRecentTasks(MAX_TASKS + 2, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
-
- ActivityInfo homeInfo = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)
- .resolveActivityInfo(pm, 0);
-
- //IconUtilities iconUtilities = new IconUtilities(this);
-
- int numTasks = recentTasks.size();
- mActivityDescriptions.clear();
- for (int i = 1, index = 0; i < numTasks && (index < MAX_TASKS + 2); ++i) {
- final ActivityManager.RecentTaskInfo recentInfo = recentTasks.get(i);
-
- Intent intent = new Intent(recentInfo.baseIntent);
- if (recentInfo.origActivity != null) {
- intent.setComponent(recentInfo.origActivity);
- }
-
- // Skip the current home activity.
- if (homeInfo != null
- && homeInfo.packageName.equals(intent.getComponent().getPackageName())
- && homeInfo.name.equals(intent.getComponent().getClassName())) {
- continue;
- }
-
- intent.setFlags((intent.getFlags()&~Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
- | Intent.FLAG_ACTIVITY_NEW_TASK);
- final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0);
- if (resolveInfo != null) {
- final ActivityInfo info = resolveInfo.activityInfo;
- final String title = info.loadLabel(pm).toString();
- Drawable icon = info.loadIcon(pm);
-
- int id = recentInfo.id;
- if (id != -1 && title != null && title.length() > 0 && icon != null) {
- //icon = iconUtilities.createIconDrawable(icon);
- ActivityDescription item = new ActivityDescription(null, icon, title, null, id);
- item.intent = intent;
- mActivityDescriptions.add(item);
- Log.v(TAG, "Added item[" + index + "], id=" + item.id);
- ++index;
- } else {
- Log.v(TAG, "SKIPPING item " + id);
- }
- }
- }
- }
-
- private void refresh() {
- updateRecentTasks();
- updateRunningTasks();
- mView.createCards(mActivityDescriptions.size());
- }
-}