Merge "Put next task on top of stack if top is finishing." into klp-dev
diff --git a/api/current.txt b/api/current.txt
index ab48c8d..fd4ddf3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -12334,7 +12334,7 @@
field public static final int EULER_Z = 2; // 0x2
}
- public abstract interface Image implements java.lang.AutoCloseable {
+ public abstract class Image implements java.lang.AutoCloseable {
method public abstract void close();
method public abstract int getFormat();
method public abstract int getHeight();
@@ -12343,23 +12343,23 @@
method public abstract int getWidth();
}
- public static abstract interface Image.Plane {
+ public static abstract class Image.Plane {
method public abstract java.nio.ByteBuffer getBuffer();
method public abstract int getPixelStride();
method public abstract int getRowStride();
}
- public final class ImageReader implements java.lang.AutoCloseable {
- ctor public ImageReader(int, int, int, int);
+ public class ImageReader implements java.lang.AutoCloseable {
+ method public android.media.Image acquireLatestImage();
+ method public android.media.Image acquireNextImage();
method public void close();
method public int getHeight();
method public int getImageFormat();
method public int getMaxImages();
- method public android.media.Image getNextImage();
method public android.view.Surface getSurface();
method public int getWidth();
- method public void releaseImage(android.media.Image);
- method public void setImageAvailableListener(android.media.ImageReader.OnImageAvailableListener, android.os.Handler);
+ method public static android.media.ImageReader newInstance(int, int, int, int);
+ method public void setOnImageAvailableListener(android.media.ImageReader.OnImageAvailableListener, android.os.Handler);
}
public static abstract interface ImageReader.OnImageAvailableListener {
@@ -15211,9 +15211,9 @@
field public static final java.lang.String EXTRA_NDEF_MESSAGES = "android.nfc.extra.NDEF_MESSAGES";
field public static final java.lang.String EXTRA_READER_PRESENCE_CHECK_DELAY = "presence";
field public static final java.lang.String EXTRA_TAG = "android.nfc.extra.TAG";
- field public static final int FLAG_READER_KOVIO = 16; // 0x10
field public static final int FLAG_READER_NFC_A = 1; // 0x1
field public static final int FLAG_READER_NFC_B = 2; // 0x2
+ field public static final int FLAG_READER_NFC_BARCODE = 16; // 0x10
field public static final int FLAG_READER_NFC_F = 4; // 0x4
field public static final int FLAG_READER_NFC_V = 8; // 0x8
field public static final int FLAG_READER_NO_PLATFORM_SOUNDS = 256; // 0x100
diff --git a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
index 2c05c58..d0b3ec4 100644
--- a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
+++ b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
@@ -19,6 +19,7 @@
import static android.hardware.camera2.CameraAccessException.CAMERA_DISABLED;
import static android.hardware.camera2.CameraAccessException.CAMERA_DISCONNECTED;
import static android.hardware.camera2.CameraAccessException.CAMERA_IN_USE;
+import static android.hardware.camera2.CameraAccessException.MAX_CAMERAS_IN_USE;
import static android.hardware.camera2.CameraAccessException.CAMERA_DEPRECATED_HAL;
import android.os.DeadObjectException;
@@ -50,6 +51,7 @@
public static final int EBUSY = -16;
public static final int ENODEV = -19;
public static final int EOPNOTSUPP = -95;
+ public static final int EDQUOT = -122;
private static class CameraBinderDecoratorListener implements Decorator.DecoratorListener {
@@ -83,6 +85,9 @@
case EBUSY:
UncheckedThrow.throwAnyException(new CameraRuntimeException(
CAMERA_IN_USE));
+ case EDQUOT:
+ UncheckedThrow.throwAnyException(new CameraRuntimeException(
+ MAX_CAMERAS_IN_USE));
case ENODEV:
UncheckedThrow.throwAnyException(new CameraRuntimeException(
CAMERA_DISCONNECTED));
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 2a18900..486e75a 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -227,9 +227,9 @@
/**
* Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
* <p>
- * Setting this flag enables polling for Kovio technology.
+ * Setting this flag enables polling for NfcBarcode technology.
*/
- public static final int FLAG_READER_KOVIO = 0x10;
+ public static final int FLAG_READER_NFC_BARCODE = 0x10;
/**
* Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
diff --git a/core/java/android/transition/Fade.java b/core/java/android/transition/Fade.java
index 12e0d73..4cc2c42 100644
--- a/core/java/android/transition/Fade.java
+++ b/core/java/android/transition/Fade.java
@@ -91,6 +91,9 @@
return null;
}
final ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", startAlpha, endAlpha);
+ if (DBG) {
+ Log.d(LOG_TAG, "Created animator " + anim);
+ }
if (listener != null) {
anim.addListener(listener);
anim.addPauseListener(listener);
@@ -146,12 +149,41 @@
final View endView = endValues.view;
if (DBG) {
View startView = (startValues != null) ? startValues.view : null;
- Log.d(LOG_TAG, "Fade.onDisappear: startView, startVis, endView, endVis = " +
+ Log.d(LOG_TAG, "Fade.onAppear: startView, startVis, endView, endVis = " +
startView + ", " + startVisibility + ", " + endView + ", " + endVisibility);
}
// if alpha < 1, just fade it in from the current value
if (endView.getAlpha() == 1.0f) {
endView.setAlpha(0);
+ TransitionListener transitionListener = new TransitionListenerAdapter() {
+ boolean mCanceled = false;
+ float mPausedAlpha;
+
+ @Override
+ public void onTransitionCancel(Transition transition) {
+ endView.setAlpha(1);
+ mCanceled = true;
+ }
+
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ if (!mCanceled) {
+ endView.setAlpha(1);
+ }
+ }
+
+ @Override
+ public void onTransitionPause(Transition transition) {
+ mPausedAlpha = endView.getAlpha();
+ endView.setAlpha(1);
+ }
+
+ @Override
+ public void onTransitionResume(Transition transition) {
+ endView.setAlpha(mPausedAlpha);
+ }
+ };
+ addListener(transitionListener);
}
return createAnimation(endView, endView.getAlpha(), 1, null);
}
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index c588c6b..60b4708 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -1240,12 +1240,13 @@
View oldView = oldInfo.view;
TransitionValues newValues = mEndValues.viewValues != null ?
mEndValues.viewValues.get(oldView) : null;
+ if (newValues == null) {
+ newValues = mEndValues.idValues.get(oldView.getId());
+ }
if (oldValues != null) {
// if oldValues null, then transition didn't care to stash values,
// and won't get canceled
- if (newValues == null) {
- cancel = true;
- } else {
+ if (newValues != null) {
for (String key : oldValues.values.keySet()) {
Object oldValue = oldValues.values.get(key);
Object newValue = newValues.values.get(key);
@@ -1451,6 +1452,8 @@
try {
clone = (Transition) super.clone();
clone.mAnimators = new ArrayList<Animator>();
+ clone.mStartValues = new TransitionValuesMaps();
+ clone.mEndValues = new TransitionValuesMaps();
} catch (CloneNotSupportedException e) {}
return clone;
diff --git a/core/java/android/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java
index 54d801e..44ca4e5 100644
--- a/core/java/android/transition/TransitionManager.java
+++ b/core/java/android/transition/TransitionManager.java
@@ -22,6 +22,7 @@
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
/**
@@ -68,8 +69,9 @@
ArrayMap<Scene, Transition> mSceneTransitions = new ArrayMap<Scene, Transition>();
ArrayMap<Scene, ArrayMap<Scene, Transition>> mScenePairTransitions =
new ArrayMap<Scene, ArrayMap<Scene, Transition>>();
- private static ThreadLocal<ArrayMap<ViewGroup, ArrayList<Transition>>> sRunningTransitions =
- new ThreadLocal<ArrayMap<ViewGroup, ArrayList<Transition>>>();
+ private static ThreadLocal<WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>>>
+ sRunningTransitions =
+ new ThreadLocal<WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>>>();
private static ArrayList<ViewGroup> sPendingTransitions = new ArrayList<ViewGroup>();
@@ -184,20 +186,24 @@
}
private static ArrayMap<ViewGroup, ArrayList<Transition>> getRunningTransitions() {
- ArrayMap<ViewGroup, ArrayList<Transition>> runningTransitions =
+ WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>> runningTransitions =
sRunningTransitions.get();
- if (runningTransitions == null) {
- runningTransitions = new ArrayMap<ViewGroup, ArrayList<Transition>>();
+ if (runningTransitions == null || runningTransitions.get() == null) {
+ ArrayMap<ViewGroup, ArrayList<Transition>> transitions =
+ new ArrayMap<ViewGroup, ArrayList<Transition>>();
+ runningTransitions = new WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>>(
+ transitions);
sRunningTransitions.set(runningTransitions);
}
- return runningTransitions;
+ return runningTransitions.get();
}
private static void sceneChangeRunTransition(final ViewGroup sceneRoot,
final Transition transition) {
if (transition != null) {
final ViewTreeObserver observer = sceneRoot.getViewTreeObserver();
- observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+ final ViewTreeObserver.OnPreDrawListener listener =
+ new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
sPendingTransitions.remove(sceneRoot);
@@ -236,7 +242,8 @@
// values set on them again and avoid artifacts.
return false;
}
- });
+ };
+ observer.addOnPreDrawListener(listener);
}
}
@@ -342,23 +349,19 @@
* value of null causes the TransitionManager to use the default transition.
*/
public static void beginDelayedTransition(final ViewGroup sceneRoot, Transition transition) {
-
- // TEMPORARY: disabling delayed transitions until a fix for the various ActionBar-
- // triggered artifacts is found
-
-// if (!sPendingTransitions.contains(sceneRoot) && sceneRoot.isLaidOut()) {
-// if (Transition.DBG) {
-// Log.d(LOG_TAG, "beginDelayedTransition: root, transition = " +
-// sceneRoot + ", " + transition);
-// }
-// sPendingTransitions.add(sceneRoot);
-// if (transition == null) {
-// transition = sDefaultTransition;
-// }
-// final Transition finalTransition = transition.clone();
-// sceneChangeSetup(sceneRoot, transition);
-// Scene.setCurrentScene(sceneRoot, null);
-// sceneChangeRunTransition(sceneRoot, finalTransition);
-// }
+ if (!sPendingTransitions.contains(sceneRoot) && sceneRoot.isLaidOut()) {
+ if (Transition.DBG) {
+ Log.d(LOG_TAG, "beginDelayedTransition: root, transition = " +
+ sceneRoot + ", " + transition);
+ }
+ sPendingTransitions.add(sceneRoot);
+ if (transition == null) {
+ transition = sDefaultTransition;
+ }
+ final Transition transitionClone = transition.clone();
+ sceneChangeSetup(sceneRoot, transitionClone);
+ Scene.setCurrentScene(sceneRoot, null);
+ sceneChangeRunTransition(sceneRoot, transitionClone);
+ }
}
}
diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java
index 75d3e7c..f49821f 100644
--- a/core/java/android/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -65,9 +65,6 @@
ViewGroup endParent;
}
- // Temporary structure, used in calculating state in setup() and play()
- private VisibilityInfo mTmpVisibilityInfo = new VisibilityInfo();
-
@Override
public String[] getTransitionProperties() {
return sTransitionProperties;
@@ -161,7 +158,7 @@
private VisibilityInfo getVisibilityChangeInfo(TransitionValues startValues,
TransitionValues endValues) {
- final VisibilityInfo visInfo = mTmpVisibilityInfo;
+ final VisibilityInfo visInfo = new VisibilityInfo();
visInfo.visibilityChange = false;
visInfo.fadeIn = false;
if (startValues != null) {
diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java
index 730c4eb..ad8b51d 100644
--- a/core/java/android/view/ViewTreeObserver.java
+++ b/core/java/android/view/ViewTreeObserver.java
@@ -992,6 +992,8 @@
mData = mDataCopy;
}
mDataCopy = null;
+ mAccess.mData.clear();
+ mAccess.mSize = 0;
}
int size() {
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
index 91c47d1..76b8579 100644
--- a/core/java/com/android/internal/app/PlatLogoActivity.java
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -30,6 +30,8 @@
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.AnticipateOvershootInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
@@ -41,6 +43,7 @@
FrameLayout mContent;
int mCount;
final Handler mHandler = new Handler();
+ static final int BGCOLOR = 0xffed1d24;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -53,6 +56,7 @@
Typeface light = Typeface.create("sans-serif-light", Typeface.NORMAL);
mContent = new FrameLayout(this);
+ mContent.setBackgroundColor(0xC0000000);
final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
@@ -64,13 +68,16 @@
logo.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
logo.setVisibility(View.INVISIBLE);
+ final View bg = new View(this);
+ bg.setBackgroundColor(BGCOLOR);
+ bg.setAlpha(0f);
+
final TextView letter = new TextView(this);
letter.setTypeface(bold);
letter.setTextSize(300);
letter.setTextColor(0xFFFFFFFF);
letter.setGravity(Gravity.CENTER);
- letter.setShadowLayer(12*metrics.density, 0, 0, 0xC085F985);
letter.setText(String.valueOf(Build.VERSION.RELEASE).substring(0, 1));
final int p = (int)(4 * metrics.density);
@@ -81,11 +88,11 @@
tv.setPadding(p, p, p, p);
tv.setTextColor(0xFFFFFFFF);
tv.setGravity(Gravity.CENTER);
- tv.setShadowLayer(4 * metrics.density, 0, 2 * metrics.density, 0x66000000);
tv.setTransformationMethod(new AllCapsTransformationMethod(this));
tv.setText("Android " + Build.VERSION.RELEASE);
tv.setVisibility(View.INVISIBLE);
+ mContent.addView(bg);
mContent.addView(letter, lp);
mContent.addView(logo, lp);
@@ -96,24 +103,54 @@
mContent.addView(tv, lp2);
mContent.setOnClickListener(new View.OnClickListener() {
+ int clicks;
@Override
public void onClick(View v) {
- if (logo.getVisibility() != View.VISIBLE) {
- letter.animate().alpha(0.25f).scaleY(0.75f).scaleX(0.75f).setDuration(2000)
- .start();
- logo.setAlpha(0f);
- logo.setVisibility(View.VISIBLE);
- logo.animate().alpha(1f).setDuration(1000).setStartDelay(500).start();
- tv.setAlpha(0f);
- tv.setVisibility(View.VISIBLE);
- tv.animate().alpha(1f).setDuration(1000).setStartDelay(1000).start();
+ clicks++;
+ if (clicks >= 6) {
+ mContent.performLongClick();
+ return;
}
+ letter.animate().cancel();
+ final float offset = (int)letter.getRotation() % 360;
+ letter.animate()
+ .rotationBy((Math.random() > 0.5f ? 360 : -360) - offset)
+ .setInterpolator(new DecelerateInterpolator())
+ .setDuration(700).start();
}
});
mContent.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
+ if (logo.getVisibility() != View.VISIBLE) {
+ bg.setScaleX(0.01f);
+ bg.animate().alpha(1f).scaleX(1f).setStartDelay(500).start();
+ letter.animate().alpha(0f).scaleY(0.5f).scaleX(0.5f)
+ .rotationBy(360)
+ .setInterpolator(new AccelerateInterpolator())
+ .setDuration(1000)
+ .start();
+ logo.setAlpha(0f);
+ logo.setVisibility(View.VISIBLE);
+ logo.setScaleX(0.5f);
+ logo.setScaleY(0.5f);
+ logo.animate().alpha(1f).scaleX(1f).scaleY(1f)
+ .setDuration(1000).setStartDelay(500)
+ .setInterpolator(new AnticipateOvershootInterpolator())
+ .start();
+ tv.setAlpha(0f);
+ tv.setVisibility(View.VISIBLE);
+ tv.animate().alpha(1f).setDuration(1000).setStartDelay(1000).start();
+ return true;
+ }
+ return false;
+ }
+ });
+
+ logo.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
try {
startActivity(new Intent(Intent.ACTION_MAIN)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
diff --git a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
index 2d06b68..f773f59 100644
--- a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
+++ b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
@@ -159,17 +159,26 @@
}
-static SkMemoryStream* adaptor_to_mem_stream(SkStream* adaptor) {
- SkASSERT(adaptor != NULL);
- SkDynamicMemoryWStream wStream;
- const int bufferSize = 256 * 1024; // 256 KB, same as ViewStateSerializer.
- uint8_t buffer[bufferSize];
- do {
- size_t bytesRead = adaptor->read(buffer, bufferSize);
- wStream.write(buffer, bytesRead);
- } while (!adaptor->isAtEnd());
- SkAutoTUnref<SkData> data(wStream.copyToData());
- return new SkMemoryStream(data.get());
+static SkMemoryStream* adaptor_to_mem_stream(SkStream* stream) {
+ SkASSERT(stream != NULL);
+ size_t bufferSize = 4096;
+ size_t streamLen = 0;
+ size_t len;
+ char* data = (char*)sk_malloc_throw(bufferSize);
+
+ while ((len = stream->read(data + streamLen,
+ bufferSize - streamLen)) != 0) {
+ streamLen += len;
+ if (streamLen == bufferSize) {
+ bufferSize *= 2;
+ data = (char*)sk_realloc_throw(data, bufferSize);
+ }
+ }
+ data = (char*)sk_realloc_throw(data, streamLen);
+
+ SkMemoryStream* streamMem = new SkMemoryStream();
+ streamMem->setMemoryOwned(data, streamLen);
+ return streamMem;
}
SkStreamRewindable* CopyJavaInputStream(JNIEnv* env, jobject stream,
diff --git a/core/res/res/drawable-hdpi/stat_sys_adb_am.png b/core/res/res/drawable-hdpi/stat_sys_adb_am.png
index 0c13339..382557e 100644
--- a/core/res/res/drawable-hdpi/stat_sys_adb_am.png
+++ b/core/res/res/drawable-hdpi/stat_sys_adb_am.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_adb_am.png b/core/res/res/drawable-mdpi/stat_sys_adb_am.png
index f0a5089..4380035 100644
--- a/core/res/res/drawable-mdpi/stat_sys_adb_am.png
+++ b/core/res/res/drawable-mdpi/stat_sys_adb_am.png
Binary files differ
diff --git a/core/res/res/drawable-nodpi/platlogo.png b/core/res/res/drawable-nodpi/platlogo.png
index 4fd0e3c..6351c2d 100644
--- a/core/res/res/drawable-nodpi/platlogo.png
+++ b/core/res/res/drawable-nodpi/platlogo.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_adb_am.png b/core/res/res/drawable-xhdpi/stat_sys_adb_am.png
index 789a3f5..3222a76 100644
--- a/core/res/res/drawable-xhdpi/stat_sys_adb_am.png
+++ b/core/res/res/drawable-xhdpi/stat_sys_adb_am.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_adb_am.png b/core/res/res/drawable-xxhdpi/stat_sys_adb_am.png
index a36fa36..e01ad386 100644
--- a/core/res/res/drawable-xxhdpi/stat_sys_adb_am.png
+++ b/core/res/res/drawable-xxhdpi/stat_sys_adb_am.png
Binary files differ
diff --git a/core/tests/ConnectivityManagerTest/AndroidManifest.xml b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
index b76c8be..1649268 100644
--- a/core/tests/ConnectivityManagerTest/AndroidManifest.xml
+++ b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
@@ -23,13 +23,6 @@
which is needed when building test cases. -->
<application>
<uses-library android:name="android.test.runner" />
- <activity android:name="ConnectivityManagerTestActivity"
- android:label="@string/app_name">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
</application>
<!--
@@ -87,4 +80,6 @@
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<uses-permission android:name="android.permission.INJECT_EVENTS" />
+ <uses-permission android:name="android.permission.DEVICE_POWER" />
+
</manifest>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
index 0461c0b..b942eb6 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
@@ -32,13 +32,11 @@
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.RouteInfo;
-import android.util.Log;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java
similarity index 88%
rename from core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
rename to core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java
index a0cb1bb..30eda75 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java
@@ -16,7 +16,7 @@
package com.android.connectivitymanagertest;
-import android.app.Activity;
+import android.app.KeyguardManager;
import android.content.Context;
import android.content.BroadcastReceiver;
import android.content.Intent;
@@ -26,21 +26,14 @@
import android.net.NetworkInfo.State;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration.KeyMgmt;
-import android.os.Bundle;
import android.os.Handler;
-import android.os.IPowerManager;
import android.os.Message;
import android.os.PowerManager;
-import android.os.ServiceManager;
import android.os.SystemClock;
-import android.os.UserHandle;
-import android.provider.Settings;
+import android.test.InstrumentationTestCase;
import android.util.Log;
import android.view.KeyEvent;
-import android.widget.LinearLayout;
import com.android.internal.util.AsyncChannel;
@@ -52,13 +45,17 @@
/**
- * An activity registered with connectivity manager broadcast
- * provides network connectivity information and
- * can be used to set device states: Cellular, Wifi, Airplane mode.
+ * Base InstrumentationTestCase for Connectivity Manager (CM) test suite
+ *
+ * It registers connectivity manager broadcast and WiFi broadcast to provide
+ * network connectivity information, also provides a set of utility functions
+ * to modify and verify connectivity states.
+ *
+ * A CM test case should extend this base class.
*/
-public class ConnectivityManagerTestActivity extends Activity {
+public class ConnectivityManagerTestBase extends InstrumentationTestCase {
- public static final String LOG_TAG = "ConnectivityManagerTestActivity";
+ public static final String LOG_TAG = "ConnectivityManagerTestBase";
public static final int WAIT_FOR_SCAN_RESULT = 10 * 1000; //10 seconds
public static final int WIFI_SCAN_TIMEOUT = 50 * 1000; // 50 seconds
public static final int SHORT_TIMEOUT = 5 * 1000; // 5 seconds
@@ -94,14 +91,9 @@
private Context mContext;
public boolean scanResultAvailable = false;
- /*
- * Control Wifi States
- */
+ /* Control Wifi States */
public WifiManager mWifiManager;
-
- /*
- * Verify connectivity state
- */
+ /* Verify connectivity state */
public static final int NUM_NETWORK_TYPES = ConnectivityManager.MAX_NETWORK_TYPE + 1;
NetworkState[] connectivityState = new NetworkState[NUM_NETWORK_TYPES];
@@ -208,26 +200,28 @@
}
}
- public ConnectivityManagerTestActivity() {
+ @Override
+ public void setUp() throws Exception {
mState = State.UNKNOWN;
scanResultAvailable = false;
- }
+ mContext = getInstrumentation().getContext();
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- log("onCreate, inst=" + Integer.toHexString(hashCode()));
+ // Get an instance of ConnectivityManager
+ mCM = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+ // Get an instance of WifiManager
+ mWifiManager =(WifiManager)mContext.getSystemService(Context.WIFI_SERVICE);
- // Create a simple layout
- LinearLayout contentView = new LinearLayout(this);
- contentView.setOrientation(LinearLayout.VERTICAL);
- setContentView(contentView);
- setTitle("ConnectivityManagerTestActivity");
+ if (mWifiManager.isWifiApEnabled()) {
+ // if soft AP is enabled, disable it
+ mWifiManager.setWifiApEnabled(null, false);
+ log("Disable soft ap");
+ }
+ initializeNetworkStates();
// register a connectivity receiver for CONNECTIVITY_ACTION;
mConnectivityReceiver = new ConnectivityReceiver();
- registerReceiver(mConnectivityReceiver,
+ mContext.registerReceiver(mConnectivityReceiver,
new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
mWifiReceiver = new WifiReceiver();
@@ -238,28 +232,15 @@
mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
mIntentFilter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
mIntentFilter.addAction(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
- registerReceiver(mWifiReceiver, mIntentFilter);
+ mContext.registerReceiver(mWifiReceiver, mIntentFilter);
- // Get an instance of ConnectivityManager
- mCM = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
- // Get an instance of WifiManager
- mWifiManager =(WifiManager)getSystemService(Context.WIFI_SERVICE);
- mContext = this;
-
- if (mWifiManager.isWifiApEnabled()) {
- // if soft AP is enabled, disable it
- mWifiManager.setWifiApEnabled(null, false);
- log("Disable soft ap");
- }
-
- initializeNetworkStates();
log("Clear Wifi before we start the test.");
removeConfiguredNetworksAndDisableWifi();
mWifiRegexs = mCM.getTetherableWifiRegexs();
}
public List<WifiConfiguration> loadNetworkConfigurations() throws Exception {
- InputStream in = getAssets().open(ACCESS_POINT_FILE);
+ InputStream in = mContext.getAssets().open(ACCESS_POINT_FILE);
mParseHelper = new AccessPointParserHelper(in);
return mParseHelper.getNetworkConfigurations();
}
@@ -277,6 +258,12 @@
public void recordNetworkState(int networkType, State networkState) {
log("record network state for network " + networkType +
", state is " + networkState);
+ if (connectivityState == null) {
+ log("ConnectivityState is null");
+ }
+ if (connectivityState[networkType] == null) {
+ log("connectivityState[networkType] is null");
+ }
connectivityState[networkType].recordState(networkState);
}
@@ -503,7 +490,7 @@
public void turnScreenOff() {
log("Turn screen off");
PowerManager pm =
- (PowerManager) getSystemService(Context.POWER_SERVICE);
+ (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
pm.goToSleep(SystemClock.uptimeMillis());
}
@@ -511,8 +498,13 @@
public void turnScreenOn() {
log("Turn screen on");
PowerManager pm =
- (PowerManager) getSystemService(Context.POWER_SERVICE);
+ (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
pm.wakeUp(SystemClock.uptimeMillis());
+ // disable lock screen
+ KeyguardManager km = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
+ if (km.inKeyguardRestrictedInputMode()) {
+ sendKeys(KeyEvent.KEYCODE_MENU);
+ }
}
/**
@@ -607,7 +599,12 @@
mWifiManager.setWifiEnabled(true);
sleep(SHORT_TIMEOUT);
}
+
List<WifiConfiguration> wifiConfigList = mWifiManager.getConfiguredNetworks();
+ if (wifiConfigList == null) {
+ log("no configuration list is null");
+ return true;
+ }
log("size of wifiConfigList: " + wifiConfigList.size());
for (WifiConfiguration wifiConfig: wifiConfigList) {
log("remove wifi configuration: " + wifiConfig.networkId);
@@ -656,57 +653,15 @@
}
@Override
- protected void onDestroy() {
- super.onDestroy();
-
+ public void tearDown() throws Exception{
//Unregister receiver
if (mConnectivityReceiver != null) {
- unregisterReceiver(mConnectivityReceiver);
+ mContext.unregisterReceiver(mConnectivityReceiver);
}
if (mWifiReceiver != null) {
- unregisterReceiver(mWifiReceiver);
+ mContext.unregisterReceiver(mWifiReceiver);
}
- log("onDestroy, inst=" + Integer.toHexString(hashCode()));
- }
-
- @Override
- public void onStart() {
- super.onStart();
- mContext = this;
- Bundle bundle = this.getIntent().getExtras();
- if (bundle != null){
- mPowerSsid = bundle.getString("power_ssid");
- }
- }
- //A thread to set the device into airplane mode then turn on wifi.
- Thread setDeviceWifiAndAirplaneThread = new Thread(new Runnable() {
- public void run() {
- mCM.setAirplaneMode(true);
- connectToWifi(mPowerSsid);
- }
- });
-
- //A thread to set the device into wifi
- Thread setDeviceInWifiOnlyThread = new Thread(new Runnable() {
- public void run() {
- connectToWifi(mPowerSsid);
- }
- });
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- switch (keyCode) {
- //This is a tricky way for the scripted monkey to
- //set the device in wifi and wifi in airplane mode.
- case KeyEvent.KEYCODE_1:
- setDeviceWifiAndAirplaneThread.start();
- break;
-
- case KeyEvent.KEYCODE_2:
- setDeviceInWifiOnlyThread.start();
- break;
- }
- return super.onKeyDown(keyCode, event);
+ super.tearDown();
}
private void log(String message) {
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerUnitTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerUnitTestRunner.java
index 3a78f26..0e57a00 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerUnitTestRunner.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerUnitTestRunner.java
@@ -16,10 +16,8 @@
package com.android.connectivitymanagertest;
-import android.os.Bundle;
import android.test.InstrumentationTestRunner;
import android.test.InstrumentationTestSuite;
-import android.util.Log;
import com.android.connectivitymanagertest.unit.WifiClientTest;
import com.android.connectivitymanagertest.unit.WifiSoftAPTest;
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
index 729e1d2..05462b4 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
@@ -24,31 +24,24 @@
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.provider.Settings;
-import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
import android.util.Log;
-import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
+import com.android.connectivitymanagertest.ConnectivityManagerTestBase;
import com.android.connectivitymanagertest.ConnectivityManagerTestRunner;
import com.android.connectivitymanagertest.NetworkState;
public class ConnectivityManagerMobileTest extends
- ActivityInstrumentationTestCase2<ConnectivityManagerTestActivity> {
- private static final String LOG_TAG = "ConnectivityManagerMobileTest";
+ ConnectivityManagerTestBase {
+ private static final String TAG = "ConnectivityManagerMobileTest";
private String mTestAccessPoint;
- private ConnectivityManagerTestActivity cmActivity;
private WakeLock wl;
private boolean mWifiOnlyFlag;
- public ConnectivityManagerMobileTest() {
- super(ConnectivityManagerTestActivity.class);
- }
-
@Override
public void setUp() throws Exception {
super.setUp();
- cmActivity = getActivity();
ConnectivityManagerTestRunner mRunner =
(ConnectivityManagerTestRunner)getInstrumentation();
mTestAccessPoint = mRunner.mTestSsid;
@@ -62,12 +55,12 @@
if (Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(),
Settings.Global.AIRPLANE_MODE_ON) == 1) {
log("airplane is not disabled, disable it.");
- cmActivity.mCM.setAirplaneMode(false);
+ mCM.setAirplaneMode(false);
}
if (!mWifiOnlyFlag) {
- if (!cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
- ConnectivityManagerTestActivity.LONG_TIMEOUT)) {
+ if (!waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+ State.CONNECTED, LONG_TIMEOUT)) {
// Note: When the test fails in setUp(), tearDown is not called. In that case,
// the activity is destroyed which blocks the next test at "getActivity()".
// tearDown() is called here to avoid that situation.
@@ -79,29 +72,22 @@
@Override
public void tearDown() throws Exception {
- cmActivity.finish();
- log("tear down ConnectivityManagerTestActivity");
wl.release();
- cmActivity.removeConfiguredNetworksAndDisableWifi();
- // if airplane mode is set, disable it.
- if (Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(),
- Settings.Global.AIRPLANE_MODE_ON) == 1) {
- log("disable airplane mode if it is enabled");
- cmActivity.mCM.setAirplaneMode(false);
- }
+ removeConfiguredNetworksAndDisableWifi();
+ mCM.setAirplaneMode(false);
super.tearDown();
}
// help function to verify 3G connection
public void verifyCellularConnection() {
- NetworkInfo extraNetInfo = cmActivity.mCM.getActiveNetworkInfo();
+ NetworkInfo extraNetInfo = mCM.getActiveNetworkInfo();
assertEquals("network type is not MOBILE", ConnectivityManager.TYPE_MOBILE,
extraNetInfo.getType());
assertTrue("not connected to cellular network", extraNetInfo.isConnected());
}
private void log(String message) {
- Log.v(LOG_TAG, message);
+ Log.v(TAG, message);
}
private void sleep(long sleeptime) {
@@ -115,46 +101,46 @@
@LargeTest
public void test3GToWifiNotification() {
if (mWifiOnlyFlag) {
- Log.v(LOG_TAG, this.getName() + " is excluded for wifi-only test");
+ Log.v(TAG, this.getName() + " is excluded for wifi-only test");
return;
}
// Enable Wi-Fi to avoid initial UNKNOWN state
- cmActivity.enableWifi();
- sleep(2 * ConnectivityManagerTestActivity.SHORT_TIMEOUT);
+ enableWifi();
+ sleep(2 * SHORT_TIMEOUT);
// Wi-Fi is disabled
- cmActivity.disableWifi();
+ disableWifi();
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI,
- State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
- State.CONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI,
+ State.DISCONNECTED, LONG_TIMEOUT));
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+ State.CONNECTED, LONG_TIMEOUT));
// Wait for 10 seconds for broadcasts to be sent out
sleep(10 * 1000);
// As Wifi stays in DISCONNETED, Mobile statys in CONNECTED,
// the connectivity manager will not broadcast any network connectivity event for Wifi
- NetworkInfo networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
- cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+ NetworkInfo networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+ setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
networkInfo.getState(), NetworkState.DO_NOTHING, State.CONNECTED);
- networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
- cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
+ networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+ setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
NetworkState.DO_NOTHING, State.DISCONNECTED);
// Eanble Wifi without associating with any AP
- cmActivity.enableWifi();
- sleep(2 * ConnectivityManagerTestActivity.SHORT_TIMEOUT);
+ enableWifi();
+ sleep(2 * SHORT_TIMEOUT);
// validate state and broadcast
- if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
+ if (!validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
log("the state for WIFI is changed");
log("reason: " +
- cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
+ getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
assertTrue("state validation fail", false);
}
- if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
+ if (!validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
log("the state for MOBILE is changed");
log("reason: " +
- cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
+ getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
assertTrue("state validation fail", false);
}
// Verify that the device is still connected to MOBILE
@@ -168,40 +154,39 @@
NetworkInfo networkInfo;
if (!mWifiOnlyFlag) {
//Prepare for connectivity verification
- networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
- cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+ networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+ setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
networkInfo.getState(), NetworkState.TO_DISCONNECTION, State.DISCONNECTED);
}
- networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
- cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
+ networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+ setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
NetworkState.TO_CONNECTION, State.CONNECTED);
// Enable Wifi and connect to a test access point
assertTrue("failed to connect to " + mTestAccessPoint,
- cmActivity.connectToWifi(mTestAccessPoint));
+ connectToWifi(mTestAccessPoint));
- assertTrue(cmActivity.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
- ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ assertTrue(waitForWifiState(WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT));
log("wifi state is enabled");
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
- ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+ WIFI_CONNECTION_TIMEOUT));
if (!mWifiOnlyFlag) {
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
- State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+ State.DISCONNECTED, LONG_TIMEOUT));
}
// validate states
- if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
+ if (!validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
log("Wifi state transition validation failed.");
log("reason: " +
- cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
+ getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
assertTrue(false);
}
if (!mWifiOnlyFlag) {
- if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
+ if (!validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
log("Mobile state transition validation failed.");
log("reason: " +
- cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
+ getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
assertTrue(false);
}
}
@@ -213,61 +198,59 @@
assertNotNull("SSID is null", mTestAccessPoint);
// Connect to mTestAccessPoint
assertTrue("failed to connect to " + mTestAccessPoint,
- cmActivity.connectToWifi(mTestAccessPoint));
- assertTrue(cmActivity.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
- ConnectivityManagerTestActivity.LONG_TIMEOUT));
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
- ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+ connectToWifi(mTestAccessPoint));
+ assertTrue(waitForWifiState(WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT));
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+ WIFI_CONNECTION_TIMEOUT));
- sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
+ sleep(SHORT_TIMEOUT);
// Disable Wifi
log("Disable Wifi");
- if (!cmActivity.disableWifi()) {
+ if (!disableWifi()) {
log("disable Wifi failed");
return;
}
// Wait for the Wifi state to be DISABLED
- assertTrue(cmActivity.waitForWifiState(WifiManager.WIFI_STATE_DISABLED,
- ConnectivityManagerTestActivity.LONG_TIMEOUT));
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI,
- State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ assertTrue(waitForWifiState(WifiManager.WIFI_STATE_DISABLED, LONG_TIMEOUT));
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI,
+ State.DISCONNECTED, LONG_TIMEOUT));
if (!mWifiOnlyFlag) {
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
- State.CONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+ State.CONNECTED, LONG_TIMEOUT));
}
NetworkInfo networkInfo;
if (!mWifiOnlyFlag) {
//Prepare for connectivity state verification
- networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
- cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+ networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+ setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
networkInfo.getState(), NetworkState.DO_NOTHING,
State.DISCONNECTED);
}
- networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
- cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
+ networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+ setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
NetworkState.TO_CONNECTION, State.CONNECTED);
// wait for 2 minutes before restart wifi
- sleep(ConnectivityManagerTestActivity.WIFI_STOP_START_INTERVAL);
+ sleep(WIFI_STOP_START_INTERVAL);
// Enable Wifi again
log("Enable Wifi again");
- cmActivity.enableWifi();
+ enableWifi();
// Wait for Wifi to be connected and mobile to be disconnected
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
- ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+ WIFI_CONNECTION_TIMEOUT));
if (!mWifiOnlyFlag) {
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
- State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+ State.DISCONNECTED, LONG_TIMEOUT));
}
// validate wifi states
- if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
+ if (!validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
log("Wifi state transition validation failed.");
log("reason: " +
- cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
+ getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
assertTrue(false);
}
}
@@ -279,48 +262,48 @@
// connect to Wifi
assertTrue("failed to connect to " + mTestAccessPoint,
- cmActivity.connectToWifi(mTestAccessPoint));
+ connectToWifi(mTestAccessPoint));
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
- ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+ WIFI_CONNECTION_TIMEOUT));
// Wait for a few seconds to avoid the state that both Mobile and Wifi is connected
- sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
+ sleep(SHORT_TIMEOUT);
NetworkInfo networkInfo;
if (!mWifiOnlyFlag) {
- networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
- cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+ networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+ setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
networkInfo.getState(),
NetworkState.TO_CONNECTION,
State.CONNECTED);
}
- networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
- cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
+ networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+ setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
NetworkState.TO_DISCONNECTION, State.DISCONNECTED);
// clear Wifi
- cmActivity.removeConfiguredNetworksAndDisableWifi();
+ removeConfiguredNetworksAndDisableWifi();
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
- ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI,
+ State.DISCONNECTED, LONG_TIMEOUT));
if (!mWifiOnlyFlag) {
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
- State.CONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+ State.CONNECTED, LONG_TIMEOUT));
}
// validate states
- if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
+ if (!validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
log("Wifi state transition validation failed.");
log("reason: " +
- cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
+ getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
assertTrue(false);
}
if (!mWifiOnlyFlag) {
- if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
+ if (!validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
log("Mobile state transition validation failed.");
log("reason: " +
- cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
+ getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
assertTrue(false);
}
}
@@ -330,62 +313,62 @@
@LargeTest
public void testDataConnectionWith3GToAmTo3G() {
if (mWifiOnlyFlag) {
- Log.v(LOG_TAG, this.getName() + " is excluded for wifi-only test");
+ Log.v(TAG, this.getName() + " is excluded for wifi-only test");
return;
}
//Prepare for state verification
- NetworkInfo networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
- cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+ NetworkInfo networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+ setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
networkInfo.getState(),
NetworkState.TO_DISCONNECTION,
State.DISCONNECTED);
- networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+ networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
assertEquals(State.DISCONNECTED, networkInfo.getState());
// Enable airplane mode
log("Enable airplane mode");
- cmActivity.mCM.setAirplaneMode(true);
- sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
+ mCM.setAirplaneMode(true);
+ sleep(SHORT_TIMEOUT);
- networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+ networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
assertEquals(State.DISCONNECTED, networkInfo.getState());
// wait until mobile is turn off
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
- State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
- if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+ State.DISCONNECTED, LONG_TIMEOUT));
+ if (!validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
log("Mobile state transition validation failed.");
log("reason: " +
- cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
+ getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
assertTrue(false);
}
// reset state recorder
- networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
- cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+ networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+ setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
networkInfo.getState(),
NetworkState.TO_CONNECTION,
State.CONNECTED);
- networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
- cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
+ networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+ setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
NetworkState.DO_NOTHING, State.DISCONNECTED);
// disable airplane mode
- cmActivity.mCM.setAirplaneMode(false);
+ mCM.setAirplaneMode(false);
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
- ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+ State.CONNECTED, LONG_TIMEOUT));
// Validate the state transition
- if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
+ if (!validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
log("Mobile state transition validation failed.");
log("reason: " +
- cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
+ getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
assertTrue(false);
}
- if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
+ if (!validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
log("Wifi state transition validation failed.");
log("reason: " +
- cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
+ getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
assertTrue(false);
}
}
@@ -394,107 +377,107 @@
@LargeTest
public void testDataConnectionOverAMWithWifi() {
if (mWifiOnlyFlag) {
- Log.v(LOG_TAG, this.getName() + " is excluded for wifi-only test");
+ Log.v(TAG, this.getName() + " is excluded for wifi-only test");
return;
}
assertNotNull("SSID is null", mTestAccessPoint);
// Eanble airplane mode
log("Enable airplane mode");
- cmActivity.mCM.setAirplaneMode(true);
+ mCM.setAirplaneMode(true);
NetworkInfo networkInfo;
if (!mWifiOnlyFlag) {
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
- State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
- networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
- cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+ State.DISCONNECTED, LONG_TIMEOUT));
+ networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+ setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
networkInfo.getState(),
NetworkState.DO_NOTHING,
State.DISCONNECTED);
}
- networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
- cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
+ networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+ setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
NetworkState.TO_CONNECTION, State.CONNECTED);
// Connect to Wifi
assertTrue("failed to connect to " + mTestAccessPoint,
- cmActivity.connectToWifi(mTestAccessPoint));
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
- ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+ connectToWifi(mTestAccessPoint));
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+ WIFI_CONNECTION_TIMEOUT));
// validate state and broadcast
- if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
+ if (!validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
log("state validate for Wifi failed");
log("reason: " +
- cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
+ getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
assertTrue("State validation failed", false);
}
if (!mWifiOnlyFlag) {
- if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
+ if (!validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
log("state validation for Mobile failed");
log("reason: " +
- cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
+ getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
assertTrue("state validation failed", false);
}
}
- cmActivity.mCM.setAirplaneMode(false);
+ mCM.setAirplaneMode(false);
}
// Test case 7: test connectivity while transit from Wifi->AM->Wifi
@LargeTest
public void testDataConnectionWithWifiToAMToWifi () {
if (mWifiOnlyFlag) {
- Log.v(LOG_TAG, this.getName() + " is excluded for wifi-only test");
+ Log.v(TAG, this.getName() + " is excluded for wifi-only test");
return;
}
// Connect to mTestAccessPoint
assertNotNull("SSID is null", mTestAccessPoint);
// Connect to Wifi
assertTrue("failed to connect to " + mTestAccessPoint,
- cmActivity.connectToWifi(mTestAccessPoint));
+ connectToWifi(mTestAccessPoint));
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
- ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+ WIFI_CONNECTION_TIMEOUT));
try {
- Thread.sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
+ Thread.sleep(SHORT_TIMEOUT);
} catch (Exception e) {
log("exception: " + e.toString());
}
// Enable airplane mode without clearing Wifi
- cmActivity.mCM.setAirplaneMode(true);
+ mCM.setAirplaneMode(true);
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
- ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI,
+ State.DISCONNECTED, LONG_TIMEOUT));
try {
- Thread.sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
+ Thread.sleep(SHORT_TIMEOUT);
} catch (Exception e) {
log("exception: " + e.toString());
}
// Prepare for state validation
- NetworkInfo networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+ NetworkInfo networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
assertEquals(State.DISCONNECTED, networkInfo.getState());
- cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI,
+ setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI,
networkInfo.getState(), NetworkState.TO_CONNECTION, State.CONNECTED);
// Disable airplane mode
- cmActivity.mCM.setAirplaneMode(false);
+ mCM.setAirplaneMode(false);
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
- ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+ WIFI_CONNECTION_TIMEOUT));
if (!mWifiOnlyFlag) {
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
- State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+ State.DISCONNECTED, LONG_TIMEOUT));
}
// validate the state transition
- if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
+ if (!validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
log("Wifi state transition validation failed.");
log("reason: " +
- cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
+ getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
assertTrue(false);
}
}
@@ -505,35 +488,33 @@
assertNotNull("SSID is null", mTestAccessPoint);
//Connect to mTestAccessPoint
assertTrue("failed to connect to " + mTestAccessPoint,
- cmActivity.connectToWifi(mTestAccessPoint));
- assertTrue(cmActivity.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
- ConnectivityManagerTestActivity.LONG_TIMEOUT));
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
- ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+ connectToWifi(mTestAccessPoint));
+ assertTrue(waitForWifiState(WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT));
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+ WIFI_CONNECTION_TIMEOUT));
assertNotNull("Not associated with any AP",
- cmActivity.mWifiManager.getConnectionInfo().getBSSID());
+ mWifiManager.getConnectionInfo().getBSSID());
try {
- Thread.sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
+ Thread.sleep(SHORT_TIMEOUT);
} catch (Exception e) {
log("exception: " + e.toString());
}
// Disconnect from the current AP
log("disconnect from the AP");
- if (!cmActivity.disconnectAP()) {
+ if (!disconnectAP()) {
log("failed to disconnect from " + mTestAccessPoint);
}
// Verify the connectivity state for Wifi is DISCONNECTED
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
- ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI,
+ State.DISCONNECTED, LONG_TIMEOUT));
- if (!cmActivity.disableWifi()) {
+ if (!disableWifi()) {
log("disable Wifi failed");
return;
}
- assertTrue(cmActivity.waitForWifiState(WifiManager.WIFI_STATE_DISABLED,
- ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ assertTrue(waitForWifiState(WifiManager.WIFI_STATE_DISABLED, LONG_TIMEOUT));
}
}
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java
index f12e62e..183f2a9 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java
@@ -16,7 +16,7 @@
package com.android.connectivitymanagertest.functional;
-import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
+import com.android.connectivitymanagertest.ConnectivityManagerTestBase;
import com.android.connectivitymanagertest.WifiAssociationTestRunner;
import android.content.Context;
@@ -32,7 +32,6 @@
import android.net.ConnectivityManager;
import android.net.NetworkInfo.State;
import android.test.suitebuilder.annotation.LargeTest;
-import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
/**
@@ -43,30 +42,22 @@
* -w com.android.connectivitymanagertest/.WifiAssociationTestRunner"
*/
public class WifiAssociationTest
- extends ActivityInstrumentationTestCase2<ConnectivityManagerTestActivity> {
+ extends ConnectivityManagerTestBase {
private static final String TAG = "WifiAssociationTest";
- private ConnectivityManagerTestActivity mAct;
private String mSsid = null;
private String mPassword = null;
private String mSecurityType = null;
private String mFrequencyBand = null;
private int mBand;
- private WifiManager mWifiManager = null;
enum SECURITY_TYPE {
OPEN, WEP64, WEP128, WPA_TKIP, WPA2_AES
- };
-
- public WifiAssociationTest() {
- super(ConnectivityManagerTestActivity.class);
}
@Override
public void setUp() throws Exception {
super.setUp();
WifiAssociationTestRunner mRunner = (WifiAssociationTestRunner)getInstrumentation();
- mWifiManager = (WifiManager) mRunner.getContext().getSystemService(Context.WIFI_SERVICE);
- mAct = getActivity();
Bundle arguments = mRunner.getArguments();
mSecurityType = arguments.getString("security-type");
mSsid = arguments.getString("ssid");
@@ -77,17 +68,15 @@
assertNotNull("Ssid is empty", mSsid);
validateFrequencyBand();
// enable Wifi and verify wpa_supplicant is started
- assertTrue("enable Wifi failed", mAct.enableWifi());
- sleep(2 * ConnectivityManagerTestActivity.SHORT_TIMEOUT,
- "interrupted while waiting for WPA_SUPPLICANT to start");
- WifiInfo mConnection = mAct.mWifiManager.getConnectionInfo();
+ assertTrue("enable Wifi failed", enableWifi());
+ sleep(2 * SHORT_TIMEOUT, "interrupted while waiting for WPA_SUPPLICANT to start");
+ WifiInfo mConnection = mWifiManager.getConnectionInfo();
assertNotNull(mConnection);
- assertTrue("wpa_supplicant is not started ", mAct.mWifiManager.pingSupplicant());
+ assertTrue("wpa_supplicant is not started ", mWifiManager.pingSupplicant());
}
@Override
public void tearDown() throws Exception {
- log("tearDown()");
super.tearDown();
}
@@ -107,16 +96,16 @@
private void connectToWifi(WifiConfiguration config) {
// step 1: connect to the test access point
assertTrue("failed to associate with " + config.SSID,
- mAct.connectToWifiWithConfiguration(config));
+ connectToWifiWithConfiguration(config));
// step 2: verify Wifi state and network state;
assertTrue("failed to connect with " + config.SSID,
- mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI,
- State.CONNECTED, ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+ waitForNetworkState(ConnectivityManager.TYPE_WIFI,
+ State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
// step 3: verify the current connected network is the given SSID
- assertNotNull("Wifi connection returns null", mAct.mWifiManager.getConnectionInfo());
- assertTrue(config.SSID.contains(mAct.mWifiManager.getConnectionInfo().getSSID()));
+ assertNotNull("Wifi connection returns null", mWifiManager.getConnectionInfo());
+ assertTrue(config.SSID.contains(mWifiManager.getConnectionInfo().getSSID()));
}
private void sleep(long sometime, String errorMsg) {
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java
index de0298e..ad73ee1 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java
@@ -16,35 +16,19 @@
package com.android.connectivitymanagertest.functional;
-import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
+import com.android.connectivitymanagertest.ConnectivityManagerTestBase;
import com.android.connectivitymanagertest.ConnectivityManagerTestRunner;
-import android.R;
-import android.app.Activity;
-import android.content.ContentResolver;
-import android.content.Intent;
import android.content.Context;
-import android.content.res.Resources;
import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiConfiguration.KeyMgmt;
-import android.net.wifi.WifiConfiguration.Status;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.ConnectivityManager;
-import android.net.DhcpInfo;
-import android.net.NetworkInfo;
import android.net.NetworkInfo.State;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.Settings;
import android.test.suitebuilder.annotation.LargeTest;
-import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
-import com.android.internal.util.AsyncChannel;
-
import java.util.ArrayList;
-import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -56,39 +40,25 @@
* -w com.android.connectivitymanagertest/.ConnectivityManagerTestRunner
*/
public class WifiConnectionTest
- extends ActivityInstrumentationTestCase2<ConnectivityManagerTestActivity> {
+ extends ConnectivityManagerTestBase {
private static final String TAG = "WifiConnectionTest";
private static final boolean DEBUG = false;
private List<WifiConfiguration> networks = new ArrayList<WifiConfiguration>();
- private ConnectivityManagerTestActivity mAct;
- private ConnectivityManagerTestRunner mRunner;
- private WifiManager mWifiManager = null;
- private Set<WifiConfiguration> enabledNetworks = null;
-
- public WifiConnectionTest() {
- super(ConnectivityManagerTestActivity.class);
- }
@Override
public void setUp() throws Exception {
super.setUp();
- mRunner = ((ConnectivityManagerTestRunner)getInstrumentation());
- mWifiManager = (WifiManager) mRunner.getContext().getSystemService(Context.WIFI_SERVICE);
-
- mAct = getActivity();
-
- networks = mAct.loadNetworkConfigurations();
+ networks = loadNetworkConfigurations();
if (DEBUG) {
printNetworkConfigurations();
}
// enable Wifi and verify wpa_supplicant is started
- assertTrue("enable Wifi failed", mAct.enableWifi());
- sleep(2 * ConnectivityManagerTestActivity.SHORT_TIMEOUT,
- "interrupted while waiting for WPA_SUPPLICANT to start");
- WifiInfo mConnection = mAct.mWifiManager.getConnectionInfo();
+ assertTrue("enable Wifi failed", enableWifi());
+ sleep(2 * SHORT_TIMEOUT, "interrupted while waiting for WPA_SUPPLICANT to start");
+ WifiInfo mConnection = mWifiManager.getConnectionInfo();
assertNotNull(mConnection);
- assertTrue("wpa_supplicant is not started ", mAct.mWifiManager.pingSupplicant());
+ assertTrue("wpa_supplicant is not started ", mWifiManager.pingSupplicant());
}
private void printNetworkConfigurations() {
@@ -101,8 +71,7 @@
@Override
public void tearDown() throws Exception {
- log("tearDown()");
- mAct.removeConfiguredNetworksAndDisableWifi();
+ removeConfiguredNetworksAndDisableWifi();
super.tearDown();
}
@@ -114,20 +83,20 @@
private void connectToWifi(WifiConfiguration config) {
// step 1: connect to the test access point
assertTrue("failed to connect to " + config.SSID,
- mAct.connectToWifiWithConfiguration(config));
+ connectToWifiWithConfiguration(config));
// step 2: verify Wifi state and network state;
- assertTrue(mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI,
- State.CONNECTED, ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI,
+ State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
// step 3: verify the current connected network is the given SSID
- assertNotNull("Wifi connection returns null", mAct.mWifiManager.getConnectionInfo());
+ assertNotNull("Wifi connection returns null", mWifiManager.getConnectionInfo());
if (DEBUG) {
log("config.SSID = " + config.SSID);
- log("mAct.mWifiManager.getConnectionInfo.getSSID()" +
- mAct.mWifiManager.getConnectionInfo().getSSID());
+ log("mWifiManager.getConnectionInfo.getSSID()" +
+ mWifiManager.getConnectionInfo().getSSID());
}
- assertTrue(config.SSID.contains(mAct.mWifiManager.getConnectionInfo().getSSID()));
+ assertTrue(config.SSID.contains(mWifiManager.getConnectionInfo().getSSID()));
}
private void sleep(long sometime, String errorMsg) {
@@ -149,8 +118,7 @@
log("-- START Wi-Fi connection test to : " + ssid + " --");
connectToWifi(networks.get(i));
// wait for 2 minutes between wifi stop and start
- sleep(ConnectivityManagerTestActivity.WIFI_STOP_START_INTERVAL,
- "interruped while connected to wifi");
+ sleep(WIFI_STOP_START_INTERVAL, "interruped while connected to wifi");
log("-- END Wi-Fi connection test to " + ssid + " -- ");
}
}
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
index 60595fb..790ca38 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
@@ -18,19 +18,13 @@
import com.android.connectivitymanagertest.ConnectivityManagerStressTestRunner;
-import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
+import com.android.connectivitymanagertest.ConnectivityManagerTestBase;
-import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.net.wifi.WifiConfiguration.AuthAlgorithm;
import android.net.wifi.WifiManager;
import android.os.Environment;
-import android.os.IPowerManager;
-import android.os.PowerManager;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
import android.util.Log;
@@ -42,30 +36,24 @@
* Stress the wifi driver as access point.
*/
public class WifiApStress
- extends ActivityInstrumentationTestCase2<ConnectivityManagerTestActivity> {
+ extends ConnectivityManagerTestBase {
private final static String TAG = "WifiApStress";
private static String NETWORK_ID = "AndroidAPTest";
private static String PASSWD = "androidwifi";
private final static String OUTPUT_FILE = "WifiStressTestOutput.txt";
- private ConnectivityManagerTestActivity mAct;
private int iterations;
private BufferedWriter mOutputWriter = null;
private int mLastIteration = 0;
private boolean mWifiOnlyFlag;
- public WifiApStress() {
- super(ConnectivityManagerTestActivity.class);
- }
-
@Override
public void setUp() throws Exception {
super.setUp();
- mAct = getActivity();
ConnectivityManagerStressTestRunner mRunner =
(ConnectivityManagerStressTestRunner)getInstrumentation();
iterations = mRunner.mSoftapIterations;
mWifiOnlyFlag = mRunner.mWifiOnlyFlag;
- mAct.turnScreenOn();
+ turnScreenOn();
}
@Override
@@ -92,30 +80,28 @@
config.preSharedKey = PASSWD;
// If Wifi is enabled, disable it
- if (mAct.mWifiManager.isWifiEnabled()) {
- mAct.disableWifi();
+ if (mWifiManager.isWifiEnabled()) {
+ disableWifi();
}
int i;
for (i = 0; i < iterations; i++) {
Log.v(TAG, "iteration: " + i);
mLastIteration = i;
// enable Wifi tethering
- assertTrue(mAct.mWifiManager.setWifiApEnabled(config, true));
+ assertTrue(mWifiManager.setWifiApEnabled(config, true));
// Wait for wifi ap state to be ENABLED
- assertTrue(mAct.waitForWifiAPState(WifiManager.WIFI_AP_STATE_ENABLED,
- 2 * ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ assertTrue(waitForWifiAPState(WifiManager.WIFI_AP_STATE_ENABLED, 2 * LONG_TIMEOUT));
// Wait for wifi tethering result
- assertEquals(ConnectivityManagerTestActivity.SUCCESS,
- mAct.waitForTetherStateChange(2*ConnectivityManagerTestActivity.SHORT_TIMEOUT));
+ assertEquals(SUCCESS, waitForTetherStateChange(2 * SHORT_TIMEOUT));
// Allow the wifi tethering to be enabled for 10 seconds
try {
- Thread.sleep(2 * ConnectivityManagerTestActivity.SHORT_TIMEOUT);
+ Thread.sleep(2 * SHORT_TIMEOUT);
} catch (Exception e) {
fail("thread in sleep is interrupted");
}
- assertTrue("no uplink data connection after Wi-Fi tethering", mAct.pingTest(null));
+ assertTrue("no uplink data connection after Wi-Fi tethering", pingTest(null));
// Disable soft AP
- assertTrue(mAct.mWifiManager.setWifiApEnabled(config, false));
+ assertTrue(mWifiManager.setWifiApEnabled(config, false));
// Wait for 30 seconds until Wi-Fi tethering is stopped
try {
Thread.sleep(30 * 1000);
@@ -123,7 +109,7 @@
} catch (Exception e) {
fail("thread in sleep is interrupted");
}
- assertFalse("Wi-Fi AP disable failed", mAct.mWifiManager.isWifiApEnabled());
+ assertFalse("Wi-Fi AP disable failed", mWifiManager.isWifiApEnabled());
}
if (i == iterations) {
mLastIteration = iterations;
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
index e3c7cc4..04ce4b7 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -29,12 +29,11 @@
import android.os.PowerManager;
import android.provider.Settings;
import android.view.KeyEvent;
-import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
import android.util.Log;
import com.android.connectivitymanagertest.ConnectivityManagerStressTestRunner;
-import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
+import com.android.connectivitymanagertest.ConnectivityManagerTestBase;
import java.io.BufferedWriter;
import java.io.File;
@@ -50,7 +49,7 @@
* -w com.android.connectivitymanagertest/.ConnectivityManagerStressTestRunner
*/
public class WifiStressTest
- extends ActivityInstrumentationTestCase2<ConnectivityManagerTestActivity> {
+ extends ConnectivityManagerTestBase {
private final static String TAG = "WifiStressTest";
/**
@@ -67,7 +66,6 @@
private final static long WIFI_SHUTDOWN_DELAY = 2 * 60 * 1000;
private final static String OUTPUT_FILE = "WifiStressTestOutput.txt";
- private ConnectivityManagerTestActivity mAct;
private int mReconnectIterations;
private int mWifiSleepTime;
private int mScanIterations;
@@ -77,15 +75,10 @@
private BufferedWriter mOutputWriter = null;
private boolean mWifiOnlyFlag;
- public WifiStressTest() {
- super(ConnectivityManagerTestActivity.class);
- }
-
@Override
public void setUp() throws Exception {
super.setUp();
- mAct = getActivity();
mRunner = (ConnectivityManagerStressTestRunner) getInstrumentation();
mReconnectIterations = mRunner.mReconnectIterations;
mSsid = mRunner.mReconnectSsid;
@@ -98,15 +91,14 @@
mPassword, mScanIterations, mWifiSleepTime));
mOutputWriter = new BufferedWriter(new FileWriter(new File(
Environment.getExternalStorageDirectory(), OUTPUT_FILE), true));
- mAct.turnScreenOn();
- if (!mAct.mWifiManager.isWifiEnabled()) {
+ turnScreenOn();
+ if (!mWifiManager.isWifiEnabled()) {
log("Enable wi-fi before stress tests.");
- if (!mAct.enableWifi()) {
+ if (!enableWifi()) {
tearDown();
fail("enable wifi failed.");
}
- sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT,
- "Interruped while waiting for wifi on");
+ sleep(SHORT_TIMEOUT, "Interruped while waiting for wifi on");
}
}
@@ -166,33 +158,32 @@
writeOutput(String.format("ssid appear %d out of %d scan iterations",
ssidAppearInScanResultsCount, i));
long startTime = System.currentTimeMillis();
- mAct.scanResultAvailable = false;
- assertTrue("start scan failed", mAct.mWifiManager.startScan());
+ scanResultAvailable = false;
+ assertTrue("start scan failed", mWifiManager.startScan());
while (true) {
if ((System.currentTimeMillis() - startTime) >
- ConnectivityManagerTestActivity.WIFI_SCAN_TIMEOUT) {
- fail("Wifi scanning takes more than " +
- ConnectivityManagerTestActivity.WIFI_SCAN_TIMEOUT + " ms");
+ WIFI_SCAN_TIMEOUT) {
+ fail("Wifi scanning takes more than " + WIFI_SCAN_TIMEOUT + " ms");
}
- synchronized(mAct) {
+ synchronized(this) {
try {
- mAct.wait(ConnectivityManagerTestActivity.WAIT_FOR_SCAN_RESULT);
+ wait(WAIT_FOR_SCAN_RESULT);
} catch (InterruptedException e) {
e.printStackTrace();
}
- if (mAct.scanResultAvailable) {
+ if (scanResultAvailable) {
long scanTime = (System.currentTimeMillis() - startTime);
scanTimeSum += scanTime;
break;
}
}
}
- if ((mAct.mWifiManager.getScanResults() == null) ||
- (mAct.mWifiManager.getScanResults().size() <= 0)) {
+ if ((mWifiManager.getScanResults() == null) ||
+ (mWifiManager.getScanResults().size() <= 0)) {
fail("Scan results are empty ");
}
- List<ScanResult> netList = mAct.mWifiManager.getScanResults();
+ List<ScanResult> netList = mWifiManager.getScanResults();
if (netList != null) {
log("size of scan result list: " + netList.size());
for (int s = 0; s < netList.size(); s++) {
@@ -244,13 +235,13 @@
config.proxySettings = ProxySettings.NONE;
assertTrue("Failed to connect to Wi-Fi network: " + mSsid,
- mAct.connectToWifiWithConfiguration(config));
- assertTrue(mAct.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
- ConnectivityManagerTestActivity.SHORT_TIMEOUT));
- assertTrue(mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
- ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+ connectToWifiWithConfiguration(config));
+ assertTrue(waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
+ SHORT_TIMEOUT));
+ assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+ WIFI_CONNECTION_TIMEOUT));
// Run ping test to verify the data connection
- assertTrue("Wi-Fi is connected, but no data connection.", mAct.pingTest(null));
+ assertTrue("Wi-Fi is connected, but no data connection.", pingTest(null));
int i;
long sum = 0;
@@ -263,33 +254,33 @@
writeOutput(String.format("iteration %d out of %d",
i, mReconnectIterations));
log("iteration: " + i);
- mAct.turnScreenOff();
+ turnScreenOff();
PowerManager pm =
(PowerManager)mRunner.getContext().getSystemService(Context.POWER_SERVICE);
assertFalse(pm.isScreenOn());
sleep(WIFI_IDLE_MS + WIFI_SHUTDOWN_DELAY, "Interruped while wait for wifi to be idle");
assertTrue("Wait for Wi-Fi to idle timeout",
- mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
- 6 * ConnectivityManagerTestActivity.SHORT_TIMEOUT));
+ waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
+ 6 * SHORT_TIMEOUT));
if (!mWifiOnlyFlag) {
// use long timeout as the pppd startup may take several retries.
assertTrue("Wait for cellular connection timeout",
- mAct.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
- 2 * ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
+ 2 * LONG_TIMEOUT));
}
sleep(mWifiSleepTime, "Interrupted while device is in sleep mode");
// Verify the wi-fi is still off and data connection is on
assertEquals("Wi-Fi is reconnected", State.DISCONNECTED,
- mAct.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState());
+ mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState());
if (!mWifiOnlyFlag) {
assertEquals("Cellular connection is down", State.CONNECTED,
- mAct.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState());
- assertTrue("Mobile is connected, but no data connection.", mAct.pingTest(null));
+ mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState());
+ assertTrue("Mobile is connected, but no data connection.", pingTest(null));
}
// Turn screen on again
- mAct.turnScreenOn();
+ turnScreenOn();
// Wait for 2 seconds for the lock screen
sleep(2 * 1000, "wait 2 seconds for lock screen");
// Disable lock screen by inject menu key event
@@ -298,16 +289,16 @@
// Measure the time for Wi-Fi to get connected
long startTime = System.currentTimeMillis();
assertTrue("Wait for Wi-Fi enable timeout after wake up",
- mAct.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
- ConnectivityManagerTestActivity.SHORT_TIMEOUT));
+ waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
+ SHORT_TIMEOUT));
assertTrue("Wait for Wi-Fi connection timeout after wake up",
- mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
- ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+ waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+ WIFI_CONNECTION_TIMEOUT));
long connectionTime = System.currentTimeMillis() - startTime;
sum += connectionTime;
log("average reconnection time is: " + sum/(i+1));
- assertTrue("Reconnect to Wi-Fi network, but no data connection.", mAct.pingTest(null));
+ assertTrue("Reconnect to Wi-Fi network, but no data connection.", pingTest(null));
}
if (i == mReconnectIterations) {
writeOutput(String.format("iteration %d out of %d",
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java
index e44023b..7a9bc78 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java
@@ -20,9 +20,6 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.Context;
-import android.app.Instrumentation;
-import android.os.Handler;
-import android.os.Message;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiConfiguration;
@@ -33,11 +30,8 @@
import android.test.suitebuilder.annotation.LargeTest;
import android.test.AndroidTestCase;
-import java.util.ArrayList;
import java.util.List;
-import android.util.Log;
-
/**
* Test wifi client
*/
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiSoftAPTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiSoftAPTest.java
index 3f43e48..f202862 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiSoftAPTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiSoftAPTest.java
@@ -16,13 +16,7 @@
package com.android.connectivitymanagertest.unit;
-import android.content.BroadcastReceiver;
-import android.content.Intent;
import android.content.Context;
-import android.app.Instrumentation;
-import android.os.Handler;
-import android.os.Message;
-import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.KeyMgmt;
@@ -30,8 +24,6 @@
import android.test.suitebuilder.annotation.LargeTest;
import android.test.AndroidTestCase;
-import java.util.ArrayList;
-
import android.util.Log;
/**
diff --git a/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java b/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java
index ebecf2e3..a2e9ae8 100644
--- a/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java
+++ b/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java
@@ -83,8 +83,8 @@
mImageReaderLock.lock();
try {
- mImageReader = new ImageReader(WIDTH, HEIGHT, PixelFormat.RGBA_8888, 2);
- mImageReader.setImageAvailableListener(mImageListener, mHandler);
+ mImageReader = ImageReader.newInstance(WIDTH, HEIGHT, PixelFormat.RGBA_8888, 2);
+ mImageReader.setOnImageAvailableListener(mImageListener, mHandler);
mSurface = mImageReader.getSurface();
} finally {
mImageReaderLock.unlock();
@@ -409,19 +409,11 @@
}
Log.d(TAG, "New image available from virtual display.");
- Image image = reader.getNextImage();
+
+ // Get the latest buffer.
+ Image image = reader.acquireLatestImage();
if (image != null) {
try {
- // Get the latest buffer.
- for (;;) {
- Image nextImage = reader.getNextImage();
- if (nextImage == null) {
- break;
- }
- reader.releaseImage(image);
- image = nextImage;
- }
-
// Scan for colors.
int color = scanImage(image);
synchronized (this) {
@@ -431,7 +423,7 @@
}
}
} finally {
- reader.releaseImage(image);
+ image.close();
}
}
} finally {
diff --git a/docs/html/guide/topics/renderscript/compute.jd b/docs/html/guide/topics/renderscript/compute.jd
index 607d16e..14a1682 100644
--- a/docs/html/guide/topics/renderscript/compute.jd
+++ b/docs/html/guide/topics/renderscript/compute.jd
@@ -10,6 +10,11 @@
<ol>
<li><a href="#writing-an-rs-kernel">Writing a RenderScript Kernel</a></li>
+ <li><a href="#access-rs-apis">Accessing RenderScript Java APIs</a>
+ <ol>
+ <li><a href="#ide-setup">Setting Up Your Development Environment</a></li>
+ </ol>
+ </li>
<li><a href="#using-rs-from-java">Using RenderScript from Java Code</a></li>
</ol>
@@ -144,9 +149,85 @@
beneficial on some architectures due to additional optimizations only available with relaxed
precision (such as SIMD CPU instructions).</p>
+
+<h2 id="access-rs-apis">Accessing RenderScript Java APIs</h2>
+
+<p>When developing an Android application that uses RenderScript, you can access its Java API in
+ one of two ways. The APIs are available in the {@link android.renderscript} package
+ on devices running Android 3.0 (API level 11) and higher. These are the original APIs for
+ RenderScript. The APIs are also available as a Support Library in the
+ {@link android.support.v8.renderscript} package, which allow you to use them on devices running
+ Android 2.2 (API level 8) and higher.</p>
+
+<p>We strongly recommend using the Support Library APIs for accessing RenderScript because they
+ include the latest improvements to the RenderScript compute framework and provide a wider range
+ of device compatibility. Using the RenderScript APIs in the Support Library requires specific
+ setup procedures for your development environment, which is described in the next section.</p>
+
+
+<h3 id="ide-setup">Using the RenderScript Support Library APIs</h3>
+
+<p>In order to use the Support Library RenderScript APIs, you must configure your development
+ environment to be able to access them. The following Android SDK tools are required for using
+ these APIs:</p>
+
+<ul>
+ <li>Android SDK Tools revision 22.2 or higher</li>
+ <li>Android SDK Build-tools revision 18.1.0 or higher</li>
+</ul>
+
+<p>You can check and update the installed version of these tools in the
+ <a href="{@docRoot}tools/help/sdk-manager.html">Android SDK Manager</a>.</p>
+
+<p class="note">
+ <strong>Note:</strong> Use of Support Library RenderScript APIs is not currently supported with
+ Android Studio or Gradle-based builds.
+</p>
+
+<p>To use the Support Library RenderScript APIs in Eclipse:</p>
+
+<ol>
+ <li>Make sure you have the required Android SDK version and Build Tools version installed.</li>
+ <li>Open the {@code project.properties} file in the root folder of your application project.</li>
+ <li>Add the following lines to the file:
+<pre>
+renderscript.target=18
+renderscript.support.mode=true
+sdk.buildtools=18.1.0
+</pre>
+ </li>
+ <li>In your application classes that use RenderScript, add an import for the Support Library
+ classes:
+<pre>
+import android.support.v8.renderscript.*;
+</pre>
+ </li>
+</ol>
+
+<p>The {@code project.properties} settings listed above control specific behavior in the Android
+ build process:</p>
+
+<ul>
+ <li>{@code renderscript.target} - Specifies the bytecode version to be generated. We
+ recommend you set this value the highest available API level and set {@code
+ renderscript.support.mode} to {@code true}. Valid values for this setting are any integer value
+ from 11 to the most recently released API level. If your minimum SDK version specified in your
+ application manifest is set to a higher value, this value is ignored and the target value is set
+ to the minimum SDK version.</li>
+ <li>{@code renderscript.support.mode} - Specifies that the generated bytecode should fall
+ back to a compatible version if the device it is running on does not support the target version.
+ </li>
+ <li>{@code sdk.buildtools} - The version of the Android SDK build tools to use. This value
+ should be set to 18.1.0 or higher. If this option is not specified, the highest installed build
+ tools version is used. You should always set this value to ensure the consistency of builds
+ across development machines with different configurations.</li>
+</ul>
+
+
<h2 id="using-rs-from-java">Using RenderScript from Java Code</h2>
-<p>Using RenderScript from Java code relies on the {@link android.renderscript} APIs. Most
+<p>Using RenderScript from Java code relies on the API classes located in the
+{@link android.renderscript} or the {@link android.support.v8.renderscript} package. Most
applications follow the same basic usage patterns:</p>
<ol>
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 4ea3752..0581435 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -5,43 +5,43 @@
page.metaDescription=Download the official Android SDK to develop apps for Android-powered devices.
-sdk.linux32_bundle_download=adt-bundle-linux-x86-20130729.zip
-sdk.linux32_bundle_bytes=457716139
-sdk.linux32_bundle_checksum=b3686d10dc1cbceba1074404d4386283
+sdk.linux32_bundle_download=adt-bundle-linux-x86-20130911.zip
+sdk.linux32_bundle_bytes=474916528
+sdk.linux32_bundle_checksum=7eacc7124299ea99a8fa15c59123540f
-sdk.linux64_bundle_download=adt-bundle-linux-x86_64-20130729.zip
-sdk.linux64_bundle_bytes=458006784
-sdk.linux64_bundle_checksum=1fabcc3f772ba8b2fc194d6e0449da17
+sdk.linux64_bundle_download=adt-bundle-linux-x86_64-20130911.zip
+sdk.linux64_bundle_bytes=475207785
+sdk.linux64_bundle_checksum=daa5794a27be7c7fa708c3d28833b0d3
-sdk.mac64_bundle_download=adt-bundle-mac-x86_64-20130729.zip
-sdk.mac64_bundle_bytes=428792424
-sdk.mac64_bundle_checksum=6c42b9966abcfa8a75c0ee83d0d95882
+sdk.mac64_bundle_download=adt-bundle-mac-x86_64-20130911.zip
+sdk.mac64_bundle_bytes=448575446
+sdk.mac64_bundle_checksum=a1e0cbcc820ae734cfdf439c40811b4c
-sdk.win32_bundle_download=adt-bundle-windows-x86-20130729.zip
-sdk.win32_bundle_bytes=463931746
-sdk.win32_bundle_checksum=51faf4e5fdf9c5b4a176179a99ce3511
+sdk.win32_bundle_download=adt-bundle-windows-x86-20130911.zip
+sdk.win32_bundle_bytes=481794820
+sdk.win32_bundle_checksum=88a2f4f242aac44f4b1c53e6eccc8710
-sdk.win64_bundle_download=adt-bundle-windows-x86_64-20130729.zip
-sdk.win64_bundle_bytes=464064756
-sdk.win64_bundle_checksum=e8f05c1fddb8e609e880de23113c7426
+sdk.win64_bundle_download=adt-bundle-windows-x86_64-20130911.zip
+sdk.win64_bundle_bytes=481927327
+sdk.win64_bundle_checksum=e3fa9b7e38af9ed9ac0e99fce3c7026c
-sdk.linux_download=android-sdk_r22.0.5-linux.tgz
-sdk.linux_bytes=105641005
-sdk.linux_checksum=8201b10c21510f082c54f58a9bb082c8
+sdk.linux_download=android-sdk_r22.2-linux.tgz
+sdk.linux_bytes=100909403
+sdk.linux_checksum=2a3776839e823ba9acb7a87a3fe26e02
-sdk.mac_download=android-sdk_r22.0.5-macosx.zip
-sdk.mac_bytes=77225724
-sdk.mac_checksum=94f3cbe896c332b94ee0408ae610a4b8
+sdk.mac_download=android-sdk_r22.2-macosx.zip
+sdk.mac_bytes=74857114
+sdk.mac_checksum=9dfef6404e2f842c433073796aed8b7d
-sdk.win_download=android-sdk_r22.0.5-windows.zip
-sdk.win_bytes=113510621
-sdk.win_checksum=30695dffc41e0d7cf9ff948ab0c48920
+sdk.win_download=android-sdk_r22.2-windows.zip
+sdk.win_bytes=108790714
+sdk.win_checksum=1ac4c104378cd53049daa6c4458ec544
-sdk.win_installer=installer_r22.0.5-windows.exe
-sdk.win_installer_bytes=93505782
-sdk.win_installer_checksum=940849be19ac6151e3e35c8706c81d86
+sdk.win_installer=installer_r22.2-windows.exe
+sdk.win_installer_bytes=88788974
+sdk.win_installer_checksum=e5503fa059297d2b18475c086ac6e80c
diff --git a/docs/html/sdk/installing/installing-adt.jd b/docs/html/sdk/installing/installing-adt.jd
index bdc07d0..e038d20 100644
--- a/docs/html/sdk/installing/installing-adt.jd
+++ b/docs/html/sdk/installing/installing-adt.jd
@@ -1,8 +1,8 @@
page.title=Installing the Eclipse Plugin
-adt.zip.version=22.0.5
-adt.zip.download=ADT-22.0.5.zip
-adt.zip.bytes=16839757
-adt.zip.checksum=1097fccf32063e3638a9d27aa0f295ca
+adt.zip.version=22.2.0
+adt.zip.download=ADT-22.2.0.zip
+adt.zip.bytes=14474195
+adt.zip.checksum=52892c9e3b1ad2d1e6edd50e48b2a127
@jd:body
diff --git a/docs/html/tools/sdk/eclipse-adt.jd b/docs/html/tools/sdk/eclipse-adt.jd
index e9c514e..151707a 100644
--- a/docs/html/tools/sdk/eclipse-adt.jd
+++ b/docs/html/tools/sdk/eclipse-adt.jd
@@ -57,6 +57,44 @@
<div class="toggle-content opened">
<p><a href="#" onclick="return toggleContent(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+ alt=""/>ADT 22.2</a> <em>(September 2013)</em>
+ </p>
+
+ <div class="toggle-content-toggleme">
+<dl>
+ <dt>Dependencies:</dt>
+
+ <dd>
+ <ul>
+ <li>Java 1.6 or higher is required.</li>
+ <li>Eclipse Helios (Version 3.6.2) or higher is required.</li>
+ <li>This version of ADT is designed for use with
+ <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r22.2</a>.
+ If you haven't already installed SDK Tools r22.2 into your SDK, use the
+ Android SDK Manager to do so.</li>
+ </ul>
+ </dd>
+
+ <dt>General Notes:</dt>
+ <dd>
+ <ul>
+ <li>Updated build tools to allow use of RenderScript on older versions of Android
+ using new features in the
+ <a href="{@docRoot}tools/support-library/features.html#v8">Support Library</a>.</li>
+ <li>Reverted signing changes that sometimes trigger a signing verification problem on older
+ platforms.</li>
+ <li>Fixed problem with gradle export function for the Windows platform.</li>
+ </ul>
+ </dd>
+
+</dl>
+</div>
+</div>
+
+
+<div class="toggle-content closed">
+ <p><a href="#" onclick="return toggleContent(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
alt=""/>ADT 22.0.5</a> <em>(July 2013)</em>
</p>
@@ -78,7 +116,7 @@
<dt>General Notes:</dt>
<dd>
<ul>
- <li>Fixed Renderscript compilation issue for Windows platforms.</li>
+ <li>Fixed RenderScript compilation issue for Windows platforms.</li>
<li>Updated <a href="{@docRoot}tools/help/systrace.html">Systrace</a> report generation
in the Monitor and DDMS perspectives.</li>
</ul>
@@ -113,7 +151,7 @@
<dt>General Notes:</dt>
<dd>
<ul>
- <li>Fixed problem with compiling Renderscript code.</li>
+ <li>Fixed problem with compiling RenderScript code.</li>
<li>Improved Gradle export with better workflow and error reporting.</li>
<li>Improved Gradle multi-module export feature.</li>
<li>Updated build logic to force exporting of the classpath containers unless you are using
@@ -1005,7 +1043,7 @@
<dt>Bug fixes:</dt>
<dd>
<ul>
- <li>Fixed build issue when using Renderscript in projects that target API levels 11-13
+ <li>Fixed build issue when using RenderScript in projects that target API levels 11-13
(<a href="http://code.google.com/p/android/issues/detail?id=21006">Issue 21006</a>).</li>
<li>Fixed issue when creating projects from existing source code.</li>
<li>Fixed issues in the SDK Manager
diff --git a/docs/html/tools/sdk/tools-notes.jd b/docs/html/tools/sdk/tools-notes.jd
index 4aef8a0..e8c4717 100644
--- a/docs/html/tools/sdk/tools-notes.jd
+++ b/docs/html/tools/sdk/tools-notes.jd
@@ -30,6 +30,54 @@
<div class="toggle-content opened">
<p><a href="#" onclick="return toggleContent(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+ alt=""/>SDK Tools, Revision 22.2</a> <em>(September 2013)</em>
+ </p>
+
+ <div class="toggle-content-toggleme">
+
+ <dl>
+ <dt>Dependencies:</dt>
+ <dd>
+ <ul>
+ <li>Android SDK Platform-tools revision 16 or later.</li>
+ <li>If you are developing in Eclipse with ADT, note that this version of SDK Tools is
+ designed for use with ADT 22.2 and later. If you haven't already, update your
+ <a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 22.2.</li>
+ <li>If you are developing outside Eclipse, you must have
+ <a href="http://ant.apache.org/">Apache Ant</a> 1.8 or later.</li>
+ </ul>
+ </dd>
+
+ <dt>General Notes:</dt>
+ <dd>
+ <ul>
+ <li>Updated build tools to allow use of RenderScript on older versions of Android
+ using new features in the
+ <a href="{@docRoot}tools/support-library/features.html#v8">Support Library</a>.</li>
+ <li>Moved the Systrace tool to the {@code >sdk</platform-tools/} directory. </li>
+ <li>Modified <a href="{@docRoot}tools/help/gltracer.html">Tracer for OpenGL ES</a> to
+ support OpenGL ES 3.0.</li>
+ <li>Lint
+ <ul>
+ <li>Fixed problem with lint not detecting custom namespaces.
+ (<a href="http://b.android.com/55673">Issue 55673</a>)</li>
+ <li>Fixed problem with the XML report including invalid characters.
+ (<a href="http://b.android.com/56205">Issue 56205</a>)</li>
+ <li>Fixed command-line execution of lint to work in headless mode to support execution
+ by build servers. (<a href="http://b.android.com/55820">Issue 55820</a>)</li>
+ </ul>
+ </li>
+ <li>Improved support for path names with spaces in the Windows command-line tools.</li>
+ </ul>
+ </dd>
+ </dl>
+ </div>
+</div>
+
+
+<div class="toggle-content closed">
+ <p><a href="#" onclick="return toggleContent(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
alt=""/>SDK Tools, Revision 22.0.5</a> <em>(July 2013)</em>
</p>
@@ -55,10 +103,10 @@
<dt>General Notes:</dt>
<dd>
<ul>
- <li>Fixed Renderscript compilation issue for Windows platforms with ant.</li>
+ <li>Fixed RenderScript compilation issue for Windows platforms with ant.</li>
<li>Updated <a href="{@docRoot}tools/help/systrace.html">Systrace</a> to work with the
Android 4.3 platform image.</li>
- <li>Fixed packaging of Renderscript compiler.</li>
+ <li>Fixed packaging of RenderScript compiler.</li>
<li>Build tools 18.0.0 is obsolete and 18.0.1 should be used instead.</li>
</ul>
</dd>
@@ -95,7 +143,7 @@
<dt>General Notes:</dt>
<dd>
<ul>
- <li>Fixed problem with compiling Renderscript code.</li>
+ <li>Fixed problem with compiling RenderScript code.</li>
</ul>
</dd>
</dl>
@@ -274,17 +322,17 @@
</ul>
</li>
- <li>Renderscript
+ <li>RenderScript
<ul>
<li>Added support for
<a href="{@docRoot}guide/topics/renderscript/compute.html#filterscript">Filterscript</a>
compilation.</li>
- <li>Added new project setting to control the Renderscript compilation target separately
+ <li>Added new project setting to control the RenderScript compilation target separately
from an Android project. Adding the following line to a {@code project.properties}
- file causes Renderscript code to be compiled for Android API Level 17, while the
+ file causes RenderScript code to be compiled for Android API Level 17, while the
containing application can target a different (lower) API level:
<pre>renderscript.target = 17</pre>
- Previously, the Renderscript compilation target was tied to the
+ Previously, the RenderScript compilation target was tied to the
{@code android:minSdkVersion} setting in the manifest.
(<a href="http://code.google.com/p/android/issues/detail?id=40487">Issue 40487</a>)
</li>
@@ -483,7 +531,7 @@
<li>Improved resize algorithm for better rendering on scaled emulator windows.</li>
<li>Fixed a bug in the {@code lint} check for unprotected broadcast receivers to ignore
unprotected receivers for default Android actions.</li>
- <li>Fixed build issue for projects using Renderscript.</li>
+ <li>Fixed build issue for projects using RenderScript.</li>
<li>Fixed memory leak in the emulator.</li>
</ul>
</dd>
@@ -823,7 +871,7 @@
<li>Fixed emulator crash on Linux due to improper webcam detection
(<a href="http://code.google.com/p/android/issues/detail?id=20952">Issue 20952</a>).</li>
<li>Fixed emulator issue when using the <code>-wipe-data</code> argument.</li>
- <li>Fixed build issue when using Renderscript in projects that target API levels 11-13
+ <li>Fixed build issue when using RenderScript in projects that target API levels 11-13
(<a href="http://code.google.com/p/android/issues/detail?id=21006">Issue 21006</a>).</li>
<li>Fixed issue when creating an AVD using the GoogleTV addon
(<a href="http://code.google.com/p/android/issues/detail?id=20963">Issue 20963</a>).</li>
diff --git a/docs/html/tools/support-library/features.jd b/docs/html/tools/support-library/features.jd
index 8d25d96..65148bf 100644
--- a/docs/html/tools/support-library/features.jd
+++ b/docs/html/tools/support-library/features.jd
@@ -15,6 +15,7 @@
<li><a href="#v7-mediarouter">v7 mediarouter library</a></li>
</ol>
</li>
+ <li><a href="#v8">v8 Support Library</a></li>
<li><a href="#v13">v13 Support Library</a></li>
</ol>
@@ -252,7 +253,7 @@
where "18.0.0" is the minimum revision at which the library is available. For example:</p>
<pre>
-com.android.support:support-v7-mediarouter:18.0.0
+com.android.support:mediarouter-v7:18.0.+
</pre>
<p class="caution">The v7 mediarouter library APIs introduced in Support Library
@@ -262,6 +263,24 @@
developer preview</a>. </p>
+<h2 id="v8">v8 Support Library</h2>
+
+<p>This library is designed to be used with Android (API level 8) and higher. It adds support for
+ the <a href="{@docRoot}guide/topics/renderscript/compute.html">RenderScript</a> computation
+ framework. These APIs are included in the {@link android.support.v8.renderscript} package. You
+ should be aware that the steps for including these APIs in your application is <em>very
+ different</em> from other support library APIs. For more information about using these APIs
+ in your application, see the
+ <a href="{@docRoot}guide/topics/renderscript/compute.html#access-rs-apis">RenderScript</a>
+ developer guide.</p>
+
+<p class="note">
+ <strong>Note:</strong> Use of RenderScript with the support library is supported with the Android
+ Eclipse plugin and Ant build tools. It is <em>not currently</em> supported with Android Studio or
+ Gradle-based builds.
+</p>
+
+
<h2 id="v13">v13 Support Library</h2>
<p>This library is designed to be used for Android 3.2 (API level 13) and higher. It adds support
diff --git a/docs/html/tools/support-library/index.jd b/docs/html/tools/support-library/index.jd
index 06c7a3f..4ee8c12 100644
--- a/docs/html/tools/support-library/index.jd
+++ b/docs/html/tools/support-library/index.jd
@@ -58,6 +58,7 @@
<p>This section provides details about the Support Library package releases.</p>
+
<div class="toggle-content opened">
<p><a href="#" onclick="return toggleContent(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img" alt=""
diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java
index 9f442f5..a346e17 100644
--- a/media/java/android/media/Image.java
+++ b/media/java/android/media/Image.java
@@ -16,20 +16,19 @@
package android.media;
-import android.graphics.ImageFormat;
import java.nio.ByteBuffer;
import java.lang.AutoCloseable;
/**
* <p>A single complete image buffer to use with a media source such as a
* {@link MediaCodec} or a
- * {@link android.hardware.camera2.CameraDevice}.</p>
+ * {@link android.hardware.camera2.CameraDevice CameraDevice}.</p>
*
* <p>This class allows for efficient direct application access to the pixel
* data of the Image through one or more
* {@link java.nio.ByteBuffer ByteBuffers}. Each buffer is encapsulated in a
* {@link Plane} that describes the layout of the pixel data in that plane. Due
- * to this direct access, and unlike the {@link android.graphics.Bitmap} class,
+ * to this direct access, and unlike the {@link android.graphics.Bitmap Bitmap} class,
* Images are not directly usable as as UI resources.</p>
*
* <p>Since Images are often directly produced or consumed by hardware
@@ -40,19 +39,28 @@
* from various media sources, not closing old Image objects will prevent the
* availability of new Images once
* {@link ImageReader#getMaxImages the maximum outstanding image count} is
- * reached.</p>
+ * reached. When this happens, the function acquiring new Images will typically
+ * throw an {@link IllegalStateException}.</p>
*
* @see ImageReader
*/
-public interface Image extends AutoCloseable {
+public abstract class Image implements AutoCloseable {
+ /**
+ * @hide
+ */
+ protected Image() {
+ }
+
/**
* Get the format for this image. This format determines the number of
* ByteBuffers needed to represent the image, and the general layout of the
* pixel data in each in ByteBuffer.
*
+ * <p>
* The format is one of the values from
- * {@link android.graphics.ImageFormat}. The mapping between the formats and
- * the planes is as follows:
+ * {@link android.graphics.ImageFormat ImageFormat}. The mapping between the
+ * formats and the planes is as follows:
+ * </p>
*
* <table>
* <tr>
@@ -61,13 +69,14 @@
* <th>Layout details</th>
* </tr>
* <tr>
- * <td>{@link android.graphics.ImageFormat#JPEG}</td>
+ * <td>{@link android.graphics.ImageFormat#JPEG JPEG}</td>
* <td>1</td>
* <td>Compressed data, so row and pixel strides are 0. To uncompress, use
- * {@link android.graphics.BitmapFactory#decodeByteArray}.</td>
+ * {@link android.graphics.BitmapFactory#decodeByteArray BitmapFactory#decodeByteArray}.
+ * </td>
* </tr>
* <tr>
- * <td>{@link android.graphics.ImageFormat#YUV_420_888}</td>
+ * <td>{@link android.graphics.ImageFormat#YUV_420_888 YUV_420_888}</td>
* <td>3</td>
* <td>A luminance plane followed by the Cb and Cr chroma planes.
* The chroma planes have half the width and height of the luminance
@@ -75,53 +84,60 @@
* Each plane has its own row stride and pixel stride.</td>
* </tr>
* <tr>
- * <td>{@link android.graphics.ImageFormat#RAW_SENSOR}</td>
+ * <td>{@link android.graphics.ImageFormat#RAW_SENSOR RAW_SENSOR}</td>
* <td>1</td>
* <td>A single plane of raw sensor image data, with 16 bits per color
* sample. The details of the layout need to be queried from the source of
* the raw sensor data, such as
- * {@link android.hardware.camera2.CameraDevice}.
+ * {@link android.hardware.camera2.CameraDevice CameraDevice}.
* </td>
* </tr>
* </table>
*
* @see android.graphics.ImageFormat
*/
- public int getFormat();
+ public abstract int getFormat();
/**
* The width of the image in pixels. For formats where some color channels
* are subsampled, this is the width of the largest-resolution plane.
*/
- public int getWidth();
+ public abstract int getWidth();
/**
* The height of the image in pixels. For formats where some color channels
* are subsampled, this is the height of the largest-resolution plane.
*/
- public int getHeight();
+ public abstract int getHeight();
/**
- * Get the timestamp associated with this frame. The timestamp is measured
- * in nanoseconds, and is monotonically increasing. However, the zero point
- * and whether the timestamp can be compared against other sources of time
- * or images depend on the source of this image.
+ * Get the timestamp associated with this frame.
+ * <p>
+ * The timestamp is measured in nanoseconds, and is monotonically
+ * increasing. However, the zero point and whether the timestamp can be
+ * compared against other sources of time or images depend on the source of
+ * this image.
+ * </p>
*/
- public long getTimestamp();
+ public abstract long getTimestamp();
/**
* Get the array of pixel planes for this Image. The number of planes is
* determined by the format of the Image.
*/
- public Plane[] getPlanes();
+ public abstract Plane[] getPlanes();
/**
- * Free up this frame for reuse. After calling this method, calling any
- * methods on this Image will result in an IllegalStateException, and
- * attempting to read from ByteBuffers returned by an earlier
- * {@code Plane#getBuffer} call will have undefined behavior.
+ * Free up this frame for reuse.
+ * <p>
+ * After calling this method, calling any methods on this {@code Image} will
+ * result in an {@link IllegalStateException}, and attempting to read from
+ * {@link ByteBuffer ByteBuffers} returned by an earlier
+ * {@link Plane#getBuffer} call will have undefined behavior.
+ * </p>
*/
- public void close();
+ @Override
+ public abstract void close();
/**
* <p>A single color plane of image data.</p>
@@ -134,29 +150,41 @@
*
* @see #getFormat
*/
- public interface Plane {
+ public static abstract class Plane {
/**
- * <p>The row stride for this color plane, in bytes.
+ * @hide
+ */
+ protected Plane() {
+ }
+
+ /**
+ * <p>The row stride for this color plane, in bytes.</p>
*
* <p>This is the distance between the start of two consecutive rows of
- * pixels in the image.</p>
+ * pixels in the image. The row stride is always greater than 0.</p>
*/
- public int getRowStride();
+ public abstract int getRowStride();
/**
* <p>The distance between adjacent pixel samples, in bytes.</p>
*
* <p>This is the distance between two consecutive pixel values in a row
* of pixels. It may be larger than the size of a single pixel to
- * account for interleaved image data or padded formats.</p>
+ * account for interleaved image data or padded formats.
+ * The pixel stride is always greater than 0.</p>
*/
- public int getPixelStride();
+ public abstract int getPixelStride();
/**
- * <p>Get a set of direct {@link java.nio.ByteBuffer byte buffers}
+ * <p>Get a direct {@link java.nio.ByteBuffer ByteBuffer}
* containing the frame data.</p>
*
+ * <p>In particular, the buffer returned will always have
+ * {@link java.nio.ByteBuffer#isDirect isDirect} return {@code true}, so
+ * the underlying data could be mapped as a pointer in JNI without doing
+ * any copies with {@code GetDirectBufferAddress}.</p>
+ *
* @return the byte buffer containing the image data for this plane.
*/
- public ByteBuffer getBuffer();
+ public abstract ByteBuffer getBuffer();
}
}
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index b14a899..aee8362 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -40,41 +40,67 @@
* <p>The image data is encapsulated in {@link Image} objects, and multiple such
* objects can be accessed at the same time, up to the number specified by the
* {@code maxImages} constructor parameter. New images sent to an ImageReader
- * through its Surface are queued until accessed through the
- * {@link #getNextImage} call. Due to memory limits, an image source will
+ * through its {@link Surface} are queued until accessed through the {@link #acquireLatestImage}
+ * or {@link #acquireNextImage} call. Due to memory limits, an image source will
* eventually stall or drop Images in trying to render to the Surface if the
* ImageReader does not obtain and release Images at a rate equal to the
* production rate.</p>
*/
-public final class ImageReader implements AutoCloseable {
+public class ImageReader implements AutoCloseable {
+
+ /**
+ * Returned by nativeImageSetup when acquiring the image was successful.
+ */
+ private static final int ACQUIRE_SUCCESS = 0;
+ /**
+ * Returned by nativeImageSetup when we couldn't acquire the buffer,
+ * because there were no buffers available to acquire.
+ */
+ private static final int ACQUIRE_NO_BUFS = 1;
+ /**
+ * Returned by nativeImageSetup when we couldn't acquire the buffer
+ * because the consumer has already acquired {@maxImages} and cannot
+ * acquire more than that.
+ */
+ private static final int ACQUIRE_MAX_IMAGES = 2;
/**
* <p>Create a new reader for images of the desired size and format.</p>
*
- * <p>The maxImages parameter determines the maximum number of {@link Image}
- * objects that can be be acquired from the ImageReader
+ * <p>The {@code maxImages} parameter determines the maximum number of {@link Image}
+ * objects that can be be acquired from the {@code ImageReader}
* simultaneously. Requesting more buffers will use up more memory, so it is
* important to use only the minimum number necessary for the use case.</p>
*
* <p>The valid sizes and formats depend on the source of the image
* data.</p>
*
- * @param width the width in pixels of the Images that this reader will
- * produce.
- * @param height the height in pixels of the Images that this reader will
- * produce.
- * @param format the format of the Image that this reader will produce. This
- * must be one of the {@link android.graphics.ImageFormat} or
- * {@link android.graphics.PixelFormat} constants.
- * @param maxImages the maximum number of images the user will want to
- * access simultaneously. This should be as small as possible to limit
- * memory use. Once maxImages Images are obtained by the user, one of them
- * has to be released before a new Image will become available for access
- * through getNextImage(). Must be greater than 0.
+ * @param width
+ * The width in pixels of the Images that this reader will produce.
+ * @param height
+ * The height in pixels of the Images that this reader will produce.
+ * @param format
+ * The format of the Image that this reader will produce. This
+ * must be one of the {@link android.graphics.ImageFormat} or
+ * {@link android.graphics.PixelFormat} constants.
+ * @param maxImages
+ * The maximum number of images the user will want to
+ * access simultaneously. This should be as small as possible to limit
+ * memory use. Once maxImages Images are obtained by the user, one of them
+ * has to be released before a new Image will become available for access
+ * through {@link #acquireLatestImage()} or {@link #acquireNextImage()}.
+ * Must be greater than 0.
*
* @see Image
*/
- public ImageReader(int width, int height, int format, int maxImages) {
+ public static ImageReader newInstance(int width, int height, int format, int maxImages) {
+ return new ImageReader(width, height, format, maxImages);
+ }
+
+ /**
+ * @hide
+ */
+ protected ImageReader(int width, int height, int format, int maxImages) {
mWidth = width;
mHeight = height;
mFormat = format;
@@ -96,33 +122,79 @@
mSurface = nativeGetSurface();
}
+ /**
+ * The width of each {@link Image}, in pixels.
+ *
+ * <p>ImageReader guarantees that all Images acquired from ImageReader (for example, with
+ * {@link #acquireNextImage}) will have the same dimensions as specified in
+ * {@link #newInstance}.</p>
+ *
+ * @return the width of an Image
+ */
public int getWidth() {
return mWidth;
}
+ /**
+ * The height of each {@link Image}, in pixels.
+ *
+ * <p>ImageReader guarantees that all Images acquired from ImageReader (for example, with
+ * {@link #acquireNextImage}) will have the same dimensions as specified in
+ * {@link #newInstance}.</p>
+ *
+ * @return the height of an Image
+ */
public int getHeight() {
return mHeight;
}
+ /**
+ * The {@link ImageFormat image format} of each Image.
+ *
+ * <p>ImageReader guarantees that all {@link Image Images} acquired from ImageReader
+ * (for example, with {@link #acquireNextImage}) will have the same format as specified in
+ * {@link #newInstance}.</p>
+ *
+ * @return the format of an Image
+ *
+ * @see ImageFormat
+ */
public int getImageFormat() {
return mFormat;
}
+ /**
+ * Maximum number of images that can be acquired from the ImageReader by any time (for example,
+ * with {@link #acquireNextImage}).
+ *
+ * <p>An image is considered acquired after it's returned by a function from ImageReader, and
+ * until the Image is {@link Image#close closed} to release the image back to the ImageReader.
+ * </p>
+ *
+ * <p>Attempting to acquire more than {@code maxImages} concurrently will result in the
+ * acquire function throwing a {@link IllegalStateException}. Furthermore,
+ * while the max number of images have been acquired by the ImageReader user, the producer
+ * enqueueing additional images may stall until at least one image has been released. </p>
+ *
+ * @return Maximum number of images for this ImageReader.
+ *
+ * @see Image#close
+ */
public int getMaxImages() {
return mMaxImages;
}
/**
- * <p>Get a Surface that can be used to produce Images for this
- * ImageReader.</p>
+ * <p>Get a {@link Surface} that can be used to produce {@link Image Images} for this
+ * {@code ImageReader}.</p>
*
- * <p>Until valid image data is rendered into this Surface, the
- * {@link #getNextImage} method will return {@code null}. Only one source
+ * <p>Until valid image data is rendered into this {@link Surface}, the
+ * {@link #acquireNextImage} method will return {@code null}. Only one source
* can be producing data into this Surface at the same time, although the
- * same Surface can be reused with a different API once the first source is
- * disconnected from the Surface.</p>
+ * same {@link Surface} can be reused with a different API once the first source is
+ * disconnected from the {@link Surface}.</p>
*
- * @return A Surface to use for a drawing target for various APIs.
+ * @return A {@link Surface} to use for a drawing target for various APIs.
*/
public Surface getSurface() {
return mSurface;
@@ -130,41 +202,154 @@
/**
* <p>
- * Get the next Image from the ImageReader's queue. Returns {@code null} if
- * no new image is available.
+ * Acquire the latest {@link Image} from the ImageReader's queue, dropping older
+ * {@link Image images}. Returns {@code null} if no new image is available.
* </p>
* <p>
- * This operation will fail by throwing an
- * {@link Surface.OutOfResourcesException OutOfResourcesException} if too
- * many images have been acquired with {@link #getNextImage}. In particular
- * a sequence of {@link #getNextImage} calls greater than {@link #getMaxImages}
- * without calling {@link Image#close} or {@link #releaseImage} in-between
- * will exhaust the underlying queue. At such a time,
- * {@link Surface.OutOfResourcesException OutOfResourcesException} will be
- * thrown until more images are released with {@link Image#close} or
- * {@link #releaseImage}.
+ * This operation will acquire all the images possible from the ImageReader,
+ * but {@link #close} all images that aren't the latest. This function is
+ * recommended to use over {@link #acquireNextImage} for most use-cases, as it's
+ * more suited for real-time processing.
+ * </p>
+ * <p>
+ * Note that {@link #getMaxImages maxImages} should be at least 2 for
+ * {@link #acquireLatestImage} to be any different than {@link #acquireNextImage} -
+ * discarding all-but-the-newest {@link Image} requires temporarily acquiring two
+ * {@link Image Images} at once. Or more generally, calling {@link #acquireLatestImage}
+ * with less than two images of margin, that is
+ * {@code (maxImages - currentAcquiredImages < 2)} will not discard as expected.
+ * </p>
+ * <p>
+ * This operation will fail by throwing an {@link IllegalStateException} if
+ * {@code maxImages} have been acquired with {@link #acquireLatestImage} or
+ * {@link #acquireNextImage}. In particular a sequence of {@link #acquireLatestImage}
+ * calls greater than {@link #getMaxImages} without calling {@link Image#close} in-between
+ * will exhaust the underlying queue. At such a time, {@link IllegalStateException}
+ * will be thrown until more images are
+ * released with {@link Image#close}.
* </p>
*
- * @return a new frame of image data, or {@code null} if no image data is
- * available.
- * @throws Surface.OutOfResourcesException if too many images are currently
- * acquired
+ * @return latest frame of image data, or {@code null} if no image data is available.
+ * @throws IllegalStateException if too many images are currently acquired
*/
- public Image getNextImage() {
- SurfaceImage si = new SurfaceImage();
- if (nativeImageSetup(si)) {
- // create SurfacePlane objects
- si.createSurfacePlanes();
- si.setImageValid(true);
- return si;
+ public Image acquireLatestImage() {
+ Image image = acquireNextImage();
+ if (image == null) {
+ return null;
}
- return null;
+ try {
+ for (;;) {
+ Image next = acquireNextImageNoThrowISE();
+ if (next == null) {
+ Image result = image;
+ image = null;
+ return result;
+ }
+ image.close();
+ image = next;
+ }
+ } finally {
+ if (image != null) {
+ image.close();
+ }
+ }
+ }
+
+ /**
+ * Don't throw IllegalStateException if there are too many images acquired.
+ *
+ * @return Image if acquiring succeeded, or null otherwise.
+ *
+ * @hide
+ */
+ public Image acquireNextImageNoThrowISE() {
+ SurfaceImage si = new SurfaceImage();
+ return acquireNextSurfaceImage(si) == ACQUIRE_SUCCESS ? si : null;
+ }
+
+ /**
+ * Attempts to acquire the next image from the underlying native implementation.
+ *
+ * <p>
+ * Note that unexpected failures will throw at the JNI level.
+ * </p>
+ *
+ * @param si A blank SurfaceImage.
+ * @return One of the {@code ACQUIRE_*} codes that determine success or failure.
+ *
+ * @see #ACQUIRE_MAX_IMAGES
+ * @see #ACQUIRE_NO_BUFS
+ * @see #ACQUIRE_SUCCESS
+ */
+ private int acquireNextSurfaceImage(SurfaceImage si) {
+
+ int status = nativeImageSetup(si);
+
+ switch (status) {
+ case ACQUIRE_SUCCESS:
+ si.createSurfacePlanes();
+ si.setImageValid(true);
+ case ACQUIRE_NO_BUFS:
+ case ACQUIRE_MAX_IMAGES:
+ break;
+ default:
+ throw new AssertionError("Unknown nativeImageSetup return code " + status);
+ }
+
+ return status;
+ }
+
+ /**
+ * <p>
+ * Acquire the next Image from the ImageReader's queue. Returns {@code null} if
+ * no new image is available.
+ * </p>
+ *
+ * <p><i>Warning:</i> Consider using {@link #acquireLatestImage()} instead, as it will
+ * automatically release older images, and allow slower-running processing routines to catch
+ * up to the newest frame. Usage of {@link #acquireNextImage} is recommended for
+ * batch/background processing. Incorrectly using this function can cause images to appear
+ * with an ever-increasing delay, followed by a complete stall where no new images seem to
+ * appear.
+ * </p>
+ *
+ * <p>
+ * This operation will fail by throwing an {@link IllegalStateException} if
+ * {@code maxImages} have been acquired with {@link #acquireNextImage} or
+ * {@link #acquireLatestImage}. In particular a sequence of {@link #acquireNextImage} or
+ * {@link #acquireLatestImage} calls greater than {@link #getMaxImages maxImages} without
+ * calling {@link Image#close} in-between will exhaust the underlying queue. At such a time,
+ * {@link IllegalStateException} will be thrown until more images are released with
+ * {@link Image#close}.
+ * </p>
+ *
+ * @return a new frame of image data, or {@code null} if no image data is available.
+ * @throws IllegalStateException if {@code maxImages} images are currently acquired
+ * @see #acquireLatestImage
+ */
+ public Image acquireNextImage() {
+ SurfaceImage si = new SurfaceImage();
+ int status = acquireNextSurfaceImage(si);
+
+ switch (status) {
+ case ACQUIRE_SUCCESS:
+ return si;
+ case ACQUIRE_NO_BUFS:
+ return null;
+ case ACQUIRE_MAX_IMAGES:
+ throw new IllegalStateException(
+ String.format(
+ "maxImages (%d) has already been acquired, " +
+ "call #close before acquiring more.", mMaxImages));
+ default:
+ throw new AssertionError("Unknown nativeImageSetup return code " + status);
+ }
}
/**
* <p>Return the frame to the ImageReader for reuse.</p>
*/
- public void releaseImage(Image i) {
+ private void releaseImage(Image i) {
if (! (i instanceof SurfaceImage) ) {
throw new IllegalArgumentException(
"This image was not produced by an ImageReader");
@@ -183,13 +368,16 @@
/**
* Register a listener to be invoked when a new image becomes available
* from the ImageReader.
- * @param listener the listener that will be run
- * @param handler The handler on which the listener should be invoked, or null
- * if the listener should be invoked on the calling thread's looper.
*
- * @throws IllegalArgumentException if no handler specified and the calling thread has no looper
+ * @param listener
+ * The listener that will be run.
+ * @param handler
+ * The handler on which the listener should be invoked, or null
+ * if the listener should be invoked on the calling thread's looper.
+ * @throws IllegalArgumentException
+ * If no handler specified and the calling thread has no looper.
*/
- public void setImageAvailableListener(OnImageAvailableListener listener, Handler handler) {
+ public void setOnImageAvailableListener(OnImageAvailableListener listener, Handler handler) {
mImageListener = listener;
Looper looper;
@@ -206,12 +394,16 @@
/**
* Callback interface for being notified that a new image is available.
+ *
+ * <p>
* The onImageAvailable is called per image basis, that is, callback fires for every new frame
* available from ImageReader.
+ * </p>
*/
public interface OnImageAvailableListener {
/**
* Callback that is called when a new image is available from ImageReader.
+ *
* @param reader the ImageReader the callback is associated with.
* @see ImageReader
* @see Image
@@ -220,12 +412,17 @@
}
/**
- * Free up all the resources associated with this ImageReader. After
- * Calling this method, this ImageReader can not be used. calling
- * any methods on this ImageReader and Images previously provided by {@link #getNextImage}
- * will result in an IllegalStateException, and attempting to read from
- * ByteBuffers returned by an earlier {@code Plane#getBuffer} call will
+ * Free up all the resources associated with this ImageReader.
+ *
+ * <p>
+ * After calling this method, this ImageReader can not be used. Calling
+ * any methods on this ImageReader and Images previously provided by
+ * {@link #acquireNextImage} or {@link #acquireLatestImage}
+ * will result in an {@link IllegalStateException}, and attempting to read from
+ * {@link ByteBuffer ByteBuffers} returned by an earlier
+ * {@link Image.Plane#getBuffer Plane#getBuffer} call will
* have undefined behavior.
+ * </p>
*/
@Override
public void close() {
@@ -242,11 +439,14 @@
}
/**
- * Only a subset of the formats defined in {@link android.graphics.ImageFormat} and
- * {@link android.graphics.PixelFormat} are supported by ImageReader. When reading RGB
- * data from a surface, the formats defined in {@link android.graphics.PixelFormat}
- * can be used, when reading YUV, JPEG or raw sensor data ( for example, from camera
- * or video decoder), formats from {@link android.graphics.ImageFormat} are used.
+ * Only a subset of the formats defined in
+ * {@link android.graphics.ImageFormat ImageFormat} and
+ * {@link android.graphics.PixelFormat PixelFormat} are supported by
+ * ImageReader. When reading RGB data from a surface, the formats defined in
+ * {@link android.graphics.PixelFormat PixelFormat} can be used, when
+ * reading YUV, JPEG or raw sensor data (for example, from camera or video
+ * decoder), formats from {@link android.graphics.ImageFormat ImageFormat}
+ * are used.
*/
private int getNumPlanesFromFormat() {
switch (mFormat) {
@@ -308,7 +508,7 @@
*/
private long mNativeContext;
- private class SurfaceImage implements android.media.Image {
+ private class SurfaceImage extends android.media.Image {
public SurfaceImage() {
mIsImageValid = false;
}
@@ -404,7 +604,7 @@
mPlanes[i] = nativeCreatePlane(i);
}
}
- private class SurfacePlane implements android.media.Image.Plane {
+ private class SurfacePlane extends android.media.Image.Plane {
// SurfacePlane instance is created by native code when a new SurfaceImage is created
private SurfacePlane(int index, int rowStride, int pixelStride) {
mIndex = index;
@@ -479,9 +679,17 @@
private synchronized native void nativeClose();
private synchronized native void nativeReleaseImage(Image i);
private synchronized native Surface nativeGetSurface();
- private synchronized native boolean nativeImageSetup(Image i);
- /*
+ /**
+ * @return A return code {@code ACQUIRE_*}
+ *
+ * @see #ACQUIRE_SUCCESS
+ * @see #ACQUIRE_NO_BUFS
+ * @see #ACQUIRE_MAX_IMAGES
+ */
+ private synchronized native int nativeImageSetup(Image i);
+
+ /**
* We use a class initializer to allow the native code to cache some
* field offsets.
*/
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index 94f20bc..fb0f69b 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -43,13 +43,16 @@
using namespace android;
-static const char* const OutOfResourcesException =
- "android/view/Surface$OutOfResourcesException";
-
enum {
IMAGE_READER_MAX_NUM_PLANES = 3,
};
+enum {
+ ACQUIRE_SUCCESS = 0,
+ ACQUIRE_NO_BUFFERS = 1,
+ ACQUIRE_MAX_IMAGES = 2,
+};
+
static struct {
jfieldID mNativeContext;
jmethodID postEventFromNative;
@@ -685,14 +688,14 @@
ctx->returnLockedBuffer(buffer);
}
-static jboolean ImageReader_imageSetup(JNIEnv* env, jobject thiz,
+static jint ImageReader_imageSetup(JNIEnv* env, jobject thiz,
jobject image)
{
ALOGV("%s:", __FUNCTION__);
JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz);
if (ctx == NULL) {
jniThrowRuntimeException(env, "ImageReaderContext is not initialized");
- return false;
+ return -1;
}
CpuConsumer* consumer = ctx->getCpuConsumer();
@@ -700,27 +703,22 @@
if (buffer == NULL) {
ALOGW("Unable to acquire a lockedBuffer, very likely client tries to lock more than"
" maxImages buffers");
- jniThrowException(env, OutOfResourcesException,
- "Too many outstanding images, close existing images"
- " to be able to acquire more.");
- return false;
+ return ACQUIRE_MAX_IMAGES;
}
status_t res = consumer->lockNextBuffer(buffer);
if (res != NO_ERROR) {
if (res != BAD_VALUE /*no buffers*/) {
if (res == NOT_ENOUGH_DATA) {
- jniThrowException(env, OutOfResourcesException,
- "Too many outstanding images, close existing images"
- " to be able to acquire more.");
+ return ACQUIRE_MAX_IMAGES;
} else {
ALOGE("%s Fail to lockNextBuffer with error: %d ",
__FUNCTION__, res);
- jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
+ jniThrowExceptionFmt(env, "java/lang/AssertionError",
"Unknown error (%d) when we tried to lock buffer.",
res);
}
}
- return false;
+ return ACQUIRE_NO_BUFFERS;
}
// Check if the left-top corner of the crop rect is origin, we currently assume this point is
@@ -730,7 +728,7 @@
ALOGE("crop left: %d, top = %d", lt.x, lt.y);
jniThrowException(env, "java/lang/UnsupportedOperationException",
"crop left top corner need to at origin");
- return false;
+ return -1;
}
// Check if the producer buffer configurations match what ImageReader configured.
@@ -739,11 +737,9 @@
int outputHeight = buffer->height;
// Correct width/height when crop is set.
- if (buffer->crop.getWidth() > 0) {
- outputWidth = buffer->crop.getWidth() + 1;
- }
- if (buffer->crop.getHeight() > 0) {
- outputHeight = buffer->crop.getHeight() + 1;
+ if (buffer->crop.isValid()) {
+ outputWidth = buffer->crop.getWidth();
+ outputHeight = buffer->crop.getHeight();
}
int imageReaderWidth = ctx->getBufferWidth();
@@ -761,6 +757,7 @@
jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
"Producer buffer size: %dx%d, doesn't match ImageReader configured size: %dx%d",
outputWidth, outputHeight, imageReaderWidth, imageReaderHeight);
+ return -1;
}
if (ctx->getBufferFormat() != buffer->format) {
@@ -777,14 +774,14 @@
buffer->format, ctx->getBufferFormat());
jniThrowException(env, "java/lang/UnsupportedOperationException",
msg.string());
- return false;
+ return -1;
}
// Set SurfaceImage instance member variables
Image_setBuffer(env, image, buffer);
env->SetLongField(image, gSurfaceImageClassInfo.mTimestamp,
static_cast<jlong>(buffer->timestamp));
- return true;
+ return ACQUIRE_SUCCESS;
}
static jobject ImageReader_getSurface(JNIEnv* env, jobject thiz)
@@ -855,7 +852,7 @@
{"nativeInit", "(Ljava/lang/Object;IIII)V", (void*)ImageReader_init },
{"nativeClose", "()V", (void*)ImageReader_close },
{"nativeReleaseImage", "(Landroid/media/Image;)V", (void*)ImageReader_imageRelease },
- {"nativeImageSetup", "(Landroid/media/Image;)Z", (void*)ImageReader_imageSetup },
+ {"nativeImageSetup", "(Landroid/media/Image;)I", (void*)ImageReader_imageSetup },
{"nativeGetSurface", "()Landroid/view/Surface;", (void*)ImageReader_getSurface },
};
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkUnitTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkUnitTestRunner.java
index ecdc287..64b12b7 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkUnitTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkUnitTestRunner.java
@@ -49,6 +49,7 @@
addMediaPlayerStateUnitTests(suite);
addMediaScannerUnitTests(suite);
addCameraUnitTests(suite);
+ addImageReaderTests(suite);
return suite;
}
@@ -65,6 +66,10 @@
suite.addTestSuite(CameraMetadataTest.class);
}
+ private void addImageReaderTests(TestSuite suite) {
+ suite.addTestSuite(ImageReaderTest.class);
+ }
+
// Running all unit tests checking the state machine may be time-consuming.
private void addMediaMetadataRetrieverStateUnitTests(TestSuite suite) {
suite.addTestSuite(MediaMetadataRetrieverTest.class);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
index 2d26ac7..7b2a20e 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
@@ -61,6 +61,7 @@
private SurfaceHolder mSurfaceHolder = null;
private static final int NUM_STRESS_LOOP = 10;
private static final int NUM_PLAYBACk_IN_EACH_LOOP = 20;
+ private static final int SHORT_WAIT = 2 * 1000; // 2 seconds
private static final long MEDIA_STRESS_WAIT_TIME = 5000; //5 seconds
private static final String MEDIA_MEMORY_OUTPUT =
"/sdcard/mediaMemOutput.txt";
@@ -99,16 +100,17 @@
@Override
protected void setUp() throws Exception {
super.setUp();
+ //Insert a 2 second before launching the test activity. This is
+ //the workaround for the race condition of requesting the updated surface.
+ Thread.sleep(SHORT_WAIT);
+ getActivity();
//Check if the device support the camcorder
- CamcorderProfile mCamcorderProfile = CamcorderProfile.get(CAMERA_ID);
+ mCamcorderProfile = CamcorderProfile.get(CAMERA_ID);
if (mCamcorderProfile != null) {
mVideoWidth = mCamcorderProfile.videoFrameWidth;
mVideoHeight = mCamcorderProfile.videoFrameHeight;
+ Log.v(TAG, "height = " + mVideoHeight + " width= " + mVideoWidth);
}
- //Insert a 2 second before launching the test activity. This is
- //the workaround for the race condition of requesting the updated surface.
- Thread.sleep(2000);
- getActivity();
if (MediaFrameworkPerfTestRunner.mGetNativeHeapDump)
MediaTestUtil.getNativeHeapDump(this.getName() + "_before");
@@ -246,6 +248,8 @@
Thread.sleep(MEDIA_STRESS_WAIT_TIME);
mRecorder.stop();
mRecorder.release();
+ //Insert 2 seconds to make sure the camera released.
+ Thread.sleep(SHORT_WAIT);
} catch (Exception e) {
Log.v("record video failed ", e.toString());
mRecorder.release();
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ImageReaderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ImageReaderTest.java
new file mode 100644
index 0000000..f6cd990
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ImageReaderTest.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2013 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.mediaframeworktest.unit;
+
+import static org.mockito.Mockito.*;
+
+import android.graphics.ImageFormat;
+import android.media.Image;
+import android.media.Image.Plane;
+import android.media.ImageReader;
+import android.media.ImageReader.OnImageAvailableListener;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+public class ImageReaderTest extends AndroidTestCase {
+
+ private static final String TAG = "ImageReaderTest-unit";
+
+ private static final int DEFAULT_WIDTH = 640;
+ private static final int DEFAULT_HEIGHT = 480;
+ private static final int DEFAULT_FORMAT = ImageFormat.YUV_420_888;
+ private static final int DEFAULT_MAX_IMAGES = 3;
+
+ private ImageReader mReader;
+ private Image mImage1;
+ private Image mImage2;
+ private Image mImage3;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ /**
+ * Workaround for mockito and JB-MR2 incompatibility
+ *
+ * Avoid java.lang.IllegalArgumentException: dexcache == null
+ * https://code.google.com/p/dexmaker/issues/detail?id=2
+ */
+ System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
+
+ // TODO: refactor above into one of the test runners
+
+ mReader = spy(ImageReader.newInstance(DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
+ DEFAULT_MAX_IMAGES));
+ mImage1 = mock(Image.class);
+ mImage2 = mock(Image.class);
+ mImage3 = mock(Image.class);
+
+ /**
+ * Ensure rest of classes are mockable
+ */
+ {
+ mock(Plane.class);
+ mock(OnImageAvailableListener.class);
+ }
+
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mReader.close();
+
+ super.tearDown();
+ }
+
+ /**
+ * Return null when there is nothing in the image queue.
+ */
+ @SmallTest
+ public void testGetLatestImageEmpty() {
+ when(mReader.acquireNextImage()).thenReturn(null);
+ when(mReader.acquireNextImageNoThrowISE()).thenReturn(null);
+ assertEquals(null, mReader.acquireLatestImage());
+ }
+
+ /**
+ * Return the last image from the image queue, close up the rest.
+ */
+ @SmallTest
+ public void testGetLatestImage1() {
+ when(mReader.acquireNextImage()).thenReturn(mImage1);
+ when(mReader.acquireNextImageNoThrowISE()).thenReturn(null);
+ assertEquals(mImage1, mReader.acquireLatestImage());
+ verify(mImage1, never()).close();
+ }
+
+ /**
+ * Return the last image from the image queue, close up the rest.
+ */
+ @SmallTest
+ public void testGetLatestImage2() {
+ when(mReader.acquireNextImage()).thenReturn(mImage1);
+ when(mReader.acquireNextImageNoThrowISE()).thenReturn(mImage2).thenReturn(null);
+ assertEquals(mImage2, mReader.acquireLatestImage());
+ verify(mImage1, atLeastOnce()).close();
+ verify(mImage2, never()).close();
+ }
+
+ /**
+ * Return the last image from the image queue, close up the rest.
+ */
+ @SmallTest
+ public void testGetLatestImage3() {
+ when(mReader.acquireNextImage()).thenReturn(mImage1);
+ when(mReader.acquireNextImageNoThrowISE()).thenReturn(mImage2).
+ thenReturn(mImage3).
+ thenReturn(null);
+ assertEquals(mImage3, mReader.acquireLatestImage());
+ verify(mImage1, atLeastOnce()).close();
+ verify(mImage2, atLeastOnce()).close();
+ verify(mImage3, never()).close();
+ }
+
+ /**
+ * Return null if get a IllegalStateException with no images in the queue.
+ */
+ @SmallTest
+ public void testGetLatestImageTooManyBuffersAcquiredEmpty() {
+ when(mReader.acquireNextImage()).thenThrow(new IllegalStateException());
+ try {
+ mReader.acquireLatestImage();
+ fail("Expected IllegalStateException to be thrown");
+ } catch(IllegalStateException e) {
+ }
+ }
+
+ /**
+ * All images are cleaned up when we get an unexpected Error.
+ */
+ @SmallTest
+ public void testGetLatestImageExceptionalError() {
+ when(mReader.acquireNextImage()).thenReturn(mImage1);
+ when(mReader.acquireNextImageNoThrowISE()).thenReturn(mImage2).
+ thenReturn(mImage3).
+ thenThrow(new OutOfMemoryError());
+ try {
+ mReader.acquireLatestImage();
+ fail("Impossible");
+ } catch(OutOfMemoryError e) {
+ }
+
+ verify(mImage1, atLeastOnce()).close();
+ verify(mImage2, atLeastOnce()).close();
+ verify(mImage3, atLeastOnce()).close();
+ }
+
+ /**
+ * All images are cleaned up when we get an unexpected RuntimeException.
+ */
+ @SmallTest
+ public void testGetLatestImageExceptionalRuntime() {
+
+ when(mReader.acquireNextImage()).thenReturn(mImage1);
+ when(mReader.acquireNextImageNoThrowISE()).thenReturn(mImage2).
+ thenReturn(mImage3).
+ thenThrow(new RuntimeException());
+ try {
+ mReader.acquireLatestImage();
+ fail("Impossible");
+ } catch(RuntimeException e) {
+ }
+
+ verify(mImage1, atLeastOnce()).close();
+ verify(mImage2, atLeastOnce()).close();
+ verify(mImage3, atLeastOnce()).close();
+ }
+}
diff --git a/media/tests/SoundPoolTest/AndroidManifest.xml b/media/tests/SoundPoolTest/AndroidManifest.xml
index 126276c..8a29052 100644
--- a/media/tests/SoundPoolTest/AndroidManifest.xml
+++ b/media/tests/SoundPoolTest/AndroidManifest.xml
@@ -8,4 +8,5 @@
</intent-filter>
</activity>
</application>
+ <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="8"/>
</manifest>
diff --git a/media/tests/SoundPoolTest/src/com/android/SoundPoolTest.java b/media/tests/SoundPoolTest/src/com/android/SoundPoolTest.java
index 33db2dd..cc3306c 100644
--- a/media/tests/SoundPoolTest/src/com/android/SoundPoolTest.java
+++ b/media/tests/SoundPoolTest/src/com/android/SoundPoolTest.java
@@ -143,7 +143,7 @@
if (DEBUG) Log.d(LOG_TAG, "Stop note " + id);
sleep(50);
}
- if (DEBUG) Log.d(LOG_TAG, "End scale test");
+ if (DEBUG) Log.d(LOG_TAG, "End sounds test");
return true;
}
@@ -165,7 +165,7 @@
if (DEBUG) Log.d(LOG_TAG, "Stop note " + id);
sleep(50);
}
- if (DEBUG) Log.d(LOG_TAG, "End sounds test");
+ if (DEBUG) Log.d(LOG_TAG, "End scale test");
return true;
}
@@ -189,6 +189,7 @@
if (DEBUG) Log.d(LOG_TAG, "Change rate " + mScale[step]);
}
mSoundPool.stop(id);
+ if (DEBUG) Log.d(LOG_TAG, "Stop note " + id);
if (DEBUG) Log.d(LOG_TAG, "End rate test");
return true;
}
@@ -205,34 +206,38 @@
Log.e(LOG_TAG, "Error occurred starting note");
return false;
}
- sleep(250);
+ sleep(1000);
// play a low priority sound
- int id = mSoundPool.play(mSounds[0], DEFAULT_VOLUME, DEFAULT_VOLUME,
+ int id = mSoundPool.play(mSounds[1], DEFAULT_VOLUME, DEFAULT_VOLUME,
LOW_PRIORITY, DEFAULT_LOOP, 1.0f);
- if (id > 0) {
+ if (id != 0) {
Log.e(LOG_TAG, "Normal > Low priority test failed");
result = false;
mSoundPool.stop(id);
} else {
- Log.e(LOG_TAG, "Normal > Low priority test passed");
+ sleep(1000);
+ Log.i(LOG_TAG, "Normal > Low priority test passed");
}
- sleep(250);
// play a high priority sound
- id = mSoundPool.play(mSounds[0], DEFAULT_VOLUME, DEFAULT_VOLUME,
+ id = mSoundPool.play(mSounds[2], DEFAULT_VOLUME, DEFAULT_VOLUME,
HIGH_PRIORITY, DEFAULT_LOOP, 1.0f);
if (id == 0) {
Log.e(LOG_TAG, "High > Normal priority test failed");
result = false;
} else {
- Log.e(LOG_TAG, "High > Normal priority test passed");
+ sleep(1000);
+ Log.i(LOG_TAG, "Stopping high priority");
+ mSoundPool.stop(id);
+ sleep(1000);
+ Log.i(LOG_TAG, "High > Normal priority test passed");
}
- sleep(250);
- mSoundPool.stop(id);
// stop normal note
+ Log.i(LOG_TAG, "Stopping normal priority");
mSoundPool.stop(normalId);
+ sleep(1000);
if (DEBUG) Log.d(LOG_TAG, "End priority test");
return result;
@@ -250,17 +255,21 @@
Log.e(LOG_TAG, "Error occurred starting note");
return false;
}
- sleep(250);
+ sleep(2500);
// pause and resume sound a few times
for (int count = 0; count < 5; count++) {
+ if (DEBUG) Log.d(LOG_TAG, "Pause note " + id);
mSoundPool.pause(id);
- sleep(250);
+ sleep(1000);
+ if (DEBUG) Log.d(LOG_TAG, "Resume note " + id);
mSoundPool.resume(id);
- sleep(250);
+ sleep(1000);
}
+ if (DEBUG) Log.d(LOG_TAG, "Stop note " + id);
mSoundPool.stop(id);
+ sleep(1000);
// play 5 sounds, forces one to be stolen
int ids[] = new int[5];
@@ -272,18 +281,21 @@
Log.e(LOG_TAG, "Error occurred starting note");
return false;
}
- sleep(250);
+ sleep(1000);
}
// pause and resume sound a few times
for (int count = 0; count < 5; count++) {
+ if (DEBUG) Log.d(LOG_TAG, "autoPause");
mSoundPool.autoPause();
- sleep(250);
+ sleep(1000);
+ if (DEBUG) Log.d(LOG_TAG, "autoResume");
mSoundPool.autoResume();
- sleep(250);
+ sleep(1000);
}
for (int i = 0; i < 5; i++) {
+ if (DEBUG) Log.d(LOG_TAG, "Stop note " + ids[i]);
mSoundPool.stop(ids[i]);
}
@@ -302,9 +314,9 @@
return false;
}
- // pan from left to right
+ // pan from right to left
for (int count = 0; count < 101; count++) {
- sleep(20);
+ sleep(50);
double radians = PI_OVER_2 * count / 100.0;
float leftVolume = (float) Math.sin(radians);
float rightVolume = (float) Math.cos(radians);
diff --git a/media/tests/audiotests/Android.mk b/media/tests/audiotests/Android.mk
new file mode 100644
index 0000000..69f0bb5
--- /dev/null
+++ b/media/tests/audiotests/Android.mk
@@ -0,0 +1,21 @@
+ifeq ($(TARGET_ARCH),arm)
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= shared_mem_test
+LOCAL_SRC_FILES := \
+ shared_mem_test.cpp
+LOCAL_SHARED_LIBRARIES := \
+ libc \
+ libcutils \
+ libutils \
+ libbinder \
+ libhardware_legacy \
+ libmedia
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
+
+endif
diff --git a/media/tests/audiotests/shared_mem_test.cpp b/media/tests/audiotests/shared_mem_test.cpp
new file mode 100644
index 0000000..992c900
--- /dev/null
+++ b/media/tests/audiotests/shared_mem_test.cpp
@@ -0,0 +1,216 @@
+// 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.
+
+//
+#define LOG_NDEBUG 0
+#define LOG_TAG "shared_mem_test"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/properties.h>
+#include <media/AudioSystem.h>
+#include <media/AudioTrack.h>
+#include <math.h>
+
+#include "shared_mem_test.h"
+#include <binder/MemoryDealer.h>
+#include <binder/MemoryHeapBase.h>
+#include <binder/MemoryBase.h>
+#include <binder/ProcessState.h>
+
+
+#include <utils/Log.h>
+
+#include <fcntl.h>
+
+namespace android {
+
+/************************************************************
+*
+* Constructor
+*
+************************************************************/
+AudioTrackTest::AudioTrackTest(void) {
+
+ InitSine(); // init sine table
+
+}
+
+
+/************************************************************
+*
+*
+************************************************************/
+void AudioTrackTest::Execute(void) {
+ if (Test01() == 0) {
+ ALOGD("01 passed\n");
+ } else {
+ ALOGD("01 failed\n");
+ }
+}
+
+/************************************************************
+*
+* Shared memory test
+*
+************************************************************/
+#define BUF_SZ 44100
+
+int AudioTrackTest::Test01() {
+
+ sp<MemoryDealer> heap;
+ sp<IMemory> iMem;
+ uint8_t* p;
+
+ short smpBuf[BUF_SZ];
+ long rate = 44100;
+ unsigned long phi;
+ unsigned long dPhi;
+ long amplitude;
+ long freq = 1237;
+ float f0;
+
+ f0 = pow(2., 32.) * freq / (float)rate;
+ dPhi = (unsigned long)f0;
+ amplitude = 1000;
+ phi = 0;
+ Generate(smpBuf, BUF_SZ, amplitude, phi, dPhi); // fill buffer
+
+ for (int i = 0; i < 1024; i++) {
+ heap = new MemoryDealer(1024*1024, "AudioTrack Heap Base");
+
+ iMem = heap->allocate(BUF_SZ*sizeof(short));
+
+ p = static_cast<uint8_t*>(iMem->pointer());
+ memcpy(p, smpBuf, BUF_SZ*sizeof(short));
+
+ sp<AudioTrack> track = new AudioTrack(AUDIO_STREAM_MUSIC,// stream type
+ rate,
+ AUDIO_FORMAT_PCM_16_BIT,// word length, PCM
+ AUDIO_CHANNEL_OUT_MONO,
+ iMem);
+
+ status_t status = track->initCheck();
+ if(status != NO_ERROR) {
+ track.clear();
+ ALOGD("Failed for initCheck()");
+ return -1;
+ }
+
+ // start play
+ ALOGD("start");
+ track->start();
+
+ usleep(20000);
+
+ ALOGD("stop");
+ track->stop();
+ iMem.clear();
+ heap.clear();
+ usleep(20000);
+ }
+
+ return 0;
+
+}
+
+/************************************************************
+*
+* Generate a mono buffer
+* Error is less than 3lsb
+*
+************************************************************/
+void AudioTrackTest::Generate(short *buffer, long bufferSz, long amplitude, unsigned long &phi, long dPhi)
+{
+ long pi13 = 25736; // 2^13*pi
+ // fill buffer
+ for(int i0=0; i0<bufferSz; i0++) {
+ long sample;
+ long l0, l1;
+
+ buffer[i0] = ComputeSine( amplitude, phi);
+ phi += dPhi;
+ }
+}
+
+/************************************************************
+*
+* Generate a sine
+* Error is less than 3lsb
+*
+************************************************************/
+short AudioTrackTest::ComputeSine(long amplitude, long phi)
+{
+ long pi13 = 25736; // 2^13*pi
+ long sample;
+ long l0, l1;
+
+ sample = (amplitude*sin1024[(phi>>22) & 0x3ff]) >> 15;
+ // correct with interpolation
+ l0 = (phi>>12) & 0x3ff; // 2^20 * x / (2*pi)
+ l1 = (amplitude*sin1024[((phi>>22) + 256) & 0x3ff]) >> 15; // 2^15*cosine
+ l0 = (l0 * l1) >> 10;
+ l0 = (l0 * pi13) >> 22;
+ sample = sample + l0;
+
+ return (short)sample;
+}
+
+
+/************************************************************
+*
+* init sine table
+*
+************************************************************/
+void AudioTrackTest::InitSine(void) {
+ double phi = 0;
+ double dPhi = 2 * M_PI / SIN_SZ;
+ for(int i0 = 0; i0<SIN_SZ; i0++) {
+ long d0;
+
+ d0 = 32768. * sin(phi);
+ phi += dPhi;
+ if(d0 >= 32767) d0 = 32767;
+ if(d0 <= -32768) d0 = -32768;
+ sin1024[i0] = (short)d0;
+ }
+}
+
+/************************************************************
+*
+* main in name space
+*
+************************************************************/
+int main() {
+ ProcessState::self()->startThreadPool();
+ AudioTrackTest *test;
+
+ test = new AudioTrackTest();
+ test->Execute();
+ delete test;
+
+ return 0;
+}
+
+}
+
+/************************************************************
+*
+* global main
+*
+************************************************************/
+int main(int argc, char *argv[]) {
+
+ return android::main();
+}
diff --git a/media/tests/audiotests/shared_mem_test.h b/media/tests/audiotests/shared_mem_test.h
new file mode 100644
index 0000000..f495955
--- /dev/null
+++ b/media/tests/audiotests/shared_mem_test.h
@@ -0,0 +1,27 @@
+// Copyright 2008 The Android Open Source Project
+
+#ifndef AUDIOTRACKTEST_H_
+#define AUDIOTRACKTEST_H_
+
+namespace android {
+
+class AudioTrackTest{
+ public:
+ AudioTrackTest(void);
+ ~AudioTrackTest() {};
+
+ void Execute(void);
+ int Test01();
+
+ void Generate(short *buffer, long bufferSz, long amplitude, unsigned long &phi, long dPhi);
+ void InitSine();
+ short ComputeSine(long amplitude, long phi);
+
+ #define SIN_SZ 1024
+ short sin1024[SIN_SZ]; // sine table 2*pi = 1024
+};
+
+};
+
+
+#endif /*AUDIOTRACKTEST_H_*/
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 5e198a2..fa5c769 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -189,6 +189,35 @@
android:taskAffinity="com.android.systemui.net"
android:excludeFromRecents="true" />
+ <!-- platform logo easter egg activity -->
+ <activity
+ android:name=".DessertCase"
+ android:exported="true"
+ android:label="@string/dessert_case"
+ android:theme="@android:style/Theme.Wallpaper.NoTitleBar.Fullscreen"
+ android:hardwareAccelerated="true"
+ android:launchMode="singleInstance"
+ android:excludeFromRecents="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="com.android.internal.category.PLATLOGO" />
+ </intent-filter>
+ </activity>
+
+ <!-- a gallery of delicious treats -->
+ <service
+ android:name=".DessertCaseDream"
+ android:exported="true"
+ android:label="@string/dessert_case"
+ android:enabled="false"
+ >
+ <intent-filter>
+ <action android:name="android.service.dreams.DreamService" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </service>
+
<activity android:name=".Somnambulator"
android:label="@string/start_dreams"
android:icon="@mipmap/ic_launcher_dreams"
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index bbfe383..7fdd308 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -431,8 +431,8 @@
<!-- Description of the button in the phone-style notification panel that controls auto-rotation, when auto-rotation is off. [CHAR LIMIT=NONE] -->
<string name="accessibility_rotation_lock_on_portrait">Screen is locked in portrait orientation.</string>
- <!-- Name of the Jelly Bean platlogo screensaver -->
- <string name="jelly_bean_dream_name">BeanFlinger</string>
+ <!-- Name of the K-release easter egg: a display case for all our tastiest desserts. [CHAR LIMIT=30] -->
+ <string name="dessert_case">Dessert Case</string>
<!-- Name of the launcher shortcut icon that allows dreams to be started immediately [CHAR LIMIT=20] -->
<string name="start_dreams">Daydream</string>
diff --git a/packages/SystemUI/src/com/android/systemui/DessertCase.java b/packages/SystemUI/src/com/android/systemui/DessertCase.java
new file mode 100644
index 0000000..b6424af0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/DessertCase.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 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.systemui;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.pm.PackageManager;
+import android.util.Slog;
+
+public class DessertCase extends Activity {
+
+ @Override
+ public void onStart() {
+ super.onStart();
+
+ Slog.v("DessertCase", "ACHIEVEMENT UNLOCKED");
+ PackageManager pm = getPackageManager();
+ pm.setComponentEnabledSetting(new ComponentName(this, DessertCaseDream.class),
+ PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
+
+ finish();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/DessertCaseDream.java b/packages/SystemUI/src/com/android/systemui/DessertCaseDream.java
new file mode 100644
index 0000000..022e4d8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/DessertCaseDream.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2013 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.systemui;
+
+import android.service.dreams.DreamService;
+
+public class DessertCaseDream extends DreamService {
+
+ @Override
+ public void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ setInteractive(true);
+ setFullscreen(true);
+ }
+
+ @Override
+ public void onDreamingStarted() {
+ super.onDreamingStarted();
+ }
+
+ @Override
+ public void onDreamingStopped() {
+ super.onDreamingStopped();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index ada30ac..5ebd11e0 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -23,6 +23,7 @@
import android.app.ActivityManagerNative;
import android.app.ActivityOptions;
import android.app.TaskStackBuilder;
+import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
@@ -698,6 +699,8 @@
new UserHandle(UserHandle.USER_CURRENT));
} catch (SecurityException e) {
Log.e(TAG, "Recents does not have the permission to launch " + intent, e);
+ } catch (ActivityNotFoundException e) {
+ Log.e(TAG, "Error launching activity " + intent, e);
}
}
if (usingDrawingCache) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 4683030..b56d7be 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -424,7 +424,7 @@
mCurrentView.getWidth(), mCurrentView.getHeight(),
visibilityToString(mCurrentView.getVisibility())));
- pw.println(String.format(" disabled=0x%08x vertical=%s hidden=%s low=%s menu=%s",
+ pw.println(String.format(" disabled=0x%08x vertical=%s menu=%s",
mDisabledFlags,
mVertical ? "true" : "false",
mShowMenu ? "true" : "false"));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index ceed30e..25ffbd4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -671,7 +671,7 @@
alarmTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- startSettingsActivity(AlarmClock.ACTION_SET_ALARM);
+ startSettingsActivity(AlarmClock.ACTION_SHOW_ALARMS);
}
});
mModel.addAlarmTile(alarmTile, new QuickSettingsModel.RefreshCallback() {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 8a285e3..ba8671a 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -2819,7 +2819,7 @@
// If the status bar is hidden, we don't want to cause
// windows behind it to scroll.
- if (mStatusBar.isVisibleLw() && !statusBarTransient && !statusBarTransparent) {
+ if (mStatusBar.isVisibleLw() && !statusBarTransient) {
// Status bar may go away, so the screen area it occupies
// is available to apps but just covering them when the
// status bar is visible.
diff --git a/services/java/com/android/server/wifi/WifiService.java b/services/java/com/android/server/wifi/WifiService.java
index 5a24ebb..bbcd01a 100644
--- a/services/java/com/android/server/wifi/WifiService.java
+++ b/services/java/com/android/server/wifi/WifiService.java
@@ -172,10 +172,16 @@
case WifiManager.CONNECT_NETWORK:
case WifiManager.SAVE_NETWORK: {
WifiConfiguration config = (WifiConfiguration) msg.obj;
- if (config.isValid()) {
+ int networkId = msg.arg1;
+ if (config != null && config.isValid()) {
+ if (DBG) Slog.d(TAG, "Connect with config" + config);
+ mWifiStateMachine.sendMessage(Message.obtain(msg));
+ } else if (config == null
+ && networkId != WifiConfiguration.INVALID_NETWORK_ID) {
+ if (DBG) Slog.d(TAG, "Connect with networkId" + networkId);
mWifiStateMachine.sendMessage(Message.obtain(msg));
} else {
- Slog.d(TAG, "ClientHandler.handleMessage ignoring msg=" + msg);
+ Slog.e(TAG, "ClientHandler.handleMessage ignoring invalid msg=" + msg);
if (msg.what == WifiManager.CONNECT_NETWORK) {
replyFailed(msg, WifiManager.CONNECT_NETWORK_FAILED);
} else {
@@ -582,7 +588,8 @@
*/
public void setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
enforceChangePermission();
- if (wifiConfig.isValid()) {
+ // null wifiConfig is a meaningful input for CMD_SET_AP
+ if (wifiConfig == null || wifiConfig.isValid()) {
mWifiController.obtainMessage(CMD_SET_AP, enabled ? 1 : 0, 0, wifiConfig).sendToTarget();
} else {
Slog.e(TAG, "Invalid WifiConfiguration");