diff options
127 files changed, 1129 insertions, 438 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index f08d88de6ba3..378a8bdb1ca2 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -645,11 +645,13 @@ public class Activity extends ContextThemeWrapper Activity mParent; boolean mCalled; boolean mCheckedForLoaderManager; - boolean mStarted; + boolean mLoadersStarted; private boolean mResumed; private boolean mStopped; boolean mFinished; boolean mStartedActivity; + /** true if the activity is going through a transient pause */ + /*package*/ boolean mTemporaryPause = false; /** true if the activity is being destroyed in order to recreate it with a new configuration */ /*package*/ boolean mChangingConfigurations = false; /*package*/ int mConfigChangeFlags; @@ -768,7 +770,7 @@ public class Activity extends ContextThemeWrapper return mLoaderManager; } mCheckedForLoaderManager = true; - mLoaderManager = getLoaderManager(-1, mStarted, true); + mLoaderManager = getLoaderManager(-1, mLoadersStarted, true); return mLoaderManager; } @@ -777,9 +779,13 @@ public class Activity extends ContextThemeWrapper mAllLoaderManagers = new SparseArray<LoaderManagerImpl>(); } LoaderManagerImpl lm = mAllLoaderManagers.get(index); - if (lm == null && create) { - lm = new LoaderManagerImpl(started); - mAllLoaderManagers.put(index, lm); + if (lm == null) { + if (create) { + lm = new LoaderManagerImpl(this, started); + mAllLoaderManagers.put(index, lm); + } + } else { + lm.updateActivity(this); } return lm; } @@ -979,13 +985,16 @@ public class Activity extends ContextThemeWrapper */ protected void onStart() { mCalled = true; - mStarted = true; - if (mLoaderManager != null) { - mLoaderManager.doStart(); - } else if (!mCheckedForLoaderManager) { - mLoaderManager = getLoaderManager(-1, mStarted, false); + + if (!mLoadersStarted) { + mLoadersStarted = true; + if (mLoaderManager != null) { + mLoaderManager.doStart(); + } else if (!mCheckedForLoaderManager) { + mLoaderManager = getLoaderManager(-1, mLoadersStarted, false); + } + mCheckedForLoaderManager = true; } - mCheckedForLoaderManager = true; } /** @@ -4249,7 +4258,7 @@ public class Activity extends ContextThemeWrapper } final void performStart() { - mFragments.mStateSaved = false; + mFragments.noteStateNotSaved(); mCalled = false; mFragments.execPendingActions(); mInstrumentation.callActivityOnStart(this); @@ -4267,7 +4276,7 @@ public class Activity extends ContextThemeWrapper } final void performRestart() { - mFragments.mStateSaved = false; + mFragments.noteStateNotSaved(); synchronized (mManagedCursors) { final int N = mManagedCursors.size(); @@ -4347,8 +4356,8 @@ public class Activity extends ContextThemeWrapper } final void performStop() { - if (mStarted) { - mStarted = false; + if (mLoadersStarted) { + mLoadersStarted = false; if (mLoaderManager != null) { if (!mChangingConfigurations) { mLoaderManager.doStop(); @@ -4407,7 +4416,7 @@ public class Activity extends ContextThemeWrapper if (Config.LOGV) Log.v( TAG, "Dispatching result: who=" + who + ", reqCode=" + requestCode + ", resCode=" + resultCode + ", data=" + data); - mFragments.mStateSaved = false; + mFragments.noteStateNotSaved(); if (who == null) { onActivityResult(requestCode, resultCode, data); } else { diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index f3f7ee7a0618..2abe822c1014 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1757,6 +1757,7 @@ public final class ActivityThread { for (int i=0; i<N; i++) { Intent intent = intents.get(i); intent.setExtrasClassLoader(r.activity.getClassLoader()); + r.activity.mFragments.noteStateNotSaved(); mInstrumentation.callActivityOnNewIntent(r.activity, intent); } } @@ -1767,11 +1768,13 @@ public final class ActivityThread { if (r != null) { final boolean resumed = !r.paused; if (resumed) { + r.activity.mTemporaryPause = true; mInstrumentation.callActivityOnPause(r.activity); } deliverNewIntents(r, intents); if (resumed) { mInstrumentation.callActivityOnResume(r.activity); + r.activity.mTemporaryPause = false; } } } @@ -2594,6 +2597,7 @@ public final class ActivityThread { try { // Now we are idle. r.activity.mCalled = false; + r.activity.mTemporaryPause = true; mInstrumentation.callActivityOnPause(r.activity); if (!r.activity.mCalled) { throw new SuperNotCalledException( @@ -2614,6 +2618,7 @@ public final class ActivityThread { deliverResults(r, res.results); if (resumed) { mInstrumentation.callActivityOnResume(r.activity); + r.activity.mTemporaryPause = false; } } } diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java index 12bf7e5c5a0d..3ec0912c5d0c 100644 --- a/core/java/android/app/Fragment.java +++ b/core/java/android/app/Fragment.java @@ -403,7 +403,7 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener View mView; LoaderManagerImpl mLoaderManager; - boolean mStarted; + boolean mLoadersStarted; boolean mCheckedForLoaderManager; /** @@ -728,7 +728,7 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener return mLoaderManager; } mCheckedForLoaderManager = true; - mLoaderManager = mActivity.getLoaderManager(mIndex, mStarted, true); + mLoaderManager = mActivity.getLoaderManager(mIndex, mLoadersStarted, true); return mLoaderManager; } @@ -880,13 +880,16 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener */ public void onStart() { mCalled = true; - mStarted = true; - if (!mCheckedForLoaderManager) { - mCheckedForLoaderManager = true; - mLoaderManager = mActivity.getLoaderManager(mIndex, mStarted, false); - } - if (mLoaderManager != null) { - mLoaderManager.doStart(); + + if (!mLoadersStarted) { + mLoadersStarted = true; + if (!mCheckedForLoaderManager) { + mCheckedForLoaderManager = true; + mLoaderManager = mActivity.getLoaderManager(mIndex, mLoadersStarted, false); + } + if (mLoaderManager != null) { + mLoaderManager.doStart(); + } } } @@ -971,7 +974,7 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener // + " mLoaderManager=" + mLoaderManager); if (!mCheckedForLoaderManager) { mCheckedForLoaderManager = true; - mLoaderManager = mActivity.getLoaderManager(mIndex, mStarted, false); + mLoaderManager = mActivity.getLoaderManager(mIndex, mLoadersStarted, false); } if (mLoaderManager != null) { mLoaderManager.doDestroy(); @@ -1182,7 +1185,7 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener } if (mLoaderManager != null) { writer.print(prefix); writer.print("mLoaderManager="); writer.print(mLoaderManager); - writer.print(" mStarted="); writer.print(mStarted); + writer.print(" mLoadersStarted="); writer.print(mLoadersStarted); writer.print(" mCheckedForLoaderManager="); writer.println(mCheckedForLoaderManager); } @@ -1190,11 +1193,12 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener void performStop() { onStop(); - if (mStarted) { - mStarted = false; + + if (mLoadersStarted) { + mLoadersStarted = false; if (!mCheckedForLoaderManager) { mCheckedForLoaderManager = true; - mLoaderManager = mActivity.getLoaderManager(mIndex, mStarted, false); + mLoaderManager = mActivity.getLoaderManager(mIndex, mLoadersStarted, false); } if (mLoaderManager != null) { if (mActivity == null || !mActivity.mChangingConfigurations) { diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java index 37e72532e45c..d9a617189781 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -86,6 +86,15 @@ public interface FragmentManager { /** * Start a series of edit operations on the Fragments associated with * this FragmentManager. + * + * <p>Note: A fragment transaction can only be created/committed prior + * to an activity saving its state. If you try to commit a transaction + * after {@link Activity#onSaveInstanceState Activity.onSaveInstanceState()} + * (and prior to a following {@link Activity#onStart Activity.onStart} + * or {@link Activity#onResume Activity.onResume()}, you will get an error. + * This is because the framework takes care of saving your current fragments + * in the state, and if changes are made after the state is saved then they + * will be lost.</p> */ public FragmentTransaction openTransaction(); @@ -271,6 +280,7 @@ final class FragmentManagerImpl implements FragmentManager { boolean mNeedMenuInvalidate; boolean mStateSaved; + String mNoTransactionsBecause; // Temporary vars for state save and restore. Bundle mStateBundle = null; @@ -843,6 +853,10 @@ final class FragmentManagerImpl implements FragmentManager { throw new IllegalStateException( "Can not perform this action after onSaveInstanceState"); } + if (mNoTransactionsBecause != null) { + throw new IllegalStateException( + "Can not perform this action inside of " + mNoTransactionsBecause); + } synchronized (this) { if (mPendingActions == null) { mPendingActions = new ArrayList<Runnable>(); @@ -1271,6 +1285,10 @@ final class FragmentManagerImpl implements FragmentManager { mActivity = activity; } + public void noteStateNotSaved() { + mStateSaved = false; + } + public void dispatchCreate() { mStateSaved = false; moveToState(Fragment.CREATED, false); diff --git a/core/java/android/app/LoaderManager.java b/core/java/android/app/LoaderManager.java index 28abcaa7735f..4d4ea9aee482 100644 --- a/core/java/android/app/LoaderManager.java +++ b/core/java/android/app/LoaderManager.java @@ -40,7 +40,12 @@ public interface LoaderManager { public Loader<D> onCreateLoader(int id, Bundle args); /** - * Called when a previously created loader has finished its load. + * Called when a previously created loader has finished its load. Note + * that normally an application is <em>not</em> allowed to commit fragment + * transactions while in this call, since it can happen after an + * activity's state is saved. See {@link FragmentManager#openTransaction() + * FragmentManager.openTransaction()} for further discussion on this. + * * @param loader The Loader that has finished. * @param data The data generated by the Loader. */ @@ -102,6 +107,7 @@ class LoaderManagerImpl implements LoaderManager { // previously run loader until the new loader's data is available. final SparseArray<LoaderInfo> mInactiveLoaders = new SparseArray<LoaderInfo>(); + Activity mActivity; boolean mStarted; boolean mRetaining; boolean mRetainingStarted; @@ -172,12 +178,12 @@ class LoaderManagerImpl implements LoaderManager { stop(); } } - if (mStarted && mData != null && mCallbacks != null) { + if (mStarted && mData != null) { // This loader was retained, and now at the point of // finishing the retain we find we remain started, have // our data, and the owner has a new callback... so // let's deliver the data now. - mCallbacks.onLoadFinished(mLoader, mData); + callOnLoadFinished(mLoader, mData); } } } @@ -219,9 +225,7 @@ class LoaderManagerImpl implements LoaderManager { // Notify of the new data so the app can switch out the old data before // we try to destroy it. mData = data; - if (mCallbacks != null) { - mCallbacks.onLoadFinished(loader, data); - } + callOnLoadFinished(loader, data); if (DEBUG) Log.v(TAG, "onLoadFinished returned: " + this); @@ -236,6 +240,23 @@ class LoaderManagerImpl implements LoaderManager { } } + void callOnLoadFinished(Loader<Object> loader, Object data) { + if (mCallbacks != null) { + String lastBecause = null; + if (mActivity != null) { + lastBecause = mActivity.mFragments.mNoTransactionsBecause; + mActivity.mFragments.mNoTransactionsBecause = "onLoadFinished"; + } + try { + mCallbacks.onLoadFinished(loader, data); + } finally { + if (mActivity != null) { + mActivity.mFragments.mNoTransactionsBecause = lastBecause; + } + } + } + } + @Override public String toString() { StringBuilder sb = new StringBuilder(64); @@ -252,10 +273,15 @@ class LoaderManagerImpl implements LoaderManager { } } - LoaderManagerImpl(boolean started) { + LoaderManagerImpl(Activity activity, boolean started) { + mActivity = activity; mStarted = started; } + void updateActivity(Activity activity) { + mActivity = activity; + } + private LoaderInfo createLoader(int id, Bundle args, LoaderManager.LoaderCallbacks<Object> callback) { LoaderInfo info = new LoaderInfo(id, args, (LoaderManager.LoaderCallbacks<Object>)callback); @@ -286,7 +312,7 @@ class LoaderManagerImpl implements LoaderManager { if (info.mData != null && mStarted) { // If the loader has already generated its data, report it now. - info.mCallbacks.onLoadFinished(info.mLoader, info.mData); + info.callOnLoadFinished(info.mLoader, info.mData); } return (Loader<D>)info.mLoader; @@ -348,7 +374,13 @@ class LoaderManagerImpl implements LoaderManager { void doStart() { if (DEBUG) Log.v(TAG, "Starting: " + this); - + if (mStarted) { + RuntimeException e = new RuntimeException("here"); + e.fillInStackTrace(); + Log.w(TAG, "Called doStart when already started: " + this, e); + return; + } + // Call out to sub classes so they can start their loaders // Let the existing loaders know that we want to be notified when a load is complete for (int i = mLoaders.size()-1; i >= 0; i--) { @@ -359,6 +391,12 @@ class LoaderManagerImpl implements LoaderManager { void doStop() { if (DEBUG) Log.v(TAG, "Stopping: " + this); + if (!mStarted) { + RuntimeException e = new RuntimeException("here"); + e.fillInStackTrace(); + Log.w(TAG, "Called doStop when not started: " + this, e); + return; + } for (int i = mLoaders.size()-1; i >= 0; i--) { mLoaders.valueAt(i).stop(); @@ -368,6 +406,12 @@ class LoaderManagerImpl implements LoaderManager { void doRetain() { if (DEBUG) Log.v(TAG, "Retaining: " + this); + if (!mStarted) { + RuntimeException e = new RuntimeException("here"); + e.fillInStackTrace(); + Log.w(TAG, "Called doRetain when not started: " + this, e); + return; + } mRetaining = true; mStarted = false; diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index c09519909b43..908a6ab69cdd 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -2471,7 +2471,7 @@ public class WebView extends AbsoluteLayout int viewWidth = getViewWidth(); int newWidth = Math.round(viewWidth * mZoomManager.getInvScale()); - int newHeight = Math.round(getViewHeight() * mZoomManager.getInvScale()); + int newHeight = Math.round((getViewHeightWithTitle() - getTitleHeight()) * mZoomManager.getInvScale()); /* * Because the native side may have already done a layout before the * View system was able to measure us, we have to send a height of 0 to diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java index ff31dec2ff0c..2949208b3ef1 100644 --- a/core/java/android/widget/TabHost.java +++ b/core/java/android/widget/TabHost.java @@ -21,6 +21,7 @@ import com.android.internal.R; import android.app.LocalActivityManager; import android.content.Context; import android.content.Intent; +import android.content.res.TypedArray; import android.graphics.drawable.Drawable; import android.os.Build; import android.util.AttributeSet; @@ -63,6 +64,8 @@ public class TabHost extends FrameLayout implements ViewTreeObserver.OnTouchMode private OnTabChangeListener mOnTabChangeListener; private OnKeyListener mTabKeyListener; + private int mTabLayoutId; + public TabHost(Context context) { super(context); initTabHost(); @@ -70,6 +73,18 @@ public class TabHost extends FrameLayout implements ViewTreeObserver.OnTouchMode public TabHost(Context context, AttributeSet attrs) { super(context, attrs); + + TypedArray a = context.obtainStyledAttributes(attrs, + com.android.internal.R.styleable.TabWidget, + com.android.internal.R.attr.tabWidgetStyle, 0); + + mTabLayoutId = a.getResourceId(R.styleable.TabWidget_tabLayout, 0); + if (mTabLayoutId == 0) { + throw new IllegalArgumentException("Invalid TabWidget tabLayout id"); + } + + a.recycle(); + initTabHost(); } @@ -214,6 +229,7 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1"); if (tabSpec.mIndicatorStrategy instanceof ViewIndicatorStrategy) { mTabWidget.setStripEnabled(false); } + mTabWidget.addView(tabIndicator); mTabSpecs.add(tabSpec); @@ -513,7 +529,7 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1"); final Context context = getContext(); LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - View tabIndicator = inflater.inflate(R.layout.tab_indicator, + View tabIndicator = inflater.inflate(mTabLayoutId, mTabWidget, // tab widget is the parent false); // no inflate params @@ -525,7 +541,7 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1"); tabIndicator.setBackgroundResource(R.drawable.tab_indicator_v4); tv.setTextColor(context.getResources().getColorStateList(R.color.tab_indicator_text_v4)); } - + return tabIndicator; } } @@ -547,7 +563,7 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1"); final Context context = getContext(); LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - View tabIndicator = inflater.inflate(R.layout.tab_indicator, + View tabIndicator = inflater.inflate(mTabLayoutId, mTabWidget, // tab widget is the parent false); // no inflate params @@ -555,14 +571,17 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1"); tv.setText(mLabel); final ImageView iconView = (ImageView) tabIndicator.findViewById(R.id.icon); - iconView.setImageDrawable(mIcon); + if (mIcon != null) { + iconView.setImageDrawable(mIcon); + iconView.setVisibility(VISIBLE); + } if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.DONUT) { // Donut apps get old color scheme tabIndicator.setBackgroundResource(R.drawable.tab_indicator_v4); tv.setTextColor(context.getResources().getColorStateList(R.color.tab_indicator_text_v4)); } - + return tabIndicator; } } diff --git a/core/java/android/widget/TabWidget.java b/core/java/android/widget/TabWidget.java index 0469e7bf7227..36adacdf2620 100644 --- a/core/java/android/widget/TabWidget.java +++ b/core/java/android/widget/TabWidget.java @@ -120,7 +120,9 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener { final Context context = mContext; final Resources resources = context.getResources(); - + + // Tests the target Sdk version, as set in the Manifest. Could not be set using styles.xml + // in a values-v? directory which targets the current platform Sdk version instead. if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.DONUT) { // Donut apps get old color scheme if (mLeftStrip == null) { @@ -131,16 +133,6 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener { mRightStrip = resources.getDrawable( com.android.internal.R.drawable.tab_bottom_right_v4); } - } else { - // Use modern color scheme for Eclair and beyond - if (mLeftStrip == null) { - mLeftStrip = resources.getDrawable( - com.android.internal.R.drawable.tab_bottom_left); - } - if (mRightStrip == null) { - mRightStrip = resources.getDrawable( - com.android.internal.R.drawable.tab_bottom_right); - } } // Deal with focus, as we don't want the focus to go by default diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 09563fc564fe..6897537a5a6d 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -7142,6 +7142,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener case Gravity.RIGHT: return 0.0f; case Gravity.CENTER_HORIZONTAL: + case Gravity.FILL_HORIZONTAL: return (mLayout.getLineWidth(0) - ((mRight - mLeft) - getCompoundPaddingLeft() - getCompoundPaddingRight())) / getHorizontalFadingEdgeLength(); diff --git a/core/java/com/android/internal/nfc/LlcpServiceSocket.java b/core/java/com/android/internal/nfc/LlcpServiceSocket.java index 46075278c2ef..318982b721a1 100644 --- a/core/java/com/android/internal/nfc/LlcpServiceSocket.java +++ b/core/java/com/android/internal/nfc/LlcpServiceSocket.java @@ -78,8 +78,9 @@ public class LlcpServiceSocket { * @param handle * The handle returned by the NFC service and used to identify * the socket in subsequent calls. + * @hide */ - LlcpServiceSocket(ILlcpServiceSocket service, ILlcpSocket socketService, int handle) { + public LlcpServiceSocket(ILlcpServiceSocket service, ILlcpSocket socketService, int handle) { this.mService = service; this.mHandle = handle; this.mLlcpSocketService = socketService; diff --git a/core/java/com/android/internal/nfc/LlcpSocket.java b/core/java/com/android/internal/nfc/LlcpSocket.java index ae74002faebf..b1b132034b4c 100644 --- a/core/java/com/android/internal/nfc/LlcpSocket.java +++ b/core/java/com/android/internal/nfc/LlcpSocket.java @@ -78,8 +78,9 @@ public class LlcpSocket { * @param handle * The handle returned by the NFC service and used to identify * the socket in subsequent calls. + * @hide */ - LlcpSocket(ILlcpSocket service, int handle) { + public LlcpSocket(ILlcpSocket service, int handle) { this.mService = service; this.mHandle = handle; } diff --git a/core/jni/android/graphics/Matrix.cpp b/core/jni/android/graphics/Matrix.cpp index b30550606be2..d0871ac5082f 100644 --- a/core/jni/android/graphics/Matrix.cpp +++ b/core/jni/android/graphics/Matrix.cpp @@ -32,12 +32,6 @@ class SkMatrixGlue { public: static void finalizer(JNIEnv* env, jobject clazz, SkMatrix* obj) { -#ifdef USE_OPENGL_RENDERER - if (android::uirenderer::Caches::hasInstance()) { - android::uirenderer::Caches::getInstance().resourceCache.destructor(obj); - return; - } -#endif // USE_OPENGL_RENDERER delete obj; } diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp index 79a02f106d82..e62b034cc694 100644 --- a/core/jni/android/graphics/Paint.cpp +++ b/core/jni/android/graphics/Paint.cpp @@ -63,12 +63,6 @@ public: }; static void finalizer(JNIEnv* env, jobject clazz, SkPaint* obj) { -#ifdef USE_OPENGL_RENDERER - if (android::uirenderer::Caches::hasInstance()) { - android::uirenderer::Caches::getInstance().resourceCache.destructor(obj); - return; - } -#endif // USE_OPENGL_RENDERER delete obj; } diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp index 45fd5a094142..a586f49e4503 100644 --- a/core/jni/android_app_NativeActivity.cpp +++ b/core/jni/android_app_NativeActivity.cpp @@ -1029,7 +1029,7 @@ static const char* const kNativeActivityPathName = "android/app/NativeActivity"; #define FIND_CLASS(var, className) \ var = env->FindClass(className); \ - LOG_FATAL_IF(! var, "Unable to find class " className); \ + LOG_FATAL_IF(! var, "Unable to find class %s", className); \ var = jclass(env->NewGlobalRef(var)); #define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \ diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp index defd0a0854bc..27d4b9e714c6 100644 --- a/core/jni/android_net_wifi_Wifi.cpp +++ b/core/jni/android_net_wifi_Wifi.cpp @@ -25,6 +25,7 @@ #include "wifi.h" #define WIFI_PKG_NAME "android/net/wifi/WifiNative" +#define BUF_SIZE 256 namespace android { @@ -67,7 +68,7 @@ static int doCommand(const char *cmd, char *replybuf, int replybuflen) static jint doIntCommand(const char *cmd) { - char reply[256]; + char reply[BUF_SIZE]; if (doCommand(cmd, reply, sizeof(reply)) != 0) { return (jint)-1; @@ -78,7 +79,7 @@ static jint doIntCommand(const char *cmd) static jboolean doBooleanCommand(const char *cmd, const char *expect) { - char reply[256]; + char reply[BUF_SIZE]; if (doCommand(cmd, reply, sizeof(reply)) != 0) { return (jboolean)JNI_FALSE; @@ -137,7 +138,7 @@ static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject claz static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject clazz) { - char buf[256]; + char buf[BUF_SIZE]; int nread = ::wifi_wait_for_event(buf, sizeof buf); if (nread > 0) { @@ -159,7 +160,7 @@ static jint android_net_wifi_addNetworkCommand(JNIEnv* env, jobject clazz) static jboolean android_net_wifi_wpsPbcCommand(JNIEnv* env, jobject clazz, jstring bssid) { - char cmdstr[50]; + char cmdstr[BUF_SIZE]; jboolean isCopy; const char *bssidStr = env->GetStringUTFChars(bssid, &isCopy); @@ -172,9 +173,9 @@ static jboolean android_net_wifi_wpsPbcCommand(JNIEnv* env, jobject clazz, jstri return doBooleanCommand(cmdstr, "OK"); } -static jboolean android_net_wifi_wpsPinCommand(JNIEnv* env, jobject clazz, jstring bssid, int apPin) +static jboolean android_net_wifi_wpsPinFromAccessPointCommand(JNIEnv* env, jobject clazz, jstring bssid, int apPin) { - char cmdstr[50]; + char cmdstr[BUF_SIZE]; jboolean isCopy; const char *bssidStr = env->GetStringUTFChars(bssid, &isCopy); @@ -187,13 +188,29 @@ static jboolean android_net_wifi_wpsPinCommand(JNIEnv* env, jobject clazz, jstri return doBooleanCommand(cmdstr, "OK"); } +static jint android_net_wifi_wpsPinFromDeviceCommand(JNIEnv* env, jobject clazz, jstring bssid) +{ + char cmdstr[BUF_SIZE]; + jboolean isCopy; + + const char *bssidStr = env->GetStringUTFChars(bssid, &isCopy); + int numWritten = snprintf(cmdstr, sizeof(cmdstr), "WPS_PIN %s", bssidStr); + env->ReleaseStringUTFChars(bssid, bssidStr); + + if ((numWritten == -1) || (numWritten >= (int)sizeof(cmdstr))) { + return false; + } + return doIntCommand(cmdstr); +} + + static jboolean android_net_wifi_setNetworkVariableCommand(JNIEnv* env, jobject clazz, jint netId, jstring name, jstring value) { - char cmdstr[256]; + char cmdstr[BUF_SIZE]; jboolean isCopy; const char *nameStr = env->GetStringUTFChars(name, &isCopy); @@ -216,7 +233,7 @@ static jstring android_net_wifi_getNetworkVariableCommand(JNIEnv* env, jint netId, jstring name) { - char cmdstr[256]; + char cmdstr[BUF_SIZE]; jboolean isCopy; const char *nameStr = env->GetStringUTFChars(name, &isCopy); @@ -234,7 +251,7 @@ static jstring android_net_wifi_getNetworkVariableCommand(JNIEnv* env, static jboolean android_net_wifi_removeNetworkCommand(JNIEnv* env, jobject clazz, jint netId) { - char cmdstr[256]; + char cmdstr[BUF_SIZE]; int numWritten = snprintf(cmdstr, sizeof(cmdstr), "REMOVE_NETWORK %d", netId); int cmdTooLong = numWritten >= (int)sizeof(cmdstr); @@ -247,7 +264,7 @@ static jboolean android_net_wifi_enableNetworkCommand(JNIEnv* env, jint netId, jboolean disableOthers) { - char cmdstr[256]; + char cmdstr[BUF_SIZE]; const char *cmd = disableOthers ? "SELECT_NETWORK" : "ENABLE_NETWORK"; int numWritten = snprintf(cmdstr, sizeof(cmdstr), "%s %d", cmd, netId); @@ -258,7 +275,7 @@ static jboolean android_net_wifi_enableNetworkCommand(JNIEnv* env, static jboolean android_net_wifi_disableNetworkCommand(JNIEnv* env, jobject clazz, jint netId) { - char cmdstr[256]; + char cmdstr[BUF_SIZE]; int numWritten = snprintf(cmdstr, sizeof(cmdstr), "DISABLE_NETWORK %d", netId); int cmdTooLong = numWritten >= (int)sizeof(cmdstr); @@ -352,7 +369,7 @@ static jboolean android_net_wifi_stopPacketFiltering(JNIEnv* env, jobject clazz) static jint android_net_wifi_getRssiHelper(const char *cmd) { - char reply[256]; + char reply[BUF_SIZE]; int rssi = -200; if (doCommand(cmd, reply, sizeof(reply)) != 0) { @@ -391,7 +408,7 @@ static jint android_net_wifi_getRssiApproxCommand(JNIEnv* env, jobject clazz) static jint android_net_wifi_getLinkSpeedCommand(JNIEnv* env, jobject clazz) { - char reply[256]; + char reply[BUF_SIZE]; int linkspeed; if (doCommand("DRIVER LINKSPEED", reply, sizeof(reply)) != 0) { @@ -405,8 +422,8 @@ static jint android_net_wifi_getLinkSpeedCommand(JNIEnv* env, jobject clazz) static jstring android_net_wifi_getMacAddressCommand(JNIEnv* env, jobject clazz) { - char reply[256]; - char buf[256]; + char reply[BUF_SIZE]; + char buf[BUF_SIZE]; if (doCommand("DRIVER MACADDR", reply, sizeof(reply)) != 0) { return env->NewStringUTF(NULL); @@ -421,7 +438,7 @@ static jstring android_net_wifi_getMacAddressCommand(JNIEnv* env, jobject clazz) static jboolean android_net_wifi_setPowerModeCommand(JNIEnv* env, jobject clazz, jint mode) { - char cmdstr[256]; + char cmdstr[BUF_SIZE]; int numWritten = snprintf(cmdstr, sizeof(cmdstr), "DRIVER POWERMODE %d", mode); int cmdTooLong = numWritten >= (int)sizeof(cmdstr); @@ -431,7 +448,7 @@ static jboolean android_net_wifi_setPowerModeCommand(JNIEnv* env, jobject clazz, static jint android_net_wifi_getPowerModeCommand(JNIEnv* env, jobject clazz) { - char reply[256]; + char reply[BUF_SIZE]; int power; if (doCommand("DRIVER GETPOWER", reply, sizeof(reply)) != 0) { @@ -469,7 +486,7 @@ static jint android_net_wifi_getBandCommand(JNIEnv* env, jobject clazz) static jboolean android_net_wifi_setNumAllowedChannelsCommand(JNIEnv* env, jobject clazz, jint numChannels) { - char cmdstr[256]; + char cmdstr[BUF_SIZE]; int numWritten = snprintf(cmdstr, sizeof(cmdstr), "DRIVER SCAN-CHANNELS %u", numChannels); int cmdTooLong = numWritten >= (int)sizeof(cmdstr); @@ -479,7 +496,7 @@ static jboolean android_net_wifi_setNumAllowedChannelsCommand(JNIEnv* env, jobje static jint android_net_wifi_getNumAllowedChannelsCommand(JNIEnv* env, jobject clazz) { - char reply[256]; + char reply[BUF_SIZE]; int numChannels; if (doCommand("DRIVER SCAN-CHANNELS", reply, sizeof(reply)) != 0) { @@ -495,7 +512,7 @@ static jint android_net_wifi_getNumAllowedChannelsCommand(JNIEnv* env, jobject c static jboolean android_net_wifi_setBluetoothCoexistenceModeCommand(JNIEnv* env, jobject clazz, jint mode) { - char cmdstr[256]; + char cmdstr[BUF_SIZE]; int numWritten = snprintf(cmdstr, sizeof(cmdstr), "DRIVER BTCOEXMODE %d", mode); int cmdTooLong = numWritten >= (int)sizeof(cmdstr); @@ -505,7 +522,7 @@ static jboolean android_net_wifi_setBluetoothCoexistenceModeCommand(JNIEnv* env, static jboolean android_net_wifi_setBluetoothCoexistenceScanModeCommand(JNIEnv* env, jobject clazz, jboolean setCoexScanMode) { - char cmdstr[256]; + char cmdstr[BUF_SIZE]; int numWritten = snprintf(cmdstr, sizeof(cmdstr), "DRIVER BTCOEXSCAN-%s", setCoexScanMode ? "START" : "STOP"); int cmdTooLong = numWritten >= (int)sizeof(cmdstr); @@ -527,7 +544,7 @@ static jboolean android_net_wifi_reloadConfigCommand(JNIEnv* env, jobject clazz) static jboolean android_net_wifi_setScanResultHandlingCommand(JNIEnv* env, jobject clazz, jint mode) { - char cmdstr[256]; + char cmdstr[BUF_SIZE]; int numWritten = snprintf(cmdstr, sizeof(cmdstr), "AP_SCAN %d", mode); int cmdTooLong = numWritten >= (int)sizeof(cmdstr); @@ -537,7 +554,7 @@ static jboolean android_net_wifi_setScanResultHandlingCommand(JNIEnv* env, jobje static jboolean android_net_wifi_addToBlacklistCommand(JNIEnv* env, jobject clazz, jstring bssid) { - char cmdstr[256]; + char cmdstr[BUF_SIZE]; jboolean isCopy; const char *bssidStr = env->GetStringUTFChars(bssid, &isCopy); @@ -636,7 +653,10 @@ static JNINativeMethod gWifiMethods[] = { { "addToBlacklistCommand", "(Ljava/lang/String;)Z", (void*) android_net_wifi_addToBlacklistCommand }, { "clearBlacklistCommand", "()Z", (void*) android_net_wifi_clearBlacklistCommand }, { "startWpsPbcCommand", "(Ljava/lang/String;)Z", (void*) android_net_wifi_wpsPbcCommand }, - { "startWpsPinCommand", "(Ljava/lang/String;I)Z", (void*) android_net_wifi_wpsPinCommand }, + { "startWpsWithPinFromAccessPointCommand", "(Ljava/lang/String;I)Z", + (void*) android_net_wifi_wpsPinFromAccessPointCommand }, + { "startWpsWithPinFromDeviceCommand", "(Ljava/lang/String;)I", + (void*) android_net_wifi_wpsPinFromDeviceCommand }, { "doDhcpRequest", "(Landroid/net/DhcpInfo;)Z", (void*) android_net_wifi_doDhcpRequest }, { "getDhcpError", "()Ljava/lang/String;", (void*) android_net_wifi_getDhcpError }, }; diff --git a/core/res/res/drawable-hdpi/btn_group_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_group_disabled_holo_dark.9.png Binary files differnew file mode 100644 index 000000000000..bd353ae5cd70 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_group_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_group_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/btn_group_disabled_holo_light.9.png Binary files differnew file mode 100644 index 000000000000..d127b3c863e2 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_group_disabled_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/btn_group_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_group_focused_holo_dark.9.png Binary files differnew file mode 100644 index 000000000000..1d1a58909cbd --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_group_focused_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_group_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_group_focused_holo_light.9.png Binary files differnew file mode 100644 index 000000000000..1d1a58909cbd --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_group_focused_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/btn_group_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_group_pressed_holo_dark.9.png Binary files differnew file mode 100644 index 000000000000..8922fa4711d9 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_group_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_group_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/btn_group_pressed_holo_light.9.png Binary files differnew file mode 100644 index 000000000000..53cf2f386f82 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_group_pressed_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/divider_vertical_holo_dark.9.png b/core/res/res/drawable-hdpi/divider_vertical_holo_dark.9.png Binary files differindex deacb7303816..c039428b70b4 100644 --- a/core/res/res/drawable-hdpi/divider_vertical_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/divider_vertical_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/divider_vertical_holo_light.9.png b/core/res/res/drawable-hdpi/divider_vertical_holo_light.9.png Binary files differindex cd2c826874bc..7c4a29ff25c2 100644 --- a/core/res/res/drawable-hdpi/divider_vertical_holo_light.9.png +++ b/core/res/res/drawable-hdpi/divider_vertical_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/tab_arrow_left_holo_dark.png b/core/res/res/drawable-hdpi/tab_arrow_left_holo_dark.png Binary files differdeleted file mode 100644 index cfd6f785c880..000000000000 --- a/core/res/res/drawable-hdpi/tab_arrow_left_holo_dark.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/tab_arrow_left_holo_light.png b/core/res/res/drawable-hdpi/tab_arrow_left_holo_light.png Binary files differdeleted file mode 100644 index 036aa8c0b6ad..000000000000 --- a/core/res/res/drawable-hdpi/tab_arrow_left_holo_light.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/tab_arrow_right_holo_dark.png b/core/res/res/drawable-hdpi/tab_arrow_right_holo_dark.png Binary files differdeleted file mode 100644 index b22603879561..000000000000 --- a/core/res/res/drawable-hdpi/tab_arrow_right_holo_dark.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/tab_arrow_right_holo_light.png b/core/res/res/drawable-hdpi/tab_arrow_right_holo_light.png Binary files differdeleted file mode 100644 index 0e5fbe671c01..000000000000 --- a/core/res/res/drawable-hdpi/tab_arrow_right_holo_light.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/tab_bottom_holo.9.png b/core/res/res/drawable-hdpi/tab_bottom_holo.9.png Binary files differnew file mode 100644 index 000000000000..ec9fa8d8054e --- /dev/null +++ b/core/res/res/drawable-hdpi/tab_bottom_holo.9.png diff --git a/core/res/res/drawable-hdpi/tab_divider_holo_dark.png b/core/res/res/drawable-hdpi/tab_divider_holo_dark.png Binary files differdeleted file mode 100644 index 112cb04b829e..000000000000 --- a/core/res/res/drawable-hdpi/tab_divider_holo_dark.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/tab_divider_holo_light.png b/core/res/res/drawable-hdpi/tab_divider_holo_light.png Binary files differdeleted file mode 100644 index 1bf4d386881a..000000000000 --- a/core/res/res/drawable-hdpi/tab_divider_holo_light.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/tab_selected_focused_holo.9.png b/core/res/res/drawable-hdpi/tab_selected_focused_holo.9.png Binary files differnew file mode 100644 index 000000000000..1ba35d554811 --- /dev/null +++ b/core/res/res/drawable-hdpi/tab_selected_focused_holo.9.png diff --git a/core/res/res/drawable-hdpi/tab_selected_holo.9.png b/core/res/res/drawable-hdpi/tab_selected_holo.9.png Binary files differnew file mode 100644 index 000000000000..ef913cc8e593 --- /dev/null +++ b/core/res/res/drawable-hdpi/tab_selected_holo.9.png diff --git a/core/res/res/drawable-hdpi/tab_selected_pressed_focused_holo.9.png b/core/res/res/drawable-hdpi/tab_selected_pressed_focused_holo.9.png Binary files differnew file mode 100644 index 000000000000..d7e968806aed --- /dev/null +++ b/core/res/res/drawable-hdpi/tab_selected_pressed_focused_holo.9.png diff --git a/core/res/res/drawable-hdpi/tab_selected_pressed_holo.9.png b/core/res/res/drawable-hdpi/tab_selected_pressed_holo.9.png Binary files differnew file mode 100644 index 000000000000..b8b1fcfe2655 --- /dev/null +++ b/core/res/res/drawable-hdpi/tab_selected_pressed_holo.9.png diff --git a/core/res/res/drawable-hdpi/tab_selector_holo_dark.9.png b/core/res/res/drawable-hdpi/tab_selector_holo_dark.9.png Binary files differdeleted file mode 100644 index f01b9bc3f92e..000000000000 --- a/core/res/res/drawable-hdpi/tab_selector_holo_dark.9.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/tab_strip_holo.9.png b/core/res/res/drawable-hdpi/tab_strip_holo.9.png Binary files differdeleted file mode 100644 index d937f6b9e2a3..000000000000 --- a/core/res/res/drawable-hdpi/tab_strip_holo.9.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/tab_unselected_focused_holo.9.png b/core/res/res/drawable-hdpi/tab_unselected_focused_holo.9.png Binary files differnew file mode 100644 index 000000000000..256e8e7302e4 --- /dev/null +++ b/core/res/res/drawable-hdpi/tab_unselected_focused_holo.9.png diff --git a/core/res/res/drawable-hdpi/tab_unselected_holo.9.png b/core/res/res/drawable-hdpi/tab_unselected_holo.9.png Binary files differnew file mode 100644 index 000000000000..eaa306aee14b --- /dev/null +++ b/core/res/res/drawable-hdpi/tab_unselected_holo.9.png diff --git a/core/res/res/drawable-hdpi/tab_unselected_pressed_focused_holo.9.png b/core/res/res/drawable-hdpi/tab_unselected_pressed_focused_holo.9.png Binary files differnew file mode 100644 index 000000000000..d17b82026b64 --- /dev/null +++ b/core/res/res/drawable-hdpi/tab_unselected_pressed_focused_holo.9.png diff --git a/core/res/res/drawable-hdpi/tab_unselected_pressed_holo.9.png b/core/res/res/drawable-hdpi/tab_unselected_pressed_holo.9.png Binary files differnew file mode 100644 index 000000000000..a344994fb5c9 --- /dev/null +++ b/core/res/res/drawable-hdpi/tab_unselected_pressed_holo.9.png diff --git a/core/res/res/drawable-mdpi/btn_group_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_group_disabled_holo_dark.9.png Binary files differnew file mode 100644 index 000000000000..aa04cc962259 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_group_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_group_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/btn_group_disabled_holo_light.9.png Binary files differnew file mode 100644 index 000000000000..25aefd2a282c --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_group_disabled_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/btn_group_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_group_focused_holo_dark.9.png Binary files differnew file mode 100644 index 000000000000..b77cc78d3e34 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_group_focused_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_group_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_group_focused_holo_light.9.png Binary files differnew file mode 100644 index 000000000000..aa00c75544ba --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_group_focused_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/btn_group_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_group_pressed_holo_dark.9.png Binary files differnew file mode 100644 index 000000000000..e35333b61bad --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_group_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_group_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/btn_group_pressed_holo_light.9.png Binary files differnew file mode 100644 index 000000000000..878fddaec00b --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_group_pressed_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/divider_vertical_holo_dark.9.png b/core/res/res/drawable-mdpi/divider_vertical_holo_dark.9.png Binary files differindex 4c6968cb9a9d..c039428b70b4 100644 --- a/core/res/res/drawable-mdpi/divider_vertical_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/divider_vertical_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/divider_vertical_holo_light.9.png b/core/res/res/drawable-mdpi/divider_vertical_holo_light.9.png Binary files differindex 7ddf1b63e2fa..7c4a29ff25c2 100644 --- a/core/res/res/drawable-mdpi/divider_vertical_holo_light.9.png +++ b/core/res/res/drawable-mdpi/divider_vertical_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/tab_arrow_left_holo_dark.png b/core/res/res/drawable-mdpi/tab_arrow_left_holo_dark.png Binary files differdeleted file mode 100644 index 4f8bafe08ce0..000000000000 --- a/core/res/res/drawable-mdpi/tab_arrow_left_holo_dark.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/tab_arrow_left_holo_light.png b/core/res/res/drawable-mdpi/tab_arrow_left_holo_light.png Binary files differdeleted file mode 100644 index 8e225fce686e..000000000000 --- a/core/res/res/drawable-mdpi/tab_arrow_left_holo_light.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/tab_arrow_right_holo_dark.png b/core/res/res/drawable-mdpi/tab_arrow_right_holo_dark.png Binary files differdeleted file mode 100644 index 0a8006de9829..000000000000 --- a/core/res/res/drawable-mdpi/tab_arrow_right_holo_dark.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/tab_arrow_right_holo_light.png b/core/res/res/drawable-mdpi/tab_arrow_right_holo_light.png Binary files differdeleted file mode 100644 index 85aae47d55f2..000000000000 --- a/core/res/res/drawable-mdpi/tab_arrow_right_holo_light.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/tab_bottom_holo.9.png b/core/res/res/drawable-mdpi/tab_bottom_holo.9.png Binary files differnew file mode 100644 index 000000000000..1e40b9c553ad --- /dev/null +++ b/core/res/res/drawable-mdpi/tab_bottom_holo.9.png diff --git a/core/res/res/drawable-mdpi/tab_divider_holo_dark.png b/core/res/res/drawable-mdpi/tab_divider_holo_dark.png Binary files differdeleted file mode 100644 index 89d7b8bec2e3..000000000000 --- a/core/res/res/drawable-mdpi/tab_divider_holo_dark.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/tab_divider_holo_light.png b/core/res/res/drawable-mdpi/tab_divider_holo_light.png Binary files differdeleted file mode 100644 index 878b2b42aa83..000000000000 --- a/core/res/res/drawable-mdpi/tab_divider_holo_light.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/tab_focused_holo.9.png b/core/res/res/drawable-mdpi/tab_focused_holo.9.png Binary files differnew file mode 100644 index 000000000000..187d8c56e11e --- /dev/null +++ b/core/res/res/drawable-mdpi/tab_focused_holo.9.png diff --git a/core/res/res/drawable-mdpi/tab_pressed_holo.9.png b/core/res/res/drawable-mdpi/tab_pressed_holo.9.png Binary files differnew file mode 100644 index 000000000000..a76fbae5be06 --- /dev/null +++ b/core/res/res/drawable-mdpi/tab_pressed_holo.9.png diff --git a/core/res/res/drawable-mdpi/tab_selected_focused_holo.9.png b/core/res/res/drawable-mdpi/tab_selected_focused_holo.9.png Binary files differnew file mode 100644 index 000000000000..9a33cd2d9287 --- /dev/null +++ b/core/res/res/drawable-mdpi/tab_selected_focused_holo.9.png diff --git a/core/res/res/drawable-mdpi/tab_selected_holo.9.png b/core/res/res/drawable-mdpi/tab_selected_holo.9.png Binary files differnew file mode 100644 index 000000000000..e029e577a711 --- /dev/null +++ b/core/res/res/drawable-mdpi/tab_selected_holo.9.png diff --git a/core/res/res/drawable-mdpi/tab_selected_pressed_focused_holo.9.png b/core/res/res/drawable-mdpi/tab_selected_pressed_focused_holo.9.png Binary files differnew file mode 100644 index 000000000000..285116e31e1c --- /dev/null +++ b/core/res/res/drawable-mdpi/tab_selected_pressed_focused_holo.9.png diff --git a/core/res/res/drawable-mdpi/tab_selected_pressed_holo.9.png b/core/res/res/drawable-mdpi/tab_selected_pressed_holo.9.png Binary files differnew file mode 100644 index 000000000000..dadefa758af5 --- /dev/null +++ b/core/res/res/drawable-mdpi/tab_selected_pressed_holo.9.png diff --git a/core/res/res/drawable-mdpi/tab_selector_holo_dark.9.png b/core/res/res/drawable-mdpi/tab_selector_holo_dark.9.png Binary files differdeleted file mode 100644 index 30d30df42b1d..000000000000 --- a/core/res/res/drawable-mdpi/tab_selector_holo_dark.9.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/tab_unselected_focused_holo.9.png b/core/res/res/drawable-mdpi/tab_unselected_focused_holo.9.png Binary files differnew file mode 100644 index 000000000000..032a9921c54e --- /dev/null +++ b/core/res/res/drawable-mdpi/tab_unselected_focused_holo.9.png diff --git a/core/res/res/drawable-mdpi/tab_unselected_holo.9.png b/core/res/res/drawable-mdpi/tab_unselected_holo.9.png Binary files differnew file mode 100644 index 000000000000..848f3f13363c --- /dev/null +++ b/core/res/res/drawable-mdpi/tab_unselected_holo.9.png diff --git a/core/res/res/drawable-mdpi/tab_unselected_pressed_focused_holo.9.png b/core/res/res/drawable-mdpi/tab_unselected_pressed_focused_holo.9.png Binary files differnew file mode 100644 index 000000000000..384513584731 --- /dev/null +++ b/core/res/res/drawable-mdpi/tab_unselected_pressed_focused_holo.9.png diff --git a/core/res/res/drawable-mdpi/tab_unselected_pressed_holo.9.png b/core/res/res/drawable-mdpi/tab_unselected_pressed_holo.9.png Binary files differnew file mode 100644 index 000000000000..23fd8c9b351c --- /dev/null +++ b/core/res/res/drawable-mdpi/tab_unselected_pressed_holo.9.png diff --git a/core/res/res/drawable-nodpi/background_holo_dark.png b/core/res/res/drawable-nodpi/background_holo_dark.png Binary files differnew file mode 100644 index 000000000000..f2ff75a54c9d --- /dev/null +++ b/core/res/res/drawable-nodpi/background_holo_dark.png diff --git a/core/res/res/drawable-nodpi/background_holo_light.png b/core/res/res/drawable-nodpi/background_holo_light.png Binary files differnew file mode 100644 index 000000000000..04f52aeb3456 --- /dev/null +++ b/core/res/res/drawable-nodpi/background_holo_light.png diff --git a/core/res/res/drawable/group_button_background_holo_dark.xml b/core/res/res/drawable/group_button_background_holo_dark.xml index 8e6675a0f5c4..fa007851fe1e 100644 --- a/core/res/res/drawable/group_button_background_holo_dark.xml +++ b/core/res/res/drawable/group_button_background_holo_dark.xml @@ -19,10 +19,10 @@ <item android:state_window_focused="false" android:drawable="@color/transparent" /> <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. --> - <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@color/group_button_background_pressed_holo_dark" /> - <item android:state_focused="true" android:state_enabled="false" android:drawable="@color/group_button_background_focused_holo_dark" /> - <item android:state_focused="true" android:state_pressed="true" android:drawable="@color/group_button_background_pressed_holo_dark" /> - <item android:state_focused="false" android:state_pressed="true" android:drawable="@color/group_button_background_pressed_holo_dark" /> - <item android:state_focused="true" android:drawable="@color/group_button_background_focused_holo_dark" /> + <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/btn_group_disabled_holo_dark" /> + <item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/btn_group_disabled_holo_dark" /> + <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/btn_group_pressed_holo_dark" /> + <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/btn_group_pressed_holo_dark" /> + <item android:state_focused="true" android:drawable="@drawable/btn_group_focused_holo_dark" /> <item android:drawable="@color/transparent" /> </selector> diff --git a/core/res/res/drawable/group_button_background_holo_light.xml b/core/res/res/drawable/group_button_background_holo_light.xml index 94b3b5a4b2a0..1e74ec78c2b4 100644 --- a/core/res/res/drawable/group_button_background_holo_light.xml +++ b/core/res/res/drawable/group_button_background_holo_light.xml @@ -19,10 +19,10 @@ <item android:state_window_focused="false" android:drawable="@color/transparent" /> <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. --> - <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@color/group_button_background_pressed_holo_light" /> - <item android:state_focused="true" android:state_enabled="false" android:drawable="@color/group_button_background_focused_holo_light" /> - <item android:state_focused="true" android:state_pressed="true" android:drawable="@color/group_button_background_pressed_holo_light" /> - <item android:state_focused="false" android:state_pressed="true" android:drawable="@color/group_button_background_pressed_holo_light" /> - <item android:state_focused="true" android:drawable="@color/group_button_background_focused_holo_light" /> + <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/btn_group_disabled_holo_light" /> + <item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/btn_group_disabled_holo_light" /> + <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/btn_group_pressed_holo_light" /> + <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/btn_group_pressed_holo_light" /> + <item android:state_focused="true" android:drawable="@drawable/btn_group_focused_holo_light" /> <item android:drawable="@color/transparent" /> </selector> diff --git a/core/res/res/drawable/item_background.xml b/core/res/res/drawable/item_background.xml new file mode 100644 index 000000000000..a1c9ff872aa7 --- /dev/null +++ b/core/res/res/drawable/item_background.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + + <item android:state_window_focused="false" android:drawable="@color/transparent" /> + + <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. --> + <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/list_selector_background_disabled" /> + <item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/list_selector_background_disabled" /> + <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/list_selector_background_transition" /> + <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/list_selector_background_transition" /> + <item android:state_focused="true" android:drawable="@drawable/list_selector_background_focused" /> + <item android:drawable="@color/transparent" /> + +</selector> diff --git a/core/res/res/drawable/item_background_holo_dark.xml b/core/res/res/drawable/item_background_holo_dark.xml new file mode 100644 index 000000000000..f119ec02b41f --- /dev/null +++ b/core/res/res/drawable/item_background_holo_dark.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + + <item android:state_window_focused="false" android:drawable="@color/transparent" /> + + <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. --> + <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/list_selector_disabled_holo_dark" /> + <item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/list_selector_disabled_holo_dark" /> + <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/list_selector_background_transition_holo_dark" /> + <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/list_selector_background_transition_holo_dark" /> + <item android:state_focused="true" android:drawable="@drawable/list_focused_holo" /> + <item android:drawable="@color/transparent" /> +</selector> diff --git a/core/res/res/drawable/item_background_holo_light.xml b/core/res/res/drawable/item_background_holo_light.xml new file mode 100644 index 000000000000..d3d278a11101 --- /dev/null +++ b/core/res/res/drawable/item_background_holo_light.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + + <item android:state_window_focused="false" android:drawable="@color/transparent" /> + + <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. --> + <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/list_selector_disabled_holo_light" /> + <item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/list_selector_disabled_holo_light" /> + <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/list_selector_background_transition_holo_light" /> + <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/list_selector_background_transition_holo_light" /> + <item android:state_focused="true" android:drawable="@drawable/list_focused_holo" /> + <item android:drawable="@color/transparent" /> +</selector> diff --git a/core/res/res/drawable/tab_bottom_right.xml b/core/res/res/drawable/tab_bottom_right.xml index f7f5c2f5a07c..450c461e983b 100644 --- a/core/res/res/drawable/tab_bottom_right.xml +++ b/core/res/res/drawable/tab_bottom_right.xml @@ -16,6 +16,6 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:drawable="@drawable/tab_press_bar_right"/> - <item android:state_focused="false" android:state_pressed="false" android:drawable="@drawable/tab_selected_bar_right"/> - <item android:state_focused="true" android:state_pressed="false" android:drawable="@drawable/tab_focus_bar_right"/> + <item android:state_focused="false" android:drawable="@drawable/tab_selected_bar_right"/> + <item android:state_focused="true" android:drawable="@drawable/tab_focus_bar_right"/> </selector> diff --git a/core/res/res/drawable/tab_indicator_holo.xml b/core/res/res/drawable/tab_indicator_holo.xml new file mode 100644 index 000000000000..0d46e0c471fd --- /dev/null +++ b/core/res/res/drawable/tab_indicator_holo.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2008 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <!-- Non focused states --> + <item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/tab_unselected_holo" /> + <item android:state_focused="false" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/tab_selected_holo" /> + + <!-- Focused states --> + <item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/tab_unselected_focused_holo" /> + <item android:state_focused="true" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/tab_selected_focused_holo" /> + + <!-- Pressed --> + <!-- Non focused states --> + <item android:state_focused="false" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/tab_unselected_pressed_holo" /> + <item android:state_focused="false" android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/tab_selected_pressed_holo" /> + + <!-- Focused states --> + <item android:state_focused="true" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/tab_unselected_pressed_focused_holo" /> + <item android:state_focused="true" android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/tab_selected_pressed_focused_holo" /> +</selector> diff --git a/core/res/res/layout/action_menu_item_layout.xml b/core/res/res/layout/action_menu_item_layout.xml index 1f3117ba92a7..94fcc2ff93fc 100644 --- a/core/res/res/layout/action_menu_item_layout.xml +++ b/core/res/res/layout/action_menu_item_layout.xml @@ -18,6 +18,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" + android:addStatesFromChildren="true" + android:background="?attr/selectableItemBackground" android:minWidth="64dip" android:minHeight="?attr/actionBarSize" android:paddingLeft="12dip" @@ -33,9 +35,9 @@ android:layout_height="wrap_content" android:layout_gravity="center" android:visibility="gone" - android:background="?attr/groupButtonBackground" android:textAppearance="?attr/textAppearanceMedium" style="?attr/buttonStyleSmall" + android:background="@null" android:paddingLeft="4dip" android:paddingRight="4dip" /> </com.android.internal.view.menu.ActionMenuItemView> diff --git a/core/res/res/layout/action_mode_close_item.xml b/core/res/res/layout/action_mode_close_item.xml index 0505f18087a2..bc6989075ff8 100644 --- a/core/res/res/layout/action_mode_close_item.xml +++ b/core/res/res/layout/action_mode_close_item.xml @@ -20,7 +20,8 @@ android:layout_marginTop="12dip" android:layout_marginBottom="12dip" android:gravity="center" - android:showDividers="end"> + android:showDividers="end" + android:background="?android:attr/selectableItemBackground"> <Button android:id="@+id/action_mode_close_button" android:text="@string/action_mode_done" android:paddingLeft="16dip" diff --git a/core/res/res/layout/tab_indicator.xml b/core/res/res/layout/tab_indicator.xml index 71e400180898..bc657c399c26 100644 --- a/core/res/res/layout/tab_indicator.xml +++ b/core/res/res/layout/tab_indicator.xml @@ -20,7 +20,6 @@ android:layout_weight="1" android:layout_marginLeft="-3dip" android:layout_marginRight="-3dip" - android:orientation="vertical" android:background="@android:drawable/tab_indicator"> <ImageView android:id="@+id/icon" diff --git a/core/res/res/layout/tab_indicator_holo.xml b/core/res/res/layout/tab_indicator_holo.xml new file mode 100644 index 000000000000..d37476be2336 --- /dev/null +++ b/core/res/res/layout/tab_indicator_holo.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2008 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="56dip" + android:layout_weight="0" + android:layout_marginLeft="0dip" + android:layout_marginRight="0dip" + android:background="@android:drawable/tab_indicator_holo"> + + <View android:id="@+id/tab_indicator_left_spacer" + android:layout_width="16dip" + android:layout_height="0dip" /> + + <ImageView android:id="@+id/icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerVertical="true" + android:visibility="gone" + android:layout_toRightOf="@id/tab_indicator_left_spacer" + android:paddingRight="8dip" /> + + <TextView android:id="@+id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerVertical="true" + android:layout_toRightOf="@id/icon" + android:paddingLeft="0dip" + android:paddingRight="16dip" + style="?android:attr/tabWidgetStyle" /> + +</RelativeLayout> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 3f4635a569d7..dab627c8a39f 100755 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -571,6 +571,9 @@ <!-- Drawable for group button backgrounds --> <attr name="groupButtonBackground" format="reference" /> + <!-- Background drawable for standalone items that need focus/pressed states. --> + <attr name="selectableItemBackground" format="reference" /> + <!-- SearchView dropdown background --> <attr name="searchDropdownBackground" format="reference" /> </declare-styleable> @@ -2134,6 +2137,8 @@ <attr name="tabStripLeft" format="reference" /> <!-- Drawable used to draw the right part of the strip underneath the tabs. --> <attr name="tabStripRight" format="reference" /> + <!-- Layout used to organize each tab's content. --> + <attr name="tabLayout" format="reference" /> </declare-styleable> <declare-styleable name="TextAppearance"> <!-- Text color. --> diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml index 774c02d3ea2a..21b810e35a83 100644 --- a/core/res/res/values/colors.xml +++ b/core/res/res/values/colors.xml @@ -132,10 +132,10 @@ <color name="link_text_holo_light">#0000ee</color> <!-- Group buttons --> - <color name="group_button_background_pressed_holo_dark">#46c5c1ff</color> - <color name="group_button_background_focused_holo_dark">#2699cc00</color> + <color name="group_button_dialog_pressed_holo_dark">#46c5c1ff</color> + <color name="group_button_dialog_focused_holo_dark">#2699cc00</color> - <color name="group_button_background_pressed_holo_light">#ffffffff</color> - <color name="group_button_background_focused_holo_light">#4699cc00</color> + <color name="group_button_dialog_pressed_holo_light">#ffffffff</color> + <color name="group_button_dialog_focused_holo_light">#4699cc00</color> </resources> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index d5ea09efc0b0..749b3c74520e 100755 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1633,7 +1633,7 @@ <!-- Do not translate. WebView User Agent string --> <string name="web_user_agent" translatable="false">Mozilla/5.0 (Linux; U; <xliff:g id="x">Android %s</xliff:g>) - AppleWebKit/534.10 (KHTML, like Gecko) Version/4.0 <xliff:g id="mobile">%s</xliff:g>Safari/534.10</string> + AppleWebKit/534.11 (KHTML, like Gecko) Version/4.0 <xliff:g id="mobile">%s</xliff:g>Safari/534.11</string> <!-- Do not translate. WebView User Agent targeted content --> <string name="web_user_agent_target_content" translatable="false">"Mobile "</string> diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index 781dd2cb1872..76a3c34abb22 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -560,6 +560,12 @@ <item name="android:textAppearance">@style/TextAppearance.Widget.TabWidget</item> <item name="ellipsize">marquee</item> <item name="singleLine">true</item> + <item name="android:tabStripLeft">@android:drawable/tab_bottom_left</item> + <item name="android:tabStripRight">@android:drawable/tab_bottom_right</item> + <item name="android:tabStripEnabled">true</item> + <item name="android:divider">@null</item> + <item name="android:gravity">fill_horizontal|center_vertical</item> + <item name="android:tabLayout">@android:layout/tab_indicator</item> </style> <style name="Widget.Gallery"> @@ -1070,7 +1076,7 @@ </style> <style name="TextAppearance.Holo.Widget.TabWidget"> - <item name="android:textSize">14sp</item> + <item name="android:textSize">18sp</item> <item name="android:textStyle">normal</item> <item name="android:textColor">@android:color/tab_indicator_text</item> </style> @@ -1250,15 +1256,19 @@ <item name="android:minHeight">48dip</item> <item name="android:paddingLeft">32dip</item> <item name="android:paddingRight">32dip</item> + <item name="android:paddingTop">4dip</item> + <item name="android:paddingBottom">4dip</item> </style> <style name="Widget.Holo.Button.Small"> <item name="android:background">@android:drawable/btn_default_holo_dark</item> <item name="android:textAppearance">?android:attr/textAppearanceSmall</item> <item name="android:textColor">@android:color/primary_text_holo_dark</item> - <item name="android:minHeight">40dip</item> + <item name="android:minHeight">48dip</item> <item name="android:paddingLeft">24dip</item> <item name="android:paddingRight">24dip</item> + <item name="android:paddingTop">4dip</item> + <item name="android:paddingBottom">4dip</item> </style> <style name="Widget.Holo.Button.Inset"> @@ -1279,6 +1289,7 @@ <style name="Widget.Holo.ButtonGroup" parent="Widget.ButtonGroup"> <item name="divider">?android:attr/dividerVertical</item> <item name="showDividers">middle</item> + <item name="android:background">@android:drawable/btn_default_holo_dark</item> </style> <style name="Widget.Holo.ButtonGroup.AlertDialog"> @@ -1416,6 +1427,13 @@ </style> <style name="Widget.Holo.TabWidget" parent="Widget.TabWidget"> + <item name="android:textAppearance">@style/TextAppearance.Holo.Widget.TabWidget</item> + <item name="android:tabStripLeft">@null</item> + <item name="android:tabStripRight">@null</item> + <item name="android:tabStripEnabled">false</item> + <item name="android:divider">@null</item> + <item name="android:gravity">left|center_vertical</item> + <item name="android:tabLayout">@android:layout/tab_indicator_holo</item> </style> <style name="Widget.Holo.WebTextView" parent="Widget.WebTextView"> @@ -1483,6 +1501,7 @@ <style name="Widget.Holo.ActionButton.Overflow"> <item name="android:src">@android:drawable/ic_menu_moreoverflow_holo_dark</item> + <item name="android:background">?android:attr/selectableItemBackground</item> </style> <style name="Widget.Holo.ActionButton.TextButton" parent="Widget.Holo.ButtonBar.Button"> @@ -1529,14 +1548,18 @@ <item name="android:minHeight">48dip</item> <item name="android:paddingLeft">32dip</item> <item name="android:paddingRight">32dip</item> + <item name="android:paddingTop">4dip</item> + <item name="android:paddingBottom">4dip</item> </style> <style name="Widget.Holo.Light.Button.Small"> <item name="android:textAppearance">?android:attr/textAppearanceSmall</item> <item name="android:textColor">@android:color/primary_text_holo_light</item> - <item name="android:minHeight">40dip</item> + <item name="android:minHeight">48dip</item> <item name="android:paddingLeft">24dip</item> <item name="android:paddingRight">24dip</item> + <item name="android:paddingTop">4dip</item> + <item name="android:paddingBottom">4dip</item> </style> <style name="Widget.Holo.Light.Button.Inset"> @@ -1554,6 +1577,7 @@ </style> <style name="Widget.Holo.Light.ButtonGroup" parent="Widget.Holo.ButtonGroup"> + <item name="android:background">@android:drawable/btn_default_holo_light</item> </style> <style name="Widget.Holo.Light.ButtonGroup.AlertDialog"> @@ -1682,7 +1706,7 @@ <style name="Widget.Holo.Light.CompoundButton.Star" parent="Widget.CompoundButton.Star"> </style> - <style name="Widget.Holo.Light.TabWidget" parent="Widget.TabWidget"> + <style name="Widget.Holo.Light.TabWidget" parent="Widget.Holo.TabWidget"> </style> <style name="Widget.Holo.Light.WebTextView" parent="Widget.WebTextView"> @@ -1737,6 +1761,7 @@ <style name="Widget.Holo.Light.ActionButton.Overflow"> <item name="android:src">@android:drawable/ic_menu_moreoverflow_holo_light</item> + <item name="android:background">?android:attr/selectableItemBackground</item> </style> <style name="Widget.Holo.Light.ActionBarView_TabView" parent="Widget.ActionBarView_TabView"> diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml index 7f6da2a14246..552e7e5ba01b 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -90,6 +90,7 @@ <item name="buttonStyleToggle">@android:style/Widget.Button.Toggle</item> <item name="groupButtonBackground">@null</item> + <item name="selectableItemBackground">@android:drawable/item_background</item> <!-- List attributes --> <item name="listPreferredItemHeight">64dip</item> @@ -569,7 +570,7 @@ <style name="Theme.IconMenu"> <!-- Menu/item attributes --> <item name="android:itemTextAppearance">@android:style/TextAppearance.Widget.IconMenu.Item</item> - <item name="android:itemBackground">@android:drawable/menu_selector</item> + <item name="android:selectableItemBackground">@android:drawable/menu_selector</item> <item name="android:itemIconDisabledAlpha">?android:attr/disabledAlpha</item> <item name="android:horizontalDivider">@android:drawable/divider_horizontal_dark</item> <item name="android:verticalDivider">@android:drawable/divider_vertical_dark</item> @@ -638,7 +639,7 @@ <item name="colorForeground">@android:color/bright_foreground_holo_dark</item> <item name="colorForegroundInverse">@android:color/bright_foreground_inverse_holo_dark</item> <item name="colorBackground">@android:color/background_holo_dark</item> - <item name="colorBackgroundCacheHint">?android:attr/colorBackground</item> + <item name="colorBackgroundCacheHint">@android:color/transparent</item> <item name="disabledAlpha">0.5</item> <item name="backgroundDimAmount">0.6</item> @@ -698,6 +699,7 @@ <item name="buttonStyleToggle">@android:style/Widget.Holo.Button.Toggle</item> <item name="groupButtonBackground">@android:drawable/group_button_background_holo_dark</item> + <item name="selectableItemBackground">@android:drawable/item_background_holo_dark</item> <!-- List attributes --> <item name="listPreferredItemHeight">64dip</item> @@ -730,7 +732,7 @@ <item name="galleryItemBackground">@android:drawable/gallery_item_background</item> <!-- Window attributes --> - <item name="windowBackground">@android:drawable/screen_background_holo_dark</item> + <item name="windowBackground">@android:drawable/background_holo_dark</item> <item name="windowFrame">@null</item> <item name="windowNoTitle">false</item> <item name="windowFullscreen">false</item> @@ -871,7 +873,7 @@ <item name="colorForeground">@android:color/bright_foreground_holo_light</item> <item name="colorForegroundInverse">@android:color/bright_foreground_inverse_holo_light</item> <item name="colorBackground">@android:color/background_holo_light</item> - <item name="colorBackgroundCacheHint">?android:attr/colorBackground</item> + <item name="colorBackgroundCacheHint">@android:color/transparent</item> <item name="disabledAlpha">0.5</item> <item name="backgroundDimAmount">0.6</item> @@ -931,6 +933,7 @@ <item name="buttonStyleToggle">@android:style/Widget.Holo.Light.Button.Toggle</item> <item name="groupButtonBackground">@android:drawable/group_button_background_holo_light</item> + <item name="selectableItemBackground">@android:drawable/item_background_holo_light</item> <!-- List attributes --> <item name="listPreferredItemHeight">64dip</item> @@ -963,7 +966,7 @@ <item name="galleryItemBackground">@android:drawable/gallery_item_background</item> <!-- Window attributes --> - <item name="windowBackground">@android:drawable/screen_background_holo_light</item> + <item name="windowBackground">@android:drawable/background_holo_light</item> <item name="windowFrame">@null</item> <item name="windowNoTitle">false</item> <item name="windowFullscreen">false</item> @@ -1146,6 +1149,8 @@ <item name="android:windowActionModeOverlay">true</item> <item name="android:colorBackgroundCacheHint">@null</item> + + <item name="android:groupButtonBackground">?android:attr/selectableItemBackground</item> <item name="textAppearance">@android:style/TextAppearance.Holo</item> <item name="textAppearanceInverse">@android:style/TextAppearance.Holo.Inverse</item> @@ -1196,6 +1201,8 @@ <item name="android:colorBackgroundCacheHint">@null</item> + <item name="android:groupButtonBackground">?android:attr/selectableItemBackground</item> + <item name="textAppearance">@android:style/TextAppearance.Holo.Light</item> <item name="textAppearanceInverse">@android:style/TextAppearance.Holo.Light.Inverse</item> </style> diff --git a/docs/html/resources/resources_toc.cs b/docs/html/resources/resources_toc.cs index a1711b51148b..a2c94fe3ccab 100644 --- a/docs/html/resources/resources_toc.cs +++ b/docs/html/resources/resources_toc.cs @@ -85,6 +85,7 @@ </li><?cs /if ?> + <li> <h2><span class="en">More</span> </h2> diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs index fdf4438c6819..d202b50fdcf4 100644 --- a/docs/html/sdk/sdk_toc.cs +++ b/docs/html/sdk/sdk_toc.cs @@ -1,5 +1,5 @@ <?cs if:!sdk.redirect ?> -<ul><?cs +<ul><?cs if:android.whichdoc == "online" ?> <li> <h2> @@ -35,7 +35,7 @@ </a></li> </ul> - </li><?cs + </li><?cs /if ?> <li> <h2> @@ -61,13 +61,13 @@ </li> </ul> <ul> - <li><a href="<?cs var:toroot ?>sdk/android-2.2.html">Android 2.2 Platform</a> <span class="new">new!</span></li> + <li><a href="<?cs var:toroot ?>sdk/android-2.2.html">Android 2.2 Platform</a></li> <li><a href="<?cs var:toroot ?>sdk/android-2.1.html">Android 2.1 Platform</a></li> <li><a href="<?cs var:toroot ?>sdk/android-1.6.html">Android 1.6 Platform</a></li> <li><a href="<?cs var:toroot ?>sdk/android-1.5.html">Android 1.5 Platform</a></li> <li class="toggle-list"> <div><a href="#" onclick="toggle(this.parentNode.parentNode,true); return false;">Older Platforms</a></div> - <ul> + <ul> <li><a href="<?cs var:toroot ?>sdk/android-2.0.1.html">Android 2.0.1 Platform</a></li> <li><a href="<?cs var:toroot ?>sdk/android-2.0.html">Android 2.0 Platform</a></li> <li><a href="<?cs var:toroot ?>sdk/android-1.1.html">Android 1.1 Platform</a></li> @@ -75,8 +75,7 @@ </li> </ul> <ul> - <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r7</a> - <span class="new">new!</span></li> + <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r7</a></li> <li><a href="<?cs var:toroot ?>sdk/win-usb.html">USB Driver for Windows, r3</a> </li> @@ -116,8 +115,7 @@ <span style="display:none" class="zh-TW"></span> </h2> <ul> - <li><a href="<?cs var:toroot ?>sdk/ndk/index.html">Android NDK, r4b</a> - <span class="new">new!</span></li> + <li><a href="<?cs var:toroot ?>sdk/ndk/index.html">Android NDK, r4b</a></li> </ul> </li> <li> diff --git a/docs/html/videos/index.jd b/docs/html/videos/index.jd index 157c0778284d..0274095762e8 100644 --- a/docs/html/videos/index.jd +++ b/docs/html/videos/index.jd @@ -2,7 +2,7 @@ videos=true page.title=Videos @jd:body -<script src="http://swfobject.googlecode.com/svn/trunk/swfobject/swfobject.js" type="text/javascript"></script>
+<script src="http://swfobject.googlecode.com/svn/trunk/swfobject/swfobject.js" type="text/javascript"></script> <script src="{@docRoot}assets/jquery-history.js" type="text/javascript"></script> <script type="text/javascript"> // for debugging in FF, so other browsers ignore the console commands. @@ -33,32 +33,32 @@ var playlists = { */ var playlistsWithTitleInDescription = "734A052F802C96B9"; -/* This 'featured' object defines the Feature Videos list. +/* This 'featured' object defines the Feature Videos list. * Each playlist ID is paired with a custom video description. */ var featured = { -// Android 2.0 Release - 'opZ69P-0Jbc' : "The Android 2.0 platform adds exciting new user features and developer APIs. Here's an introduction to what's new.", -// How to Make your Android UI Fast.. - 'N6YdwzAvwOA' : "Make your user interface fast, with more efficient AdapterViews, better bitmap scaling, faster redrawing, ViewStub layouts, fewer Views, and more.", -// How Do I Code Thee? - 'GARMe7Km_gk' : "If you'd like to augment your Android applications with pieces written in JavaScript or native code, watch this video." +// Android UI design patterns + 'M1ZBjlCRfz0' : "The Android user experience team provides suggestions for how to make your applications more useable and engaging.", +// The world of ListView + 'wDBM6wVEO70' : "ListView is a common widget that's customizable, but can be tricky to polish, so this talk shows how you can provide the best performance.", +// Debugging Arts of the Ninja Masters + 'Dgnx0E7m1GQ' : "The Android SDK includes tools to debug your apps like a ninja. Enter the dojo and become a master at debugging your apps." }; -
+ /* When an event on the browser history occurs (back, forward, load), - * load the video found in the URL hash - */
-$(window).history(function(e, hash) {
- if (location.href.indexOf("#v=") != -1) {
- videoId = location.href.split("#v=");
- clickVideo(videoId[1]); // click the link with a matching class
- }
+ * load the video found in the URL hash + */ +$(window).history(function(e, hash) { + if (location.href.indexOf("#v=") != -1) { + videoId = location.href.split("#v="); + clickVideo(videoId[1]); // click the link with a matching class + } }); /* Load a video into the player box. * @param id The YouTube video ID * @param title The video title to display in the player box (character escaped) - * @param autoplay Whether to automatically play the video + * @param autoplay Whether to automatically play the video */ function loadVideo(id, title, autoplay) { if($("." + id).hasClass("noplay")) { @@ -66,51 +66,51 @@ function loadVideo(id, title, autoplay) { autoplay = false; $("." + id).removeClass("noplay"); } - swfobject.embedSWF('http://www.youtube.com/v/' + id + '&rel=1&border=0&fs=1&autoplay=' + + swfobject.embedSWF('http://www.youtube.com/v/' + id + '&rel=1&border=0&fs=1&autoplay=' + (autoplay?1:0), 'player', '500', '334', '9.0.0', false, false, {allowfullscreen: 'true'}); $("#videoPlayerTitle").html("<h2>" + unescape(title) + "</h2>"); -
+ $.history.add('v=' + id); // add the current video to the browser history - document.getElementById("doc-content").scrollTop = 0; // scroll the window to the top + document.getElementById("doc-content").scrollTop = 0; // scroll the window to the top } /* Draw all videos from a playlist into a 'videoPreviews' list * @param data The feed data returned from the youtube request */ -function renderPlaylist(data) { +function renderPlaylist(data) { var MAX_DESC_LENGTH = 390; // the length at which we will trim the description var feed = data.feed; var entries = feed.entry || []; var playlistId = feed.yt$playlistId.$t; - + var ul = $('<ul class="videoPreviews" />'); - + // Loop through each entry (each video) and add it to the 'videoPreviews' list for (var i = 0; i < entries.length; i++) { var entry = entries[i]; - + var title = entry.title.$t; var id = entry.media$group.yt$videoid.$t; var thumbUrl = entry.media$group.media$thumbnail[0].url; var fullDescription = entry.media$group.media$description.$t; var playerUrl = entry.media$group.media$content[0].url; - + // Check whether this playlist includes the video title inside the description meta-data, so we can remove it if (playlistsWithTitleInDescription.indexOf(playlistId) != -1) { var lines = fullDescription.split("\n"); // If the first line includes the first 17 chars from the title, let's use the title from the description instead (because it's a more complete title) // This accounts for, literally, "Google I/O 2009 -", which is (so far) the min AND max for properly identifying a title in the only playlist with titles in the description - if (lines[0].indexOf(title.slice(0,16)) != -1) { - h3Title = "<h3>" + lines[0] + "</h3>"; + if (lines[0].indexOf(title.slice(0,16)) != -1) { + h3Title = "<h3>" + lines[0] + "</h3>"; if (lines[2].length < 30) lines = lines.slice(3); // also, if the second line is very short (the speaker name), slice it out too else lines = lines.slice(1); // otherwise, slice after the first line } fullDescription = lines.join(""); - } - + } + var shortDescription = fullDescription.substr(0, MAX_DESC_LENGTH); shortDescription += shortDescription.length == MAX_DESC_LENGTH ? "..." : ""; // add ellipsis if we've chopped the description - + var img = $('<img src="' + thumbUrl + '" width="120" height="90"/>'); var a = $('<a class="' + id + '" href="#" onclick="loadVideo(\'' + id + '\',\'' + escape(title) + '\',true); return setSelected(this);" />'); var pShortDescription = $('<p class="short">' + shortDescription + '</p>'); @@ -118,19 +118,19 @@ function renderPlaylist(data) { var h3Title = "<h3>" + title + "</h3>"; var pToggle = "<p class='toggle'><a href='#' onclick='return toggleDescription(this)'><span class='more'>more</span><span class='less'>less</span></a></p>"; var li = $('<li/>'); - + li.append(a); a.append(img).append(h3Title).append(pShortDescription); - + // Add the full description and "more/less" toggle, if necessary if (fullDescription.length > MAX_DESC_LENGTH) { a.append(pFullDescription); li.append(pToggle); } - + ul.append(li); } - + // Now add the 'videoPreviews' list to the page, and be sure we put it in the right tab // This is the part that allows us to put multiple playlists in one tab for (var x in playlists) { @@ -141,13 +141,13 @@ function renderPlaylist(data) { break; } } - } + } } -/* Draw a featured video into the existing 'videoPreviews' list +/* Draw a featured video into the existing 'videoPreviews' list * @param data The video data returned from the youtube request */ -function renderFeatured(data) { +function renderFeatured(data) { var MAX_TITLE_LENGTH = 48; var entry = data.entry || []; var id = entry.media$group.yt$videoid.$t; @@ -155,15 +155,15 @@ function renderFeatured(data) { var title = entry.title.$t; var thumbUrl = entry.media$group.media$thumbnail[0].url; var playerUrl = entry.media$group.media$content[0].url; - + var ellipsis = title.length > MAX_TITLE_LENGTH ? "..." : ""; - + var h3Title = "<h3>"+ title.substr(0,MAX_TITLE_LENGTH) + ellipsis + "</h3>"; var img = $('<img src="' + thumbUrl + '" width="120" height="90"/>'); var p = $('<p>' + description + '</p>'); var a = $('<a class="' + id + '" href="#" onclick="loadVideo(\'' + id + '\',\'' + title + '\',true); return setSelected(this);" />'); var li = $("<li/>"); - + a.append(h3Title).append(img).append(p); li.append(a); @@ -175,8 +175,8 @@ function showPlaylists() { for (var x in playlists) { var ids = playlists[x].ids; for (var i in ids) { - var script = "<script type='text/javascript' src='http://gdata.youtube.com/feeds/api/playlists/" - + ids[i] + + var script = "<script type='text/javascript' src='http://gdata.youtube.com/feeds/api/playlists/" + + ids[i] + "?v=2&alt=json-in-script&callback=renderPlaylist'><\/script>"; $("body").append(script); } @@ -186,14 +186,14 @@ function showPlaylists() { /* Request the featured videos from YouTube */ function showFeatured() { for (var id in featured) { - var script = "<script type='text/javascript' src='http://gdata.youtube.com/feeds/api/videos/" - + id + + var script = "<script type='text/javascript' src='http://gdata.youtube.com/feeds/api/videos/" + + id + "?v=2&alt=json-in-script&callback=renderFeatured'><\/script>"; $("body").append(script); } } -/* Reveal a tab (playlist) box +/* Reveal a tab (playlist) box * @param name The name of the tab */ function showBox(name) { @@ -202,7 +202,7 @@ function showBox(name) { return false; } -/* Highlight a video thumbnail, including all duplicates that there may be +/* Highlight a video thumbnail, including all duplicates that there may be * @param link The link <a> object that was clicked */ function setSelected(link) { @@ -220,8 +220,8 @@ function setSelected(link) { return false; } -/* Reveal and hide the long/short descriptions for a video in the playlist - * @param link The link <a> object that was clicked +/* Reveal and hide the long/short descriptions for a video in the playlist + * @param link The link <a> object that was clicked */ function toggleDescription(link) { var aToggle = $(link); @@ -238,9 +238,9 @@ function toggleDescription(link) { } /* Add actions to the page onload event so that we load a video right away */ -addLoadEvent(function () {
- // if there's a video url in the hash, click that video
- if (location.href.indexOf("#v=") != -1) {
+addLoadEvent(function () { + // if there's a video url in the hash, click that video + if (location.href.indexOf("#v=") != -1) { var videoId = location.href.split("#v="); clickVideo(videoId[1]); } else { // otherwise, click the default video @@ -251,20 +251,20 @@ addLoadEvent(function () { var clickVideoAttempts = 0; // Used with clickVideo() -/* Click a video in order to load it and select it +/* Click a video in order to load it and select it * @param videoId The ID of the video to click */ function clickVideo(videoId) { if ($("." + videoId).length != 0) { // if we find the video, click it and return - $("." + videoId).addClass("noplay"); // add class to indicate we should NOT autoplay (class removed by loadVideo)
+ $("." + videoId).addClass("noplay"); // add class to indicate we should NOT autoplay (class removed by loadVideo) $("." + videoId + ":first").click(); return; } else { // if we don't find it, increment clickVideoAttempts console.log("video NOT found: " + videoId); clickVideoAttempts++; } - - // if we don't find it after 20 attempts (2 seconds), click the first feature video
+ + // if we don't find it after 20 attempts (2 seconds), click the first feature video if (clickVideoAttempts > 10) { console.log("video never found, clicking default..."); clickVideoAttempts = 0; @@ -278,15 +278,15 @@ function clickVideo(videoId) { function clickDefaultVideo() { if ($("#mainBodyRight .videoPreviews a:first").length != 0) { var videoId = $("#mainBodyRight .videoPreviews a:first").attr("class"); - $("." + videoId).addClass("noplay"); // add class to indicate we should NOT autoplay (class removed by loadVideo)
+ $("." + videoId).addClass("noplay"); // add class to indicate we should NOT autoplay (class removed by loadVideo) $("." + videoId + ":first").click(); return; } else { // if we don't find it, increment clickVideoAttempts console.log("default video NOT found"); clickVideoAttempts++; } - - // if we don't find it after 50 attempts (5 seconds), just fail
+ + // if we don't find it after 50 attempts (5 seconds), just fail if (clickVideoAttempts > 50) { console.log("default video never found..."); } else { // try again after 100 milliseconds @@ -296,8 +296,8 @@ function clickDefaultVideo() { </script> <div id="mainBodyFixed"> - - <div id="mainBodyLeft" class="videoPlayer" > + + <div id="mainBodyLeft" class="videoPlayer" > <div id="videoPlayerBox"> <div id="videoBorder"> <div id="videoPlayerTitle"></div> @@ -307,32 +307,32 @@ function clickDefaultVideo() { </div> </div> </div><!-- end mainBodyLeft --> - + <div id="mainBodyRight" class="videoPlayer"> <h2>Featured Videos</h2> <ul class="videoPreviews"></ul> </div><!-- end mainBodyRight --> - + <ul id="videoTabs"> <li id="aboutTab" class="selected"><a onclick="return showBox('about');" href="#">About the Platform</a></li> <li id="developertipsTab"><a onclick="return showBox('developertips');" href="#">Developer Tips</a></li> <li id="googleioTab"><a onclick="return showBox('googleio');" href="#">Google I/O Sessions</a></li> <li id="developersandboxTab"><a onclick="return showBox('developersandbox');" href="#">Developer Sandbox</a></li> </ul> - + <div id="videos"> <div id="aboutBox" class="selected"></div> <div id="developertipsBox"></div> <div id="googleioBox"></div> <div id="developersandboxBox"></div> </div> - + </div><!-- end mainBodyFixed --> - + <script type="text/javascript"> // Initialization actions showFeatured(); // load featured videos showPlaylists(); // load playlists </script> - + diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h index 6fef2e706130..0f4fbfb1d195 100644 --- a/include/media/stagefright/OMXCodec.h +++ b/include/media/stagefright/OMXCodec.h @@ -39,6 +39,11 @@ struct OMXCodec : public MediaSource, // The client wants to access the output buffer's video // data for example for thumbnail extraction. kClientNeedsFramebuffer = 4, + + // Request for software or hardware codecs. If request + // can not be fullfilled, Create() returns NULL. + kSoftwareCodecsOnly = 8, + kHardwareCodecsOnly = 16, }; static sp<MediaSource> Create( const sp<IOMX> &omx, diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index a4def0ba78b4..e0094d8245db 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -43,7 +43,7 @@ Caches::Caches(): Singleton<Caches>(), blend(false), lastSrcMode(GL_ZERO), glBindBuffer(GL_ARRAY_BUFFER, meshBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(gMeshVertices), gMeshVertices, GL_STATIC_DRAW); - currentBuffer = meshBuffer; + mCurrentBuffer = meshBuffer; } /** @@ -57,9 +57,9 @@ void Caches::bindMeshBuffer() { * Binds the specified VBO. */ void Caches::bindMeshBuffer(const GLuint buffer) { - if (currentBuffer != buffer) { + if (mCurrentBuffer != buffer) { glBindBuffer(GL_ARRAY_BUFFER, buffer); - currentBuffer = buffer; + mCurrentBuffer = buffer; } } @@ -67,9 +67,9 @@ void Caches::bindMeshBuffer(const GLuint buffer) { * Unbinds the VBO used to render simple textured quads. */ void Caches::unbindMeshBuffer() { - if (currentBuffer) { + if (mCurrentBuffer) { glBindBuffer(GL_ARRAY_BUFFER, 0); - currentBuffer = 0; + mCurrentBuffer = 0; } } diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index 79644a55d0bf..aff536620daa 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -79,7 +79,9 @@ class Caches: public Singleton<Caches> { friend class Singleton<Caches>; - CacheLogger logger; + CacheLogger mlogger; + + GLuint mCurrentBuffer; public: void bindMeshBuffer(); @@ -92,7 +94,6 @@ public: Program* currentProgram; GLuint meshBuffer; - GLuint currentBuffer; TextureCache textureCache; LayerCache layerCache; diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index a43f164ee8f1..a9cd5be5ff85 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -108,18 +108,7 @@ DisplayList::DisplayList(const DisplayListRenderer& recorder) { mBitmapResources.add(resource); caches.resourceCache.incrementRefcount(resource); } - const Vector<SkMatrix*> &matrixResources = recorder.getMatrixResources(); - for (size_t i = 0; i < matrixResources.size(); i++) { - SkMatrix* resource = matrixResources.itemAt(i); - mMatrixResources.add(resource); - caches.resourceCache.incrementRefcount(resource); - } - const Vector<SkPaint*> &paintResources = recorder.getPaintResources(); - for (size_t i = 0; i < paintResources.size(); i++) { - SkPaint* resource = paintResources.itemAt(i); - mPaintResources.add(resource); - caches.resourceCache.incrementRefcount(resource); - } + const Vector<SkiaShader*> &shaderResources = recorder.getShaderResources(); for (size_t i = 0; i < shaderResources.size(); i++) { SkiaShader* resource = shaderResources.itemAt(i); @@ -127,6 +116,16 @@ DisplayList::DisplayList(const DisplayListRenderer& recorder) { caches.resourceCache.incrementRefcount(resource); } + const Vector<SkPaint*> &paints = recorder.getPaints(); + for (size_t i = 0; i < paints.size(); i++) { + mPaints.add(paints.itemAt(i)); + } + + const Vector<SkMatrix*> &matrices = recorder.getMatrices(); + for (size_t i = 0; i < matrices.size(); i++) { + mMatrices.add(matrices.itemAt(i)); + } + mPathHeap = recorder.mPathHeap; mPathHeap->safeRef(); } @@ -137,25 +136,25 @@ DisplayList::~DisplayList() { Caches& caches = Caches::getInstance(); for (size_t i = 0; i < mBitmapResources.size(); i++) { - SkBitmap* resource = mBitmapResources.itemAt(i); - caches.resourceCache.decrementRefcount(resource); + caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i)); } mBitmapResources.clear(); - for (size_t i = 0; i < mMatrixResources.size(); i++) { - SkMatrix* resource = mMatrixResources.itemAt(i); - caches.resourceCache.decrementRefcount(resource); - } - mMatrixResources.clear(); - for (size_t i = 0; i < mPaintResources.size(); i++) { - SkPaint* resource = mPaintResources.itemAt(i); - caches.resourceCache.decrementRefcount(resource); - } - mPaintResources.clear(); + for (size_t i = 0; i < mShaderResources.size(); i++) { - SkiaShader* resource = mShaderResources.itemAt(i); - caches.resourceCache.decrementRefcount(resource); + caches.resourceCache.decrementRefcount(mShaderResources.itemAt(i)); } mShaderResources.clear(); + + for (size_t i = 0; i < mPaints.size(); i++) { + delete mPaints.itemAt(i); + } + mPaints.clear(); + + for (size_t i = 0; i < mMatrices.size(); i++) { + delete mMatrices.itemAt(i); + } + mMatrices.clear(); + mPathHeap->safeUnref(); } @@ -335,21 +334,16 @@ void DisplayListRenderer::reset() { caches.resourceCache.decrementRefcount(resource); } mBitmapResources.clear(); - for (size_t i = 0; i < mMatrixResources.size(); i++) { - SkMatrix* resource = mMatrixResources.itemAt(i); - caches.resourceCache.decrementRefcount(resource); - } - mMatrixResources.clear(); - for (size_t i = 0; i < mPaintResources.size(); i++) { - SkPaint* resource = mPaintResources.itemAt(i); - caches.resourceCache.decrementRefcount(resource); - } - mPaintResources.clear(); + for (size_t i = 0; i < mShaderResources.size(); i++) { SkiaShader* resource = mShaderResources.itemAt(i); caches.resourceCache.decrementRefcount(resource); } mShaderResources.clear(); + + mPaints.clear(); + mPaintMap.clear(); + mMatrices.clear(); } /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index c8cd8017e9cd..ce4cfc556984 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -182,10 +182,11 @@ private: PathHeap* mPathHeap; Vector<SkBitmap*> mBitmapResources; - Vector<SkMatrix*> mMatrixResources; - Vector<SkPaint*> mPaintResources; Vector<SkiaShader*> mShaderResources; + Vector<SkPaint*> mPaints; + Vector<SkMatrix*> mMatrices; + mutable SkFlattenableReadBuffer mReader; SkRefCntPlayback mRCPlayback; @@ -263,16 +264,16 @@ public: return mBitmapResources; } - const Vector<SkMatrix*>& getMatrixResources() const { - return mMatrixResources; + const Vector<SkiaShader*>& getShaderResources() const { + return mShaderResources; } - const Vector<SkPaint*>& getPaintResources() const { - return mPaintResources; + const Vector<SkPaint*>& getPaints() const { + return mPaints; } - const Vector<SkiaShader*>& getShaderResources() const { - return mShaderResources; + const Vector<SkMatrix*>& getMatrices() const { + return mMatrices; } private: @@ -334,20 +335,30 @@ private: } inline void addPaint(SkPaint* paint) { - addInt((int)paint); - mPaintResources.add(paint); - Caches& caches = Caches::getInstance(); - caches.resourceCache.incrementRefcount(paint); + if (paint == NULL) { + addInt((int)NULL); + return; + } + SkPaint *paintCopy = mPaintMap.valueFor(paint); + if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) { + paintCopy = new SkPaint(*paint); + mPaintMap.add(paint, paintCopy); + mPaints.add(paintCopy); + } + addInt((int)paintCopy); } inline void addMatrix(SkMatrix* matrix) { - addInt((int)matrix); - mMatrixResources.add(matrix); - Caches& caches = Caches::getInstance(); - caches.resourceCache.incrementRefcount(matrix); + // Copying the matrix is cheap and prevents against the user changing the original + // matrix before the operation that uses it + addInt((int) new SkMatrix(*matrix)); } inline void addBitmap(SkBitmap* bitmap) { + // Note that this assumes the bitmap is immutable. There are cases this won't handle + // correctly, such as creating the bitmap from scratch, drawing with it, changing its + // contents, and drawing again. The only fix would be to always copy it the first time, + // which doesn't seem worth the extra cycles for this unlikely case. addInt((int)bitmap); mBitmapResources.add(bitmap); Caches& caches = Caches::getInstance(); @@ -364,10 +375,12 @@ private: SkChunkAlloc mHeap; Vector<SkBitmap*> mBitmapResources; - Vector<SkMatrix*> mMatrixResources; - Vector<SkPaint*> mPaintResources; Vector<SkiaShader*> mShaderResources; + Vector<SkPaint*> mPaints; + DefaultKeyedVector<SkPaint *, SkPaint *> mPaintMap; + Vector<SkMatrix*> mMatrices; + PathHeap* mPathHeap; SkWriter32 mWriter; diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 7495a068f50c..859251186b28 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -644,7 +644,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint } glActiveTexture(GL_TEXTURE0); - const Texture* texture = mCaches.textureCache.get(bitmap); + Texture* texture = mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); @@ -661,7 +661,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* pai } glActiveTexture(GL_TEXTURE0); - const Texture* texture = mCaches.textureCache.get(bitmap); + Texture* texture = mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); @@ -677,9 +677,10 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, } glActiveTexture(GL_TEXTURE0); - const Texture* texture = mCaches.textureCache.get(bitmap); + Texture* texture = mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); + setTextureWrapModes(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); const float width = texture->width; const float height = texture->height; @@ -711,9 +712,10 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int } glActiveTexture(GL_TEXTURE0); - const Texture* texture = mCaches.textureCache.get(bitmap); + Texture* texture = mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); + setTextureWrapModes(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); int alpha; SkXfermode::Mode mode; @@ -1046,7 +1048,7 @@ void OpenGLRenderer::setupTextureAlpha8(GLuint texture, uint32_t width, uint32_t // Build and use the appropriate shader useProgram(mCaches.programCache.get(description)); - bindTexture(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, textureUnit); + bindTexture(texture, textureUnit); glUniform1i(mCaches.currentProgram->getUniform("sampler"), textureUnit); int texCoordsSlot = mCaches.currentProgram->getAttrib("texCoords"); @@ -1220,11 +1222,13 @@ void OpenGLRenderer::setupColorRect(float left, float top, float right, float bo } void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom, - const Texture* texture, SkPaint* paint) { + Texture* texture, SkPaint* paint) { int alpha; SkXfermode::Mode mode; getAlphaAndMode(paint, &alpha, &mode); + setTextureWrapModes(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); + drawTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f, mode, texture->blend, (GLvoid*) NULL, (GLvoid*) gMeshTextureOffset, GL_TRIANGLE_STRIP, gMeshCount); @@ -1263,7 +1267,7 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b } // Texture - bindTexture(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, 0); + bindTexture(texture); glUniform1i(mCaches.currentProgram->getUniform("sampler"), 0); // Always premultiplied @@ -1380,11 +1384,29 @@ SkXfermode::Mode OpenGLRenderer::getXfermode(SkXfermode* mode) { return mode->fMode; } -void OpenGLRenderer::bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit) { +void OpenGLRenderer::bindTexture(GLuint texture, GLuint textureUnit) { glActiveTexture(gTextureUnits[textureUnit]); glBindTexture(GL_TEXTURE_2D, texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT); +} + +void OpenGLRenderer::setTextureWrapModes(Texture* texture, GLenum wrapS, GLenum wrapT, + GLuint textureUnit) { + bool bound = false; + if (wrapS != texture->wrapS) { + glActiveTexture(gTextureUnits[textureUnit]); + glBindTexture(GL_TEXTURE_2D, texture->id); + bound = true; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS); + texture->wrapS = wrapS; + } + if (wrapT != texture->wrapT) { + if (!bound) { + glActiveTexture(gTextureUnits[textureUnit]); + glBindTexture(GL_TEXTURE_2D, texture->id); + } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT); + texture->wrapT = wrapT; + } } }; // namespace uirenderer diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index b7615fe59375..07188d4c59f8 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -231,7 +231,7 @@ private: * @param paint The paint containing the alpha, blending mode, etc. */ void drawTextureRect(float left, float top, float right, float bottom, - const Texture* texture, SkPaint* paint); + Texture* texture, SkPaint* paint); /** * Draws a textured mesh with the specified texture. If the indices are omitted, @@ -360,9 +360,11 @@ private: inline void getAlphaAndMode(SkPaint* paint, int* alpha, SkXfermode::Mode* mode); /** - * Binds the specified texture with the specified wrap modes. + * Binds the specified texture to the specified texture unit. */ - inline void bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit = 0); + inline void bindTexture(GLuint texture, GLuint textureUnit = 0); + inline void setTextureWrapModes(Texture* texture, GLenum wrapS, GLenum wrapT, + GLuint textureUnit = 0); /** * Enable or disable blending as necessary. This function sets the appropriate diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp index 253a19ba77ff..3d21431bfd8d 100644 --- a/libs/hwui/Patch.cpp +++ b/libs/hwui/Patch.cpp @@ -26,8 +26,6 @@ namespace android { namespace uirenderer { -class Caches; - /////////////////////////////////////////////////////////////////////////////// // Constructors/destructor /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp index 20b8d6ce5b83..b0fbe65339bb 100644 --- a/libs/hwui/ResourceCache.cpp +++ b/libs/hwui/ResourceCache.cpp @@ -62,14 +62,6 @@ void ResourceCache::incrementRefcount(SkBitmap* bitmapResource) { incrementRefcount((void*)bitmapResource, kBitmap); } -void ResourceCache::incrementRefcount(SkMatrix* matrixResource) { - incrementRefcount((void*)matrixResource, kMatrix); -} - -void ResourceCache::incrementRefcount(SkPaint* paintResource) { - incrementRefcount((void*)paintResource, kPaint); -} - void ResourceCache::incrementRefcount(SkiaShader* shaderResource) { shaderResource->getSkShader()->safeRef(); incrementRefcount((void*)shaderResource, kShader); @@ -136,34 +128,6 @@ void ResourceCache::destructor(SkBitmap* resource) { } } -void ResourceCache::destructor(SkMatrix* resource) { - ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; - if (ref == NULL) { - // If we're not tracking this resource, just delete it - delete resource; - return; - } - ref->destroyed = true; - if (ref->refCount == 0) { - deleteResourceReference(resource, ref); - return; - } -} - -void ResourceCache::destructor(SkPaint* resource) { - ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; - if (ref == NULL) { - // If we're not tracking this resource, just delete it - delete resource; - return; - } - ref->destroyed = true; - if (ref->refCount == 0) { - deleteResourceReference(resource, ref); - return; - } -} - void ResourceCache::destructor(SkiaShader* resource) { ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; if (ref == NULL) { @@ -196,12 +160,6 @@ void ResourceCache::deleteResourceReference(void* resource, ResourceReference* r delete bitmap; } break; - case kMatrix: - delete (SkMatrix*) resource; - break; - case kPaint: - delete (SkPaint*) resource; - break; case kShader: SkiaShader* shader = (SkiaShader*)resource; if (Caches::hasInstance()) { diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h index cda27188fe10..b5503674490b 100644 --- a/libs/hwui/ResourceCache.h +++ b/libs/hwui/ResourceCache.h @@ -18,8 +18,6 @@ #define ANDROID_UI_RESOURCE_CACHE_H #include <SkBitmap.h> -#include <SkMatrix.h> -#include <SkPaint.h> #include <SkiaShader.h> #include <utils/KeyedVector.h> @@ -31,8 +29,6 @@ namespace uirenderer { */ enum ResourceType { kBitmap, - kMatrix, - kPaint, kShader, }; @@ -56,8 +52,6 @@ public: ResourceCache(); ~ResourceCache(); void incrementRefcount(SkBitmap* resource); - void incrementRefcount(SkMatrix* resource); - void incrementRefcount(SkPaint* resource); void incrementRefcount(SkiaShader* resource); void incrementRefcount(const void* resource, ResourceType resourceType); void decrementRefcount(void* resource); @@ -66,8 +60,6 @@ public: void recycle(void* resource); void recycle(SkBitmap* resource); void destructor(SkBitmap* resource); - void destructor(SkMatrix* resource); - void destructor(SkPaint* resource); void destructor(SkiaShader* resource); private: void deleteResourceReference(void* resource, ResourceReference* ref); diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp index fa85d20ed3a4..e7e118755c49 100644 --- a/libs/hwui/SkiaShader.cpp +++ b/libs/hwui/SkiaShader.cpp @@ -63,11 +63,17 @@ void SkiaShader::setupProgram(Program* program, const mat4& modelView, const Sna GLuint* textureUnit) { } -void SkiaShader::bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit) { +void SkiaShader::bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit) { glActiveTexture(gTextureUnitsMap[textureUnit]); - glBindTexture(GL_TEXTURE_2D, texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT); + glBindTexture(GL_TEXTURE_2D, texture->id); + if (wrapS != texture->wrapS) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS); + texture->wrapS = wrapS; + } + if (wrapT != texture->wrapT) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT); + texture->wrapT = wrapT; + } } void SkiaShader::computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView) { @@ -86,7 +92,7 @@ SkiaBitmapShader::SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::Ti } void SkiaBitmapShader::describe(ProgramDescription& description, const Extensions& extensions) { - const Texture* texture = mTextureCache->get(mBitmap); + Texture* texture = mTextureCache->get(mBitmap); if (!texture) return; mTexture = texture; @@ -114,7 +120,7 @@ void SkiaBitmapShader::setupProgram(Program* program, const mat4& modelView, GLuint textureSlot = (*textureUnit)++; glActiveTexture(gTextureUnitsMap[textureSlot]); - const Texture* texture = mTexture; + Texture* texture = mTexture; mTexture = NULL; if (!texture) return; const AutoTexture autoCleanup(texture); @@ -126,7 +132,7 @@ void SkiaBitmapShader::setupProgram(Program* program, const mat4& modelView, computeScreenSpaceMatrix(textureTransform, modelView); // Uniforms - bindTexture(texture->id, mWrapS, mWrapT, textureSlot); + bindTexture(texture, mWrapS, mWrapT, textureSlot); glUniform1i(program->getUniform("bitmapSampler"), textureSlot); glUniformMatrix4fv(program->getUniform("textureTransform"), 1, GL_FALSE, &textureTransform.data[0]); @@ -198,7 +204,7 @@ void SkiaLinearGradientShader::setupProgram(Program* program, const mat4& modelV computeScreenSpaceMatrix(screenSpace, modelView); // Uniforms - bindTexture(texture->id, gTileModes[mTileX], gTileModes[mTileY], textureSlot); + bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY], textureSlot); glUniform1i(program->getUniform("gradientSampler"), textureSlot); glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); } @@ -291,7 +297,7 @@ void SkiaSweepGradientShader::setupProgram(Program* program, const mat4& modelVi computeScreenSpaceMatrix(screenSpace, modelView); // Uniforms - bindTexture(texture->id, gTileModes[mTileX], gTileModes[mTileY], textureSlot); + bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY], textureSlot); glUniform1i(program->getUniform("gradientSampler"), textureSlot); glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); } diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h index 011991a1e9f3..4cd1b8b27f85 100644 --- a/libs/hwui/SkiaShader.h +++ b/libs/hwui/SkiaShader.h @@ -97,7 +97,7 @@ struct SkiaShader { void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView); protected: - inline void bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit); + inline void bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit); Type mType; SkShader* mKey; @@ -138,7 +138,7 @@ private: } SkBitmap* mBitmap; - const Texture* mTexture; + Texture* mTexture; GLenum mWrapS; GLenum mWrapT; }; // struct SkiaBitmapShader diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h index 817f1436bd3c..755074d674f6 100644 --- a/libs/hwui/Texture.h +++ b/libs/hwui/Texture.h @@ -29,6 +29,8 @@ struct Texture { Texture() { cleanup = false; bitmapSize = 0; + wrapS = GL_CLAMP_TO_EDGE; + wrapT = GL_CLAMP_TO_EDGE; } /** @@ -59,6 +61,12 @@ struct Texture { * Optional, size of the original bitmap. */ uint32_t bitmapSize; + + /** + * Last wrap modes set on this texture. Defaults to GL_CLAMP_TO_EDGE. + */ + GLenum wrapS; + GLenum wrapT; }; // struct Texture class AutoTexture { diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp index 701df8358964..d860953bc247 100644 --- a/libs/hwui/TextureCache.cpp +++ b/libs/hwui/TextureCache.cpp @@ -94,6 +94,8 @@ void TextureCache::operator()(SkBitmap*& bitmap, Texture*& texture) { // This will be called already locked if (texture) { mSize -= texture->bitmapSize; + TEXTURE_LOGD("TextureCache::callback: removed size, mSize = %d, %d", + texture->bitmapSize, mSize); glDeleteTextures(1, &texture->id); delete texture; } @@ -131,6 +133,8 @@ Texture* TextureCache::get(SkBitmap* bitmap) { if (size < mMaxSize) { mLock.lock(); mSize += size; + TEXTURE_LOGD("TextureCache::get: create texture(0x%p): size, mSize = %d, %d", + bitmap, size, mSize); mCache.put(bitmap, texture); mLock.unlock(); } else { @@ -151,6 +155,7 @@ void TextureCache::remove(SkBitmap* bitmap) { void TextureCache::clear() { Mutex::Autolock _l(mLock); mCache.clear(); + TEXTURE_LOGD("TextureCache:clear(), miSize = %d", mSize); } void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool regenerate) { diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h index 467e851f7200..671859716d82 100644 --- a/libs/hwui/TextureCache.h +++ b/libs/hwui/TextureCache.h @@ -25,6 +25,20 @@ namespace android { namespace uirenderer { +/////////////////////////////////////////////////////////////////////////////// +// Defines +/////////////////////////////////////////////////////////////////////////////// + +// Debug +#define DEBUG_TEXTURES 0 + +// Debug +#if DEBUG_TEXTURES + #define TEXTURE_LOGD(...) LOGD(__VA_ARGS__) +#else + #define TEXTURE_LOGD(...) +#endif + /** * A simple LRU texture cache. The cache has a maximum size expressed in bytes. * Any texture added to the cache causing the cache to grow beyond the maximum diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp index 629234b2682c..4c86ebe0f5e1 100644 --- a/libs/ui/InputDispatcher.cpp +++ b/libs/ui/InputDispatcher.cpp @@ -1163,7 +1163,10 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, // If the pointer is not currently down, then ignore the event. if (! mTempTouchState.down) { - LOGI("Dropping event because the pointer is not down."); +#if DEBUG_INPUT_DISPATCHER_POLICY + LOGD("Dropping event because the pointer is not down or we previously " + "dropped the pointer down event."); +#endif injectionResult = INPUT_EVENT_INJECTION_FAILED; goto Failed; } @@ -2775,7 +2778,7 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) { dump.append(INDENT "ActiveConnections:\n"); for (size_t i = 0; i < mActiveConnections.size(); i++) { const Connection* connection = mActiveConnections[i]; - dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u" + dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u, " "inputState.isNeutral=%s\n", i, connection->getInputChannelName(), connection->getStatusLabel(), connection->outboundQueue.count(), diff --git a/media/java/android/media/videoeditor/VideoEditorTestImpl.java b/media/java/android/media/videoeditor/VideoEditorTestImpl.java index f4842b528902..505b93e9f97f 100644 --- a/media/java/android/media/videoeditor/VideoEditorTestImpl.java +++ b/media/java/android/media/videoeditor/VideoEditorTestImpl.java @@ -1155,12 +1155,18 @@ public class VideoEditorTestImpl implements VideoEditor { private void removeAdjacentTransitions(MediaItem mediaItem) { final Transition beginTransition = mediaItem.getBeginTransition(); if (beginTransition != null) { + if (beginTransition.getAfterMediaItem() != null) { + beginTransition.getAfterMediaItem().setEndTransition(null); + } beginTransition.invalidate(); mTransitions.remove(beginTransition); } final Transition endTransition = mediaItem.getEndTransition(); if (endTransition != null) { + if (endTransition.getBeforeMediaItem() != null) { + endTransition.getBeforeMediaItem().setBeginTransition(null); + } endTransition.invalidate(); mTransitions.remove(endTransition); } diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp index ec2449d5300e..913d953bd976 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.cpp +++ b/media/libmediaplayerservice/StagefrightRecorder.cpp @@ -165,7 +165,8 @@ status_t StagefrightRecorder::setVideoSize(int width, int height) { status_t StagefrightRecorder::setVideoFrameRate(int frames_per_second) { LOGV("setVideoFrameRate: %d", frames_per_second); - if (frames_per_second <= 0 || frames_per_second > 30) { + if ((frames_per_second <= 0 && frames_per_second != -1) || + frames_per_second > 120) { LOGE("Invalid video frame rate: %d", frames_per_second); return BAD_VALUE; } @@ -960,7 +961,7 @@ void StagefrightRecorder::clipVideoFrameRate() { "enc.vid.fps.min", mVideoEncoder); int maxFrameRate = mEncoderProfiles->getVideoEncoderParamByName( "enc.vid.fps.max", mVideoEncoder); - if (mFrameRate < minFrameRate) { + if (mFrameRate < minFrameRate && mFrameRate != -1) { LOGW("Intended video encoding frame rate (%d fps) is too small" " and will be set to (%d fps)", mFrameRate, minFrameRate); mFrameRate = minFrameRate; @@ -1035,6 +1036,10 @@ void StagefrightRecorder::clipVideoFrameHeight() { } status_t StagefrightRecorder::setupCameraSource(sp<CameraSource> *cameraSource) { + status_t err = OK; + if ((err = checkVideoEncoderCapabilities()) != OK) { + return err; + } Size videoSize; videoSize.width = mVideoWidth; videoSize.height = mVideoHeight; @@ -1050,6 +1055,18 @@ status_t StagefrightRecorder::setupCameraSource(sp<CameraSource> *cameraSource) } CHECK(*cameraSource != NULL); + // When frame rate is not set, the actual frame rate will be set to + // the current frame rate being used. + if (mFrameRate == -1) { + int32_t frameRate = 0; + CHECK ((*cameraSource)->getFormat()->findInt32( + kKeySampleRate, &frameRate)); + LOGI("Frame rate is not explicitly set. Use the current frame " + "rate (%d fps)", frameRate); + mFrameRate = frameRate; + } + + CHECK(mFrameRate != -1); return OK; } @@ -1371,7 +1388,7 @@ status_t StagefrightRecorder::reset() { mVideoHeight = 144; mAuxVideoWidth = 176; mAuxVideoHeight = 144; - mFrameRate = 20; + mFrameRate = -1; mVideoBitRate = 192000; mAuxVideoBitRate = 192000; mSampleRate = 8000; diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp index 95afb1d8cf59..159d937576c2 100644 --- a/media/libstagefright/CameraSource.cpp +++ b/media/libstagefright/CameraSource.cpp @@ -313,6 +313,20 @@ status_t CameraSource::configureCamera( } if (frameRate != -1) { + CHECK(frameRate > 0 && frameRate <= 120); + const char* supportedFrameRates = + params->get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES); + CHECK(supportedFrameRates != NULL); + LOGV("Supported frame rates: %s", supportedFrameRates); + char buf[4]; + snprintf(buf, 4, "%d", frameRate); + if (strstr(supportedFrameRates, buf) == NULL) { + LOGE("Requested frame rate (%d) is not supported: %s", + frameRate, supportedFrameRates); + return BAD_VALUE; + } + + // The frame rate is supported, set the camera to the requested value. params->setPreviewFrameRate(frameRate); isCameraParamChanged = true; } else { // frameRate == -1 @@ -517,6 +531,7 @@ status_t CameraSource::init( mMeta->setInt32(kKeyHeight, mVideoSize.height); mMeta->setInt32(kKeyStride, mVideoSize.width); mMeta->setInt32(kKeySliceHeight, mVideoSize.height); + mMeta->setInt32(kKeySampleRate, mVideoFrameRate); return OK; } diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp index be23c60f9099..ea5577d9d93d 100644 --- a/media/libstagefright/DataSource.cpp +++ b/media/libstagefright/DataSource.cpp @@ -105,7 +105,7 @@ void DataSource::RegisterDefaultSniffers() { RegisterSniffer(SniffAMR); RegisterSniffer(SniffMPEG2TS); RegisterSniffer(SniffMP3); - RegisterSniffer(SniffDRM); + //RegisterSniffer(SniffDRM); } // static diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 2e368b60ce98..0d8abe2f0c5f 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -156,19 +156,15 @@ static const CodecInfo kDecoderInfo[] = { // { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.Nvidia.mp3.decoder" }, // { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" }, { MEDIA_MIMETYPE_AUDIO_MPEG, "MP3Decoder" }, -// { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.PV.mp3dec" }, // { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.decode" }, // { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.Nvidia.amr.decoder" }, { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBDecoder" }, -// { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrdec" }, // { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.Nvidia.amrwb.decoder" }, { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" }, { MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBDecoder" }, -// { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.PV.amrdec" }, // { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.Nvidia.aac.decoder" }, { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.decode" }, { MEDIA_MIMETYPE_AUDIO_AAC, "AACDecoder" }, -// { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacdec" }, { MEDIA_MIMETYPE_AUDIO_G711_ALAW, "G711Decoder" }, { MEDIA_MIMETYPE_AUDIO_G711_MLAW, "G711Decoder" }, // { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.Nvidia.mp4.decode" }, @@ -177,20 +173,17 @@ static const CodecInfo kDecoderInfo[] = { { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.SEC.MPEG4.Decoder" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH263Decoder" }, -// { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4dec" }, // { MEDIA_MIMETYPE_VIDEO_H263, "OMX.Nvidia.h263.decode" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.7x30.video.decoder.h263" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.SEC.H263.Decoder" }, { MEDIA_MIMETYPE_VIDEO_H263, "M4vH263Decoder" }, -// { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263dec" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.Nvidia.h264.decode" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.7x30.video.decoder.avc" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.SEC.AVC.Decoder" }, { MEDIA_MIMETYPE_VIDEO_AVC, "AVCDecoder" }, -// { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcdec" }, { MEDIA_MIMETYPE_AUDIO_VORBIS, "VorbisDecoder" }, { MEDIA_MIMETYPE_VIDEO_VPX, "VPXDecoder" }, }; @@ -202,28 +195,24 @@ static const CodecInfo kEncoderInfo[] = { { MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBEncoder" }, { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.encode" }, { MEDIA_MIMETYPE_AUDIO_AAC, "AACEncoder" }, -// { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacenc" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.7x30.video.encoder.mpeg4" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.encoder.mpeg4" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.encoder" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.Nvidia.mp4.encoder" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.SEC.MPEG4.Encoder" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH263Encoder" }, -// { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4enc" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.7x30.video.encoder.h263" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.encoder.h263" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.encoder" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.Nvidia.h263.encoder" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.SEC.H263.Encoder" }, { MEDIA_MIMETYPE_VIDEO_H263, "M4vH263Encoder" }, -// { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263enc" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.7x30.video.encoder.avc" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.encoder.avc" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.encoder" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.Nvidia.h264.encoder" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.SEC.AVC.Encoder" }, { MEDIA_MIMETYPE_VIDEO_AVC, "AVCEncoder" }, -// { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcenc" }, }; #undef OPTIONAL @@ -318,16 +307,15 @@ static void InitOMXParams(T *params) { } static bool IsSoftwareCodec(const char *componentName) { - if (!strncmp("OMX.PV.", componentName, 7)) { - return true; + if (!strncmp("OMX.", componentName, 4)) { + return false; } - return false; + return true; } // A sort order in which non-OMX components are first, -// followed by software codecs, i.e. OMX.PV.*, followed -// by all the others. +// followed by software codecs, and followed by all the others. static int CompareSoftwareCodecsFirst( const String8 *elem1, const String8 *elem2) { bool isNotOMX1 = strncmp(elem1->string(), "OMX.", 4); @@ -368,9 +356,6 @@ uint32_t OMXCodec::getComponentQuirks( quirks |= kDecoderLiesAboutNumberOfChannels; } - if (!strcmp(componentName, "OMX.PV.avcdec")) { - quirks |= kWantsNALFragments; - } if (!strcmp(componentName, "OMX.TI.MP3.decode")) { quirks |= kNeedsFlushBeforeDisable; quirks |= kDecoderLiesAboutNumberOfChannels; @@ -465,7 +450,16 @@ void OMXCodec::findMatchingCodecs( continue; } - matchingCodecs->push(String8(componentName)); + // When requesting software-only codecs, only push software codecs + // When requesting hardware-only codecs, only push hardware codecs + // When there is request neither for software-only nor for + // hardware-only codecs, push all codecs + if (((flags & kSoftwareCodecsOnly) && IsSoftwareCodec(componentName)) || + ((flags & kHardwareCodecsOnly) && !IsSoftwareCodec(componentName)) || + (!(flags & (kSoftwareCodecsOnly | kHardwareCodecsOnly)))) { + + matchingCodecs->push(String8(componentName)); + } } if (flags & kPreferSoftwareCodecs) { @@ -3881,17 +3875,8 @@ void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) { CHECK(!"Unknown compression format."); } - if (!strcmp(mComponentName, "OMX.PV.avcdec")) { - // This component appears to be lying to me. - mOutputFormat->setInt32( - kKeyWidth, (video_def->nFrameWidth + 15) & -16); - mOutputFormat->setInt32( - kKeyHeight, (video_def->nFrameHeight + 15) & -16); - } else { - mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth); - mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight); - } - + mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth); + mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight); mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat); break; } diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java index 41207f77285a..c937b068619b 100644 --- a/opengl/java/android/opengl/GLSurfaceView.java +++ b/opengl/java/android/opengl/GLSurfaceView.java @@ -530,7 +530,6 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); - mGLThread.requestExitAndWait(); } // ---------------------------------------------------------------------- diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_panel_recents_bg.9.png b/packages/SystemUI/res/drawable-mdpi/sysbar_panel_recents_bg.9.png Binary files differnew file mode 100644 index 000000000000..85726d2892b8 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_panel_recents_bg.9.png diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml index 429fdf2b1736..dbe41674bbb2 100644 --- a/packages/SystemUI/res/layout-xlarge/status_bar.xml +++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml @@ -146,7 +146,7 @@ android:background="@drawable/ic_sysbar_icon_bg" systemui:keyCode="3" /> - <ImageButton android:id="@+id/recent" + <ImageButton android:id="@+id/recent_apps" android:layout_width="wrap_content" android:layout_height="match_parent" android:src="@drawable/ic_sysbar_recent" diff --git a/packages/SystemUI/res/layout-xlarge/sysbar_panel_recent.xml b/packages/SystemUI/res/layout-xlarge/sysbar_panel_recent.xml new file mode 100644 index 000000000000..2f9e0d76baba --- /dev/null +++ b/packages/SystemUI/res/layout-xlarge/sysbar_panel_recent.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* apps/common/assets/default/default/skins/StatusBar.xml +** +** Copyright 2010, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<com.android.systemui.statusbar.tablet.RecentAppsPanel + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:background="@drawable/sysbar_panel_recents_bg" + android:orientation="vertical"> + + <TextView android:id="@+id/recents_no_recents" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:text="@string/recent_tasks_empty" + android:gravity="center_horizontal|center_vertical" + android:visibility="gone"> + </TextView> + + <HorizontalScrollView android:id="@+id/scroll_view" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <LinearLayout android:id="@+id/recents_container" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="right" + android:orientation="horizontal" + /> + + </HorizontalScrollView> + +</com.android.systemui.statusbar.tablet.RecentAppsPanel> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java new file mode 100644 index 000000000000..67979589b8c4 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.tablet; + +import java.util.ArrayList; +import java.util.List; + +import android.app.ActivityManager; +import android.bluetooth.BluetoothAdapter; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; +import android.media.AudioManager; +import android.net.wifi.WifiManager; +import android.util.AttributeSet; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.view.View.OnClickListener; +import android.widget.BaseAdapter; +import android.widget.Gallery; +import android.widget.HorizontalScrollView; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import com.android.systemui.R; + +public class RecentAppsPanel extends LinearLayout implements StatusBarPanel, OnClickListener { + private static final String TAG = "RecentAppsPanel"; + private static final boolean DEBUG = TabletStatusBarService.DEBUG; + private static final int MAX_RECENT_TASKS = 20; + private static final float ITEM_WIDTH = 75; + private static final float ITEM_HEIGHT = 75; + private TabletStatusBarService mBar; + private TextView mNoRecents; + private LinearLayout mRecentsContainer; + private float mDensity; + private HorizontalScrollView mScrollView; + + public boolean isInContentArea(int x, int y) { + final int l = getPaddingLeft(); + final int r = getWidth() - getPaddingRight(); + final int t = getPaddingTop(); + final int b = getHeight() - getPaddingBottom(); + return x >= l && x < r && y >= t && y < b; + } + + public void setBar(TabletStatusBarService bar) { + mBar = bar; + } + + public RecentAppsPanel(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public RecentAppsPanel(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + mDensity = getResources().getDisplayMetrics().density; + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mNoRecents = (TextView) findViewById(R.id.recents_no_recents); + mRecentsContainer = (LinearLayout) findViewById(R.id.recents_container); + mScrollView = (HorizontalScrollView) findViewById(R.id.scroll_view); + mScrollView.setHorizontalFadingEdgeEnabled(true); + } + + @Override + protected void onVisibilityChanged(View changedView, int visibility) { + super.onVisibilityChanged(changedView, visibility); + Log.v(TAG, "onVisibilityChanged(" + changedView + ", " + visibility + ")"); + if (visibility == View.VISIBLE && changedView == this) { + refreshIcons(); + mRecentsContainer.setScrollbarFadingEnabled(true); + mRecentsContainer.scrollTo(0, 0); + } + } + + private void refreshIcons() { + mRecentsContainer.removeAllViews(); + final Context context = getContext(); + final PackageManager pm = context.getPackageManager(); + final ActivityManager am = (ActivityManager) + context.getSystemService(Context.ACTIVITY_SERVICE); + final List<ActivityManager.RecentTaskInfo> recentTasks = + am.getRecentTasks(MAX_RECENT_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE); + + ActivityInfo homeInfo = new Intent(Intent.ACTION_MAIN) + .addCategory(Intent.CATEGORY_HOME) + .resolveActivityInfo(pm, 0); + + int numTasks = recentTasks.size(); + final int width = (int) (mDensity * ITEM_WIDTH + 0.5f); + final int height = (int) (mDensity * ITEM_HEIGHT + 0.5f); + ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(width, height); + for (int i = 0; i < numTasks; ++i) { + final ActivityManager.RecentTaskInfo info = recentTasks.get(i); + + Intent intent = new Intent(info.baseIntent); + if (info.origActivity != null) { + intent.setComponent(info.origActivity); + } + + // Exclude home activity. + if (homeInfo != null + && homeInfo.packageName.equals(intent.getComponent().getPackageName()) + && homeInfo.name.equals(intent.getComponent().getClassName())) { + continue; + } + + intent.setFlags((intent.getFlags()&~Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) + | Intent.FLAG_ACTIVITY_NEW_TASK); + final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0); + if (resolveInfo != null) { + final ActivityInfo activityInfo = resolveInfo.activityInfo; + final String title = activityInfo.loadLabel(pm).toString(); + Drawable icon = activityInfo.loadIcon(pm); + + if (title != null && title.length() > 0 && icon != null) { + ImageView imageView = new ImageView(mContext); + imageView.setScaleType(ImageView.ScaleType.FIT_XY); + imageView.setLayoutParams(layoutParams); + imageView.setOnClickListener(this); + imageView.setTag(intent); + imageView.setImageDrawable(icon); + mRecentsContainer.addView(imageView); + } + } + } + + int views = mRecentsContainer.getChildCount(); + mNoRecents.setVisibility(views == 0 ? View.VISIBLE : View.GONE); + mRecentsContainer.setVisibility(views > 0 ? View.VISIBLE : View.GONE); + } + + public void onClick(View v) { + Intent intent = (Intent) v.getTag(); + if (DEBUG) Log.v(TAG, "Starting activity " + intent); + getContext().startActivity(intent); + mBar.animateCollapse(); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java index 9fb29ac81cc9..7234557a1538 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java @@ -67,8 +67,11 @@ public class TabletStatusBarService extends StatusBarService { public static final int MSG_CLOSE_NOTIFICATION_PANEL = 1001; public static final int MSG_OPEN_SYSTEM_PANEL = 1010; public static final int MSG_CLOSE_SYSTEM_PANEL = 1011; - + public static final int MSG_OPEN_RECENTS_PANEL = 1020; + public static final int MSG_CLOSE_RECENTS_PANEL = 1021; + private static final int MAX_IMAGE_LEVEL = 10000; + private static final boolean USE_2D_RECENTS = true; int mIconSize; @@ -76,7 +79,7 @@ public class TabletStatusBarService extends StatusBarService { // tracking all current notifications private NotificationData mNotns = new NotificationData(); - + TabletStatusBarView mStatusBarView; ImageView mNotificationTrigger; NotificationIconArea mNotificationIconArea; @@ -110,6 +113,7 @@ public class TabletStatusBarService extends StatusBarService { int mDisabled = 0; boolean mNotificationsOn = true; + private RecentAppsPanel mRecentsPanel; protected void addPanelWindows() { final Context context = mContext; @@ -118,6 +122,7 @@ public class TabletStatusBarService extends StatusBarService { final int barHeight= res.getDimensionPixelSize( com.android.internal.R.dimen.status_bar_height); + // Notification Panel mNotificationPanel = (NotificationPanel)View.inflate(context, R.layout.sysbar_panel_notifications, null); mNotificationPanel.setVisibility(View.GONE); @@ -139,11 +144,11 @@ public class TabletStatusBarService extends StatusBarService { WindowManagerImpl.getDefault().addView(mNotificationPanel, lp); + // System Panel mSystemPanel = (SystemPanel) View.inflate(context, R.layout.sysbar_panel_system, null); mSystemPanel.setVisibility(View.GONE); mSystemPanel.setOnTouchListener(new TouchOutsideListener(MSG_CLOSE_SYSTEM_PANEL, - mSystemPanel)); - + mSystemPanel)); mStatusBarView.setIgnoreChildren(1, mSystemInfo, mSystemPanel); lp = new WindowManager.LayoutParams( @@ -159,6 +164,31 @@ public class TabletStatusBarService extends StatusBarService { WindowManagerImpl.getDefault().addView(mSystemPanel, lp); mSystemPanel.setBar(this); + + + // Recents Panel + if (USE_2D_RECENTS) { + mRecentsPanel = (RecentAppsPanel) View.inflate(context, R.layout.sysbar_panel_recent, + null); + mRecentsPanel.setVisibility(View.GONE); + mRecentsPanel.setOnTouchListener(new TouchOutsideListener(MSG_CLOSE_RECENTS_PANEL, + mRecentsPanel)); + mStatusBarView.setIgnoreChildren(2, mRecentButton, mRecentsPanel); + + lp = new WindowManager.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT, + WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, + WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN + | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, + PixelFormat.TRANSLUCENT); + lp.gravity = Gravity.BOTTOM | Gravity.LEFT; + lp.setTitle("RecentsPanel"); + lp.windowAnimations = com.android.internal.R.style.Animation_SlidingCard; + + WindowManagerImpl.getDefault().addView(mRecentsPanel, lp); + mRecentsPanel.setBar(this); + } } @Override @@ -181,12 +211,13 @@ public class TabletStatusBarService extends StatusBarService { mBarContents = sb.findViewById(R.id.bar_contents); mCurtains = sb.findViewById(R.id.lights_out); mSystemInfo = sb.findViewById(R.id.systemInfo); + mRecentButton = sb.findViewById(R.id.recent_apps); // mSystemInfo.setOnClickListener(mOnClickListener); mSystemInfo.setOnLongClickListener(new SetLightsOnListener(false)); mSystemInfo.setOnTouchListener(new ClockTouchListener()); - mRecentButton = sb.findViewById(R.id.recent); + mRecentButton = sb.findViewById(R.id.recent_apps); mRecentButton.setOnClickListener(mOnClickListener); SetLightsOnListener on = new SetLightsOnListener(true); @@ -231,7 +262,7 @@ public class TabletStatusBarService extends StatusBarService { mPile = (ViewGroup)mNotificationPanel.findViewById(R.id.content); mPile.removeAllViews(); - + ScrollView scroller = (ScrollView)mPile.getParent(); scroller.setFillViewport(true); @@ -277,6 +308,13 @@ public class TabletStatusBarService extends StatusBarService { case MSG_CLOSE_SYSTEM_PANEL: if (DEBUG) Slog.d(TAG, "closing system panel"); mSystemPanel.setVisibility(View.GONE); + case MSG_OPEN_RECENTS_PANEL: + if (DEBUG) Slog.d(TAG, "opening recents panel"); + if (mRecentsPanel != null) mRecentsPanel.setVisibility(View.VISIBLE); + break; + case MSG_CLOSE_RECENTS_PANEL: + if (DEBUG) Slog.d(TAG, "closing recents panel"); + if (mRecentsPanel != null) mRecentsPanel.setVisibility(View.GONE); break; } } @@ -315,7 +353,7 @@ public class TabletStatusBarService extends StatusBarService { mSignalMeter.setImageResource(R.drawable.sysbar_wifimini); // adjust to permyriad mSignalMeter.setImageLevel(level * (MAX_IMAGE_LEVEL / 100)); - mSignalIcon.setImageResource(isWifi ? R.drawable.ic_sysbar_wifi_mini + mSignalIcon.setImageResource(isWifi ? R.drawable.ic_sysbar_wifi_mini : R.drawable.ic_sysbar_wifi_mini); // XXX } } @@ -362,7 +400,7 @@ public class TabletStatusBarService extends StatusBarService { public void updateNotification(IBinder key, StatusBarNotification notification) { if (DEBUG) Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ") // TODO"); - + final NotificationData.Entry oldEntry = mNotns.findByKey(key); if (oldEntry == null) { Slog.w(TAG, "updateNotification for unknown key: " + key); @@ -527,6 +565,8 @@ public class TabletStatusBarService extends StatusBarService { mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PANEL); mHandler.removeMessages(MSG_CLOSE_SYSTEM_PANEL); mHandler.sendEmptyMessage(MSG_CLOSE_SYSTEM_PANEL); + mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL); + mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL); } public void setLightsOn(boolean on) { @@ -665,7 +705,7 @@ public class TabletStatusBarService extends StatusBarService { mIconLayout.setVisibility(View.VISIBLE); // TODO: animation refreshNotificationTrigger(); } else { - int msg = (mNotificationPanel.getVisibility() == View.GONE) + int msg = (mNotificationPanel.getVisibility() == View.GONE) ? MSG_OPEN_NOTIFICATION_PANEL : MSG_CLOSE_NOTIFICATION_PANEL; mHandler.removeMessages(msg); @@ -677,7 +717,7 @@ public class TabletStatusBarService extends StatusBarService { public void onClickSystemInfo() { if (DEBUG) Slog.d(TAG, "clicked system info"); if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) { - int msg = (mSystemPanel.getVisibility() == View.GONE) + int msg = (mSystemPanel.getVisibility() == View.GONE) ? MSG_OPEN_SYSTEM_PANEL : MSG_CLOSE_SYSTEM_PANEL; mHandler.removeMessages(msg); @@ -687,11 +727,21 @@ public class TabletStatusBarService extends StatusBarService { public void onClickRecentButton() { if (DEBUG) Slog.d(TAG, "clicked recent apps"); - Intent intent = new Intent(); - intent.setClass(mContext, RecentApplicationsActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); - mContext.startActivity(intent); + if (mRecentsPanel == null) { + Intent intent = new Intent(); + intent.setClass(mContext, RecentApplicationsActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); + mContext.startActivity(intent); + } else { + if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) { + int msg = (mRecentsPanel.getVisibility() == View.GONE) + ? MSG_OPEN_RECENTS_PANEL + : MSG_CLOSE_RECENTS_PANEL; + mHandler.removeMessages(msg); + mHandler.sendEmptyMessage(msg); + } + } } private class NotificationClicker implements View.OnClickListener { @@ -835,7 +885,7 @@ public class TabletStatusBarService extends StatusBarService { final String _pkg = sbn.pkg; final String _tag = sbn.tag; final int _id = sbn.id; - vetoButton.setOnClickListener(new View.OnClickListener() { + vetoButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { try { mBarService.onNotificationClear(_pkg, _tag, _id); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java index d836e4af8855..15866fe7c88d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java @@ -26,8 +26,8 @@ import android.widget.FrameLayout; public class TabletStatusBarView extends FrameLayout { private Handler mHandler; - private View[] mIgnoreChildren = new View[2]; - private View[] mPanels = new View[2]; + private View[] mIgnoreChildren = new View[3]; + private View[] mPanels = new View[3]; private int[] mPos = new int[2]; public TabletStatusBarView(Context context) { @@ -44,9 +44,11 @@ public class TabletStatusBarView extends FrameLayout { mHandler.sendEmptyMessage(TabletStatusBarService.MSG_CLOSE_NOTIFICATION_PANEL); mHandler.removeMessages(TabletStatusBarService.MSG_CLOSE_SYSTEM_PANEL); mHandler.sendEmptyMessage(TabletStatusBarService.MSG_CLOSE_SYSTEM_PANEL); + mHandler.removeMessages(TabletStatusBarService.MSG_CLOSE_RECENTS_PANEL); + mHandler.sendEmptyMessage(TabletStatusBarService.MSG_CLOSE_RECENTS_PANEL); - for (int i=0; i<mPanels.length; i++) { - if (mPanels[i].getVisibility() == View.VISIBLE) { + for (int i=0; i < mPanels.length; i++) { + if (mPanels[i] != null && mPanels[i].getVisibility() == View.VISIBLE) { if (eventInside(mIgnoreChildren[i], ev)) { return true; } diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java index e59cc8c8eabe..656ec4d266dd 100644 --- a/services/java/com/android/server/LocationManagerService.java +++ b/services/java/com/android/server/LocationManagerService.java @@ -577,15 +577,16 @@ public class LocationManagerService extends ILocationManager.Stub implements Run || LocationManager.PASSIVE_PROVIDER.equals(provider)) && (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)) { - throw new SecurityException("Requires ACCESS_FINE_LOCATION permission"); + throw new SecurityException("Provider " + provider + + " requires ACCESS_FINE_LOCATION permission"); } if (LocationManager.NETWORK_PROVIDER.equals(provider) && (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) && (mContext.checkCallingOrSelfPermission(ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)) { - throw new SecurityException( - "Requires ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permission"); + throw new SecurityException("Provider " + provider + + " requires ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permission"); } } @@ -744,9 +745,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Run private LocationProviderInterface best(List<String> providerNames) { ArrayList<LocationProviderInterface> providers; synchronized (mLock) { - providers = new ArrayList<LocationProviderInterface>(mProviders.size()); - for (int i = mProviders.size() - 1; i >= 0; i--) { - providers.add(mProviders.get(i)); + providers = new ArrayList<LocationProviderInterface>(providerNames.size()); + for (String name : providerNames) { + providers.add(mProvidersByName.get(name)); } } diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java index b3e9f9dd44df..30e90a859711 100644 --- a/services/java/com/android/server/PowerManagerService.java +++ b/services/java/com/android/server/PowerManagerService.java @@ -2354,6 +2354,14 @@ class PowerManagerService extends IPowerManager.Stub Slog.d(TAG, "lightSensorChangedLocked " + value); } + // Don't do anything if the screen is off. + if ((mPowerState & SCREEN_ON_BIT) == 0) { + if (mDebugLightSensor) { + Slog.d(TAG, "dropping lightSensorChangedLocked because screen is off"); + } + return; + } + // do not allow light sensor value to decrease if (mHighestLightSensorValue < value) { mHighestLightSensorValue = value; diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java index 4f753663c8cf..92588fc878b0 100644 --- a/services/java/com/android/server/WifiService.java +++ b/services/java/com/android/server/WifiService.java @@ -872,9 +872,19 @@ public class WifiService extends IWifiManager.Stub { mWifiStateMachine.startWpsPbc(bssid); } - public void startWpsPin(String bssid, int apPin) { + public void startWpsWithPinFromAccessPoint(String bssid, int apPin) { enforceChangePermission(); - mWifiStateMachine.startWpsPin(bssid, apPin); + mWifiStateMachine.startWpsWithPinFromAccessPoint(bssid, apPin); + } + + public int startWpsWithPinFromDevice(String bssid) { + enforceChangePermission(); + if (mChannel != null) { + return mWifiStateMachine.syncStartWpsWithPinFromDevice(mChannel, bssid); + } else { + Slog.e(TAG, "mChannel is not initialized"); + return -1; + } } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index f52d3228649d..463493bd99c7 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -2139,7 +2139,7 @@ public class ActivityStack { // being started, which means not bringing it to the front // if the caller is not itself in the front. ActivityRecord curTop = topRunningNonDelayedActivityLocked(notTop); - if (curTop.task != taskTop.task) { + if (curTop != null && curTop.task != taskTop.task) { r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); boolean callerAtFront = sourceRecord == null || curTop.task == sourceRecord.task; diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java index ab7b601c6f01..5f9a3e7dac2b 100644 --- a/telephony/java/com/android/internal/telephony/CallManager.java +++ b/telephony/java/com/android/internal/telephony/CallManager.java @@ -380,7 +380,7 @@ public final class CallManager { break; case OFFHOOK: Phone fgPhone = getFgPhone(); - if (!(fgPhone instanceof SipPhone)) { + if (hasActiveFgCall() && !(fgPhone instanceof SipPhone)) { mode = AudioManager.MODE_IN_CALL; } break; diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java index 2db1071899a4..02eaa7cf698c 100644 --- a/tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java @@ -51,27 +51,28 @@ public class ShadersActivity extends Activity { private LinearGradient mHorGradient; private LinearGradient mDiagGradient; private LinearGradient mVertGradient; + private Bitmap mTexture; ShadersView(Context c) { super(c); - Bitmap texture = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset1); - mTexWidth = texture.getWidth(); - mTexHeight = texture.getHeight(); + mTexture = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset1); + mTexWidth = mTexture.getWidth(); + mTexHeight = mTexture.getHeight(); mDrawWidth = mTexWidth * 2.2f; mDrawHeight = mTexHeight * 1.2f; - mRepeatShader = new BitmapShader(texture, Shader.TileMode.REPEAT, + mRepeatShader = new BitmapShader(mTexture, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); - mTranslatedShader = new BitmapShader(texture, Shader.TileMode.REPEAT, + mTranslatedShader = new BitmapShader(mTexture, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); Matrix m1 = new Matrix(); m1.setTranslate(mTexWidth / 2.0f, mTexHeight / 2.0f); m1.postRotate(45, 0, 0); mTranslatedShader.setLocalMatrix(m1); - mScaledShader = new BitmapShader(texture, Shader.TileMode.MIRROR, + mScaledShader = new BitmapShader(mTexture, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR); Matrix m2 = new Matrix(); m2.setScale(0.5f, 0.5f); @@ -98,6 +99,7 @@ public class ShadersActivity extends Activity { protected void onDraw(Canvas canvas) { super.onDraw(canvas); //canvas.drawRGB(255, 255, 255); + canvas.drawBitmap(mTexture, 0.0f, 0.0f, null); // Bitmap shaders canvas.save(); diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp index cee85469c848..8551b0f9c903 100644 --- a/tools/aapt/XMLNode.cpp +++ b/tools/aapt/XMLNode.cpp @@ -203,13 +203,9 @@ status_t parseStyledString(Bundle* bundle, } } if (xliffDepth == 0 && pseudolocalize) { -#ifdef ENABLE_PSEUDOLOCALIZE std::string orig(String8(text).string()); std::string pseudo = pseudolocalize_string(orig); curString.append(String16(String8(pseudo.c_str()))); -#else - assert(false); -#endif } else { if (isFormatted && hasSubstitutionErrors(fileName, inXml, text) != NO_ERROR) { return UNKNOWN_ERROR; diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index f760d27a5f6b..720f6acd7a5a 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -108,6 +108,8 @@ interface IWifiManager void startWpsPbc(String bssid); - void startWpsPin(String bssid, int apPin); + void startWpsWithPinFromAccessPoint(String bssid, int apPin); + + int startWpsWithPinFromDevice(String bssid); } diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java index be5fab4b5285..04b3891ef240 100644 --- a/wifi/java/android/net/wifi/WifiConfigStore.java +++ b/wifi/java/android/net/wifi/WifiConfigStore.java @@ -361,10 +361,11 @@ class WifiConfigStore { } /** - * Start WPS pin method configuration + * Start WPS pin method configuration with pin obtained + * from the access point */ - static boolean startWpsPin(String bssid, int apPin) { - if (WifiNative.startWpsPinCommand(bssid, apPin)) { + static boolean startWpsWithPinFromAccessPoint(String bssid, int apPin) { + if (WifiNative.startWpsWithPinFromAccessPointCommand(bssid, apPin)) { /* WPS leaves all networks disabled */ markAllNetworksDisabled(); return true; @@ -374,6 +375,21 @@ class WifiConfigStore { } /** + * Start WPS pin method configuration with pin obtained + * from the device + */ + static int startWpsWithPinFromDevice(String bssid) { + int pin = WifiNative.startWpsWithPinFromDeviceCommand(bssid); + /* WPS leaves all networks disabled */ + if (pin != -1) { + markAllNetworksDisabled(); + } else { + Log.e(TAG, "Failed to start WPS pin method configuration"); + } + return pin; + } + + /** * Start WPS push button configuration */ static boolean startWpsPbc(String bssid) { diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 0b3a78266378..84d615cc9a1d 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1050,19 +1050,36 @@ public class WifiManager { /** * Start Wi-fi Protected Setup pin method configuration + * with pin obtained from the access point * * @param bssid BSSID of the access point * @param apPin PIN issued by the access point * * @hide */ - public void startWpsPin(String bssid, int apPin) { + public void startWpsWithPinFromAccessPoint(String bssid, int apPin) { try { - mService.startWpsPin(bssid, apPin); + mService.startWpsWithPinFromAccessPoint(bssid, apPin); } catch (RemoteException e) { } } /** + * Start Wi-fi Protected Setup pin method configuration + * with pin obtained from the device + * + * @param bssid BSSID of the access point + * @return pin generated by device + * @hide + */ + public int startWpsWithPinFromDevice(String bssid) { + try { + return mService.startWpsWithPinFromDevice(bssid); + } catch (RemoteException e) { + return -1; + } + } + + /** * Allows an application to keep the Wi-Fi radio awake. * Normally the Wi-Fi radio may turn off when the user has not used the device in a while. * Acquiring a WifiLock will keep the radio on until the lock is released. Multiple diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java index 1251a2524c0e..313ae0b6f135 100644 --- a/wifi/java/android/net/wifi/WifiNative.java +++ b/wifi/java/android/net/wifi/WifiNative.java @@ -153,7 +153,9 @@ public class WifiNative { public native static boolean startWpsPbcCommand(String bssid); - public native static boolean startWpsPinCommand(String bssid, int apPin); + public native static boolean startWpsWithPinFromAccessPointCommand(String bssid, int apPin); + + public native static int startWpsWithPinFromDeviceCommand(String bssid); public native static boolean doDhcpRequest(DhcpInfo results); diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index e3deeb3e3e54..faafb7a19735 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -301,9 +301,10 @@ public class WifiStateMachine extends HierarchicalStateMachine { * supplicant config. */ private static final int CMD_FORGET_NETWORK = 92; - /* Start Wi-Fi protected setup */ - private static final int CMD_START_WPS = 93; - + /* Start Wi-Fi protected setup push button configuration */ + private static final int CMD_START_WPS_PBC = 93; + /* Start Wi-Fi protected setup pin method configuration */ + private static final int CMD_START_WPS_PIN = 94; /** * Interval in milliseconds between polling for connection * status items that are not sent via asynchronous events. @@ -787,11 +788,18 @@ public class WifiStateMachine extends HierarchicalStateMachine { } public void startWpsPbc(String bssid) { - sendMessage(obtainMessage(CMD_START_WPS, bssid)); + sendMessage(obtainMessage(CMD_START_WPS_PBC, bssid)); + } + + public void startWpsWithPinFromAccessPoint(String bssid, int apPin) { + sendMessage(obtainMessage(CMD_START_WPS_PIN, apPin, 0, bssid)); } - public void startWpsPin(String bssid, int apPin) { - sendMessage(obtainMessage(CMD_START_WPS, apPin, 0, bssid)); + public int syncStartWpsWithPinFromDevice(AsyncChannel channel, String bssid) { + Message resultMsg = channel.sendMessageSynchronously(CMD_START_WPS_PIN, bssid); + int result = resultMsg.arg1; + resultMsg.recycle(); + return result; } public void enableRssiPolling(boolean enabled) { @@ -1654,7 +1662,8 @@ public class WifiStateMachine extends HierarchicalStateMachine { case CMD_CONNECT_NETWORK: case CMD_SAVE_NETWORK: case CMD_FORGET_NETWORK: - case CMD_START_WPS: + case CMD_START_WPS_PBC: + case CMD_START_WPS_PIN: break; default: Log.e(TAG, "Error! unhandled message" + message); @@ -2395,17 +2404,11 @@ public class WifiStateMachine extends HierarchicalStateMachine { /* Expect a disconnection from the old connection */ transitionTo(mDisconnectingState); break; - case CMD_START_WPS: + case CMD_START_WPS_PBC: String bssid = (String) message.obj; - int apPin = message.arg1; - boolean success; - if (apPin != 0) { - /* WPS pin method configuration */ - success = WifiConfigStore.startWpsPin(bssid, apPin); - } else { - /* WPS push button configuration */ - success = WifiConfigStore.startWpsPbc(bssid); - } + /* WPS push button configuration */ + boolean success = WifiConfigStore.startWpsPbc(bssid); + /* During WPS setup, all other networks are disabled. After * a successful connect a new config is created in the supplicant. * @@ -2422,6 +2425,24 @@ public class WifiStateMachine extends HierarchicalStateMachine { transitionTo(mDisconnectingState); } break; + case CMD_START_WPS_PIN: + bssid = (String) message.obj; + int apPin = message.arg1; + int pin; + if (apPin != 0) { + /* WPS pin from access point */ + success = WifiConfigStore.startWpsWithPinFromAccessPoint(bssid, apPin); + } else { + pin = WifiConfigStore.startWpsWithPinFromDevice(bssid); + success = (pin != -1); + mReplyChannel.replyToMessage(message, CMD_START_WPS_PIN, pin); + } + if (success) { + mWpsStarted = true; + /* Expect a disconnection from the old connection */ + transitionTo(mDisconnectingState); + } + break; case SCAN_RESULTS_EVENT: /* Set the scan setting back to "connect" mode */ WifiNative.setScanResultHandlingCommand(CONNECT_MODE); |