Merge "Fix issue #5180553: permission RECEIVE_BOOT_COMPLETED is not checked"
diff --git a/api/current.txt b/api/current.txt
index d377109..4332833 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11431,7 +11431,7 @@
method public android.net.NetworkInfo getActiveNetworkInfo();
method public android.net.NetworkQuotaInfo getActiveNetworkQuotaInfo();
method public android.net.NetworkInfo[] getAllNetworkInfo();
- method public boolean getBackgroundDataSetting();
+ method public deprecated boolean getBackgroundDataSetting();
method public android.net.NetworkInfo getNetworkInfo(int);
method public int getNetworkPreference();
method public static boolean isNetworkTypeValid(int);
@@ -17087,7 +17087,7 @@
field public static final java.lang.String ALLOWED_GEOLOCATION_ORIGINS = "allowed_geolocation_origins";
field public static final java.lang.String ALLOW_MOCK_LOCATION = "mock_location";
field public static final java.lang.String ANDROID_ID = "android_id";
- field public static final java.lang.String BACKGROUND_DATA = "background_data";
+ field public static final deprecated java.lang.String BACKGROUND_DATA = "background_data";
field public static final java.lang.String BLUETOOTH_ON = "bluetooth_on";
field public static final android.net.Uri CONTENT_URI;
field public static final java.lang.String DATA_ROAMING = "data_roaming";
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 53fd50d..9c96883 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -21,6 +21,7 @@
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.os.Binder;
+import android.os.Build.VERSION_CODES;
import android.os.RemoteException;
import java.net.InetAddress;
@@ -503,16 +504,19 @@
* <p>
* All applications that have background services that use the network
* should listen to {@link #ACTION_BACKGROUND_DATA_SETTING_CHANGED}.
+ * <p>
+ * As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, availability of
+ * background data depends on several combined factors, and this method will
+ * always return {@code true}. Instead, when background data is unavailable,
+ * {@link #getActiveNetworkInfo()} will now appear disconnected.
*
* @return Whether background data usage is allowed.
*/
+ @Deprecated
public boolean getBackgroundDataSetting() {
- try {
- return mService.getBackgroundDataSetting();
- } catch (RemoteException e) {
- // Err on the side of safety
- return false;
- }
+ // assume that background data is allowed; final authority is
+ // NetworkInfo which may be blocked.
+ return true;
}
/**
@@ -525,11 +529,9 @@
* @see #getBackgroundDataSetting()
* @hide
*/
+ @Deprecated
public void setBackgroundDataSetting(boolean allowBackgroundData) {
- try {
- mService.setBackgroundDataSetting(allowBackgroundData);
- } catch (RemoteException e) {
- }
+ // ignored
}
/**
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index f391200..1b95b60 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -63,10 +63,6 @@
boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress);
- boolean getBackgroundDataSetting();
-
- void setBackgroundDataSetting(boolean allowBackgroundData);
-
boolean getMobileDataEnabled();
void setMobileDataEnabled(boolean enabled);
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index 78c9010..1029161 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -589,8 +589,6 @@
mPreferenceManager.setOnPreferenceTreeClickListener(this);
}
- getListView().setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
-
// see if we should show Back/Next buttons
Intent intent = getIntent();
if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false)) {
diff --git a/core/java/android/preference/PreferenceFragment.java b/core/java/android/preference/PreferenceFragment.java
index f6ba7f7..bdd858b 100644
--- a/core/java/android/preference/PreferenceFragment.java
+++ b/core/java/android/preference/PreferenceFragment.java
@@ -159,7 +159,6 @@
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- getListView().setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
if (mHavePrefs) {
bindPreferences();
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index de06f20..554afd2 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3081,6 +3081,7 @@
* Whether background data usage is allowed by the user. See
* ConnectivityManager for more info.
*/
+ @Deprecated
public static final String BACKGROUND_DATA = "background_data";
/**
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 642aa22..77f6776 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -1807,7 +1807,9 @@
* @hide
*/
public void setProperty(String key, String value) {
- mWebView.nativeSetProperty(key, value);
+ if (mWebView.nativeSetProperty(key, value)) {
+ mWebView.contentInvalidateAll();
+ }
}
/**
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 6374b47..5d776fd 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -9036,15 +9036,6 @@
}
/**
- * Enable expanded tiles bound for smoother scrolling.
- *
- * @hide only used by the Browser
- */
- public void setExpandedTileBounds(boolean enabled) {
- nativeSetExpandedTileBounds(enabled);
- }
-
- /**
* Set the time to wait between passing touches to WebCore. See also the
* TOUCH_SENT_INTERVAL member for further discussion.
*
@@ -9273,7 +9264,6 @@
static final int NO_LEFTEDGE = -1;
native int nativeGetBlockLeftEdge(int x, int y, float scale);
- private native void nativeSetExpandedTileBounds(boolean enabled);
private native void nativeUseHardwareAccelSkia(boolean enabled);
// Returns a pointer to the scrollable LayerAndroid at the given point.
@@ -9288,6 +9278,6 @@
*/
private native boolean nativeScrollLayer(int layer, int newX, int newY);
private native int nativeGetBackgroundColor();
- native void nativeSetProperty(String key, String value);
+ native boolean nativeSetProperty(String key, String value);
native String nativeGetProperty(String key);
}
diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java
index 45d73af..6a84626 100644
--- a/core/java/android/widget/ActivityChooserView.java
+++ b/core/java/android/widget/ActivityChooserView.java
@@ -156,7 +156,7 @@
* @param attrs A collection of attributes.
*/
public ActivityChooserView(Context context, AttributeSet attrs) {
- this(context, attrs, R.attr.actionButtonStyle);
+ this(context, attrs, 0);
}
/**
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index 5c42579..dd75925 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -391,7 +391,6 @@
final boolean inGroup = seenGroups.get(groupId);
boolean isAction = (maxActions > 0 || inGroup) && widthLimit > 0 &&
(!mStrictWidthLimit || cellsRemaining > 0);
- maxActions--;
if (isAction) {
View v = getItemView(item, mScrapActionButtonView, parent);
@@ -430,11 +429,15 @@
for (int j = 0; j < i; j++) {
MenuItemImpl areYouMyGroupie = visibleItems.get(j);
if (areYouMyGroupie.getGroupId() == groupId) {
+ // Give back the action slot
+ if (areYouMyGroupie.isActionButton()) maxActions++;
areYouMyGroupie.setIsActionButton(false);
}
}
}
+ if (isAction) maxActions--;
+
item.setIsActionButton(isAction);
}
}
diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java
index 5e70e4c..5622b44 100644
--- a/core/java/com/android/internal/view/menu/MenuBuilder.java
+++ b/core/java/com/android/internal/view/menu/MenuBuilder.java
@@ -567,7 +567,7 @@
}
}
- if (changedAtLeastOneItem) onItemsChanged(false);
+ if (changedAtLeastOneItem) onItemsChanged(true);
}
public void setGroupEnabled(int group, boolean enabled) {
@@ -929,6 +929,7 @@
*
* @param structureChanged true if the menu structure changed,
* false if only item properties changed.
+ * (Visibility is a structural property since it affects layout.)
*/
void onItemsChanged(boolean structureChanged) {
if (!mPreventDispatchingItemsChanged) {
@@ -971,7 +972,7 @@
void onItemVisibleChanged(MenuItemImpl item) {
// Notify of items being changed
mIsVisibleItemsStale = true;
- onItemsChanged(false);
+ onItemsChanged(true);
}
/**
@@ -981,7 +982,7 @@
void onItemActionRequestChanged(MenuItemImpl item) {
// Notify of items being changed
mIsActionItemsStale = true;
- onItemsChanged(false);
+ onItemsChanged(true);
}
ArrayList<MenuItemImpl> getVisibleItems() {
diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java
index 8b53bb8..04147ab 100644
--- a/core/java/com/android/internal/view/menu/MenuItemImpl.java
+++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java
@@ -585,7 +585,7 @@
public MenuItem setActionProvider(ActionProvider actionProvider) {
mActionView = null;
mActionProvider = actionProvider;
- mMenu.onItemsChanged(false);
+ mMenu.onItemsChanged(true); // Measurement can be changed
return this;
}
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 7baa412..792766b 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -1036,6 +1036,8 @@
} else if (centeredLeft + navWidth > menuLeft) {
hgravity = Gravity.RIGHT;
}
+ } else if (gravity == -1) {
+ hgravity = Gravity.LEFT;
}
int xpos = 0;
@@ -1051,8 +1053,14 @@
break;
}
+ int vgravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
+
+ if (gravity == -1) {
+ vgravity = Gravity.CENTER_VERTICAL;
+ }
+
int ypos = 0;
- switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) {
+ switch (vgravity) {
case Gravity.CENTER_VERTICAL:
final int paddedTop = getPaddingTop();
final int paddedBottom = mBottom - mTop - getPaddingBottom();
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index 45b7f27..b369efb 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -507,6 +507,7 @@
#define EVENT_LOOP_EXIT 1
#define EVENT_LOOP_ADD 2
#define EVENT_LOOP_REMOVE 3
+#define EVENT_LOOP_WAKEUP 4
dbus_bool_t dbusAddWatch(DBusWatch *watch, void *data) {
native_data_t *nat = (native_data_t *)data;
@@ -551,6 +552,13 @@
}
}
+void dbusWakeup(void *data) {
+ native_data_t *nat = (native_data_t *)data;
+
+ char control = EVENT_LOOP_WAKEUP;
+ write(nat->controlFdW, &control, sizeof(char));
+}
+
static void handleWatchAdd(native_data_t *nat) {
DBusWatch *watch;
int newFD;
@@ -634,6 +642,7 @@
dbus_connection_set_watch_functions(nat->conn, dbusAddWatch,
dbusRemoveWatch, dbusToggleWatch, ptr, NULL);
+ dbus_connection_set_wakeup_main_function(nat->conn, dbusWakeup, ptr, NULL);
nat->running = true;
@@ -669,6 +678,11 @@
handleWatchRemove(nat);
break;
}
+ case EVENT_LOOP_WAKEUP:
+ {
+ // noop
+ break;
+ }
}
}
} else {
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index b432d65..b8f2d6f 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -385,7 +385,8 @@
{
public:
JavaDeathRecipient(JNIEnv* env, jobject object, const sp<DeathRecipientList>& list)
- : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)), mList(list)
+ : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)),
+ mObjectWeak(NULL), mList(list)
{
// These objects manage their own lifetimes so are responsible for final bookkeeping.
// The list holds a strong reference to this object.
@@ -398,16 +399,23 @@
void binderDied(const wp<IBinder>& who)
{
- JNIEnv* env = javavm_to_jnienv(mVM);
-
LOGDEATH("Receiving binderDied() on JavaDeathRecipient %p\n", this);
+ if (mObject != NULL) {
+ JNIEnv* env = javavm_to_jnienv(mVM);
- env->CallStaticVoidMethod(gBinderProxyOffsets.mClass,
- gBinderProxyOffsets.mSendDeathNotice, mObject);
- jthrowable excep = env->ExceptionOccurred();
- if (excep) {
- report_exception(env, excep,
- "*** Uncaught exception returned from death notification!");
+ env->CallStaticVoidMethod(gBinderProxyOffsets.mClass,
+ gBinderProxyOffsets.mSendDeathNotice, mObject);
+ jthrowable excep = env->ExceptionOccurred();
+ if (excep) {
+ report_exception(env, excep,
+ "*** Uncaught exception returned from death notification!");
+ }
+
+ // Demote from strong ref to weak after binderDied() has been delivered,
+ // to allow the DeathRecipient and BinderProxy to be GC'd if no longer needed.
+ mObjectWeak = env->NewWeakGlobalRef(mObject);
+ env->DeleteGlobalRef(mObject);
+ mObject = NULL;
}
}
@@ -423,8 +431,17 @@
}
bool matches(jobject obj) {
+ bool result;
JNIEnv* env = javavm_to_jnienv(mVM);
- return env->IsSameObject(obj, mObject);
+
+ if (mObject != NULL) {
+ result = env->IsSameObject(obj, mObject);
+ } else {
+ jobject me = env->NewLocalRef(mObjectWeak);
+ result = env->IsSameObject(obj, me);
+ env->DeleteLocalRef(me);
+ }
+ return result;
}
protected:
@@ -433,12 +450,17 @@
//LOGI("Removing death ref: recipient=%p\n", mObject);
android_atomic_dec(&gNumDeathRefs);
JNIEnv* env = javavm_to_jnienv(mVM);
- env->DeleteGlobalRef(mObject);
+ if (mObject != NULL) {
+ env->DeleteGlobalRef(mObject);
+ } else {
+ env->DeleteWeakGlobalRef(mObjectWeak);
+ }
}
private:
- JavaVM* const mVM;
- jobject const mObject;
+ JavaVM* const mVM;
+ jobject mObject;
+ jweak mObjectWeak; // will be a weak ref to the same VM-side DeathRecipient after binderDied()
wp<DeathRecipientList> mList;
};
@@ -512,7 +534,7 @@
if (val->checkSubclass(&gBinderOffsets)) {
// One of our own!
jobject object = static_cast<JavaBBinder*>(val.get())->object();
- //printf("objectForBinder %p: it's our own %p!\n", val.get(), object);
+ LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
return object;
}
@@ -528,7 +550,7 @@
LOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
return res;
}
- LOGV("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
+ LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
android_atomic_dec(&gNumProxyRefs);
val->detachObject(&gBinderProxyOffsets);
env->DeleteGlobalRef(object);
diff --git a/core/res/res/layout-sw600dp/preference_list_content.xml b/core/res/res/layout-sw600dp/preference_list_content.xml
index 5b67d71..08f6453 100644
--- a/core/res/res/layout-sw600dp/preference_list_content.xml
+++ b/core/res/res/layout-sw600dp/preference_list_content.xml
@@ -44,8 +44,11 @@
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
- android:paddingTop="16dp"
- android:paddingBottom="16dp"
+ android:paddingLeft="@dimen/preference_screen_header_padding_side"
+ android:paddingRight="@dimen/preference_screen_header_padding_side"
+ android:paddingTop="@dimen/preference_screen_header_vertical_padding"
+ android:paddingBottom="@dimen/preference_screen_header_vertical_padding"
+ android:scrollbarStyle="@integer/preference_screen_header_scrollbarStyle"
android:drawSelectorOnTop="false"
android:cacheColorHint="@android:color/transparent"
android:listPreferredItemHeight="48dp"
diff --git a/core/res/res/layout/activity_chooser_view.xml b/core/res/res/layout/activity_chooser_view.xml
index 5d82a97..82e1f83 100644
--- a/core/res/res/layout/activity_chooser_view.xml
+++ b/core/res/res/layout/activity_chooser_view.xml
@@ -22,7 +22,8 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
- style="?android:attr/actionButtonStyle">
+ style="?android:attr/actionButtonStyle"
+ android:padding="0dip">
<FrameLayout
android:id="@+id/default_activity_button"
@@ -31,7 +32,7 @@
android:layout_gravity="center"
android:focusable="true"
android:addStatesFromChildren="true"
- android:background="?android:attr/selectableItemBackground">
+ android:background="?android:attr/actionBarItemBackground">
<ImageView android:id="@+id/image"
android:layout_width="32dip"
@@ -53,7 +54,7 @@
android:layout_gravity="center"
android:focusable="true"
android:addStatesFromChildren="true"
- android:background="?android:attr/selectableItemBackground">
+ android:background="?android:attr/actionBarItemBackground">
<ImageView android:id="@+id/image"
android:layout_width="32dip"
diff --git a/core/res/res/layout/breadcrumbs_in_fragment.xml b/core/res/res/layout/breadcrumbs_in_fragment.xml
index 98fffb7..9c12618 100644
--- a/core/res/res/layout/breadcrumbs_in_fragment.xml
+++ b/core/res/res/layout/breadcrumbs_in_fragment.xml
@@ -13,10 +13,10 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+
<!-- This layout disables breadcrumbs in the fragment area and causes PreferenceActivity to
put the breadcrumbs in the action bar. -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_height="@dimen/preference_fragment_padding_side"
- android:layout_width="match_parent">
-</LinearLayout>
\ No newline at end of file
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="0dip"
+ android:layout_height="0dip"
+ android:visibility="gone" />
diff --git a/core/res/res/layout/preference_list_content.xml b/core/res/res/layout/preference_list_content.xml
index 4e7981a..62181b5 100644
--- a/core/res/res/layout/preference_list_content.xml
+++ b/core/res/res/layout/preference_list_content.xml
@@ -44,8 +44,11 @@
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
+ android:paddingLeft="@dimen/preference_screen_header_padding_side"
+ android:paddingRight="@dimen/preference_screen_header_padding_side"
android:paddingTop="@dimen/preference_screen_header_vertical_padding"
android:paddingBottom="@dimen/preference_screen_header_vertical_padding"
+ android:scrollbarStyle="@integer/preference_screen_header_scrollbarStyle"
android:drawSelectorOnTop="false"
android:cacheColorHint="@android:color/transparent"
android:listPreferredItemHeight="48dp"
diff --git a/core/res/res/layout/preference_list_fragment.xml b/core/res/res/layout/preference_list_fragment.xml
index 315f708..fdef4fc 100644
--- a/core/res/res/layout/preference_list_fragment.xml
+++ b/core/res/res/layout/preference_list_fragment.xml
@@ -32,11 +32,19 @@
android:paddingBottom="@dimen/preference_fragment_padding_bottom"
android:paddingLeft="@dimen/preference_fragment_padding_side"
android:paddingRight="@dimen/preference_fragment_padding_side"
+ android:scrollbarStyle="@integer/preference_fragment_scrollbarStyle"
android:clipToPadding="false"
android:drawSelectorOnTop="false"
android:cacheColorHint="@android:color/transparent"
android:scrollbarAlwaysDrawVerticalTrack="true" />
+ <TextView android:id="@android:id/empty"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="@dimen/preference_fragment_padding_side"
+ android:gravity="center"
+ android:visibility="gone" />
+
<RelativeLayout android:id="@+id/button_bar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
diff --git a/core/res/res/values-h720dp/dimens.xml b/core/res/res/values-h720dp/dimens.xml
index 37dee8e..7efe322 100644
--- a/core/res/res/values-h720dp/dimens.xml
+++ b/core/res/res/values-h720dp/dimens.xml
@@ -25,4 +25,10 @@
<dimen name="preference_screen_top_margin">16dp</dimen>
<!-- Preference activity bottom margin -->
<dimen name="preference_screen_bottom_margin">16dp</dimen>
+
+ <dimen name="preference_screen_header_padding_side">0dip</dimen>
+
+ <integer name="preference_screen_header_scrollbarStyle">0x0</integer> <!-- insideOverlay -->
+ <integer name="preference_fragment_scrollbarStyle">0x0</integer> <!-- insideOverlay -->
+
</resources>
diff --git a/core/res/res/values-w720dp/dimens.xml b/core/res/res/values-w720dp/dimens.xml
index 3d10103..c62c3f5 100644
--- a/core/res/res/values-w720dp/dimens.xml
+++ b/core/res/res/values-w720dp/dimens.xml
@@ -29,4 +29,9 @@
This helps in aligning titles when some items have icons and some don't. When space is
at a premium, we don't pre-allocate any space. -->
<dimen name="preference_icon_minWidth">56dp</dimen>
+
+ <dimen name="preference_screen_header_padding_side">0dip</dimen>
+
+ <integer name="preference_screen_header_scrollbarStyle">0x0</integer> <!-- insideOverlay -->
+ <integer name="preference_fragment_scrollbarStyle">0x0</integer> <!-- insideOverlay -->
</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 40355e3..aa3397f 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -5264,9 +5264,9 @@
<!-- Specifies a background drawable for the action bar. -->
<attr name="background" />
<!-- Specifies a background drawable for a second stacked row of the action bar. -->
- <attr name="backgroundStacked" format="reference" />
+ <attr name="backgroundStacked" format="reference|color" />
<!-- Specifies a background drawable for the bottom component of a split action bar. -->
- <attr name="backgroundSplit" format="reference" />
+ <attr name="backgroundSplit" format="reference|color" />
<!-- Specifies a layout for custom navigation. Overrides navigationMode. -->
<attr name="customNavigationLayout" format="reference" />
<!-- Specifies a fixed height. -->
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 8855645..83e86939 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -76,9 +76,9 @@
<dimen name="multiwaveview_hit_radius">60dip</dimen>
<!-- Preference activity side margins -->
- <dimen name="preference_screen_side_margin">16dp</dimen>
+ <dimen name="preference_screen_side_margin">0dp</dimen>
<!-- Preference activity side margins negative-->
- <dimen name="preference_screen_side_margin_negative">16dp</dimen>
+ <dimen name="preference_screen_side_margin_negative">0dp</dimen>
<!-- Preference activity top margin -->
<dimen name="preference_screen_top_margin">0dp</dimen>
<!-- Preference activity bottom margin -->
@@ -88,7 +88,7 @@
<!-- Preference fragment padding, bottom -->
<dimen name="preference_fragment_padding_bottom">0dp</dimen>
<!-- Preference fragment padding, sides -->
- <dimen name="preference_fragment_padding_side">0dp</dimen>
+ <dimen name="preference_fragment_padding_side">16dp</dimen>
<!-- Weight of the left pane in a multi-pane preference layout. -->
<integer name="preferences_left_pane_weight">4</integer>
<!-- Weight of the right pane in a multi-pane preference layout. So the split is 40:60 -->
@@ -108,6 +108,11 @@
<!-- Preference activity, vertical padding for the header list -->
<dimen name="preference_screen_header_vertical_padding">0dp</dimen>
+ <dimen name="preference_screen_header_padding_side">16dip</dimen>
+ <integer name="preference_screen_header_scrollbarStyle">0x02000000</integer> <!-- outsideOverlay -->
+
+ <integer name="preference_fragment_scrollbarStyle">0x02000000</integer> <!-- outsideOverlay -->
+
<dimen name="preference_item_padding_side">8dip</dimen>
<dimen name="preference_item_padding_inner">8dip</dimen>
<dimen name="preference_child_padding_side">16dip</dimen>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 128889c..6aff54e 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3099,7 +3099,7 @@
<!-- Notification title when mobile data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=32] -->
<string name="data_usage_mobile_limit_title">Mobile data disabled</string>
<!-- Notification body when data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=32] -->
- <string name="data_usage_limit_body">tap to enable</string>
+ <string name="data_usage_limit_body">Touch to enable</string>
<!-- Notification title when 2G-3G data usage has exceeded limit threshold. [CHAR LIMIT=32] -->
<string name="data_usage_3g_limit_snoozed_title">2G-3G data limit exceeded</string>
@@ -3110,6 +3110,11 @@
<!-- Notification body when data usage has exceeded limit threshold. [CHAR LIMIT=32] -->
<string name="data_usage_limit_snoozed_body"><xliff:g id="size" example="3.8GB">%s</xliff:g> over specified limit</string>
+ <!-- Notification title when background data usage is limited. [CHAR LIMIT=32] -->
+ <string name="data_usage_restricted_title">Background data restricted</string>
+ <!-- Notification body when background data usage is limited. [CHAR LIMIT=32] -->
+ <string name="data_usage_restricted_body">Touch to remove restriction</string>
+
<!-- SSL Certificate dialogs -->
<!-- Title for an SSL Certificate dialog -->
<string name="ssl_certificate">Security certificate</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 6f2f1e5..94c6e41 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -2363,7 +2363,7 @@
<style name="Widget.Holo.PreferenceFrameLayout">
<item name="android:borderTop">0dip</item>
- <item name="android:borderBottom">@dimen/preference_fragment_padding_side</item>
+ <item name="android:borderBottom">@dimen/preference_fragment_padding_bottom</item>
<item name="android:borderLeft">@dimen/preference_fragment_padding_side</item>
<item name="android:borderRight">@dimen/preference_fragment_padding_side</item>
</style>
diff --git a/core/tests/coretests/src/android/provider/SettingsProviderTest.java b/core/tests/coretests/src/android/provider/SettingsProviderTest.java
index b82e698..3e96dc4 100644
--- a/core/tests/coretests/src/android/provider/SettingsProviderTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsProviderTest.java
@@ -20,11 +20,16 @@
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.net.Uri;
import android.provider.Settings;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.util.List;
/** Unit test for SettingsProvider. */
public class SettingsProviderTest extends AndroidTestCase {
@@ -191,4 +196,49 @@
assertEquals("test1,test2",
Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
}
+
+ @SmallTest
+ public void testSettings() {
+ assertCanBeHandled(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_ADD_ACCOUNT));
+ assertCanBeHandled(new Intent(Settings.ACTION_AIRPLANE_MODE_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_APN_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
+ .setData(Uri.parse("package:" + getContext().getPackageName())));
+ assertCanBeHandled(new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_APPLICATION_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_BLUETOOTH_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_DATE_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_DEVICE_INFO_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_DISPLAY_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_INTERNAL_STORAGE_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_LOCALE_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_MEMORY_CARD_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_NETWORK_OPERATOR_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_PRIVACY_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_QUICK_LAUNCH_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_SEARCH_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_SECURITY_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_SOUND_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_SYNC_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_SYSTEM_UPDATE_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_USER_DICTIONARY_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_WIFI_IP_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_WIFI_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_WIRELESS_SETTINGS));
+ }
+
+ private void assertCanBeHandled(final Intent intent) {
+ PackageManager packageManager = mContext.getPackageManager();
+ List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities(intent, 0);
+ assertNotNull(resolveInfoList);
+ // one or more activity can handle this intent.
+ assertTrue(resolveInfoList.size() > 0);
+ }
}
diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h
index dba98a3..6b31ca4 100644
--- a/include/surfaceflinger/ISurfaceComposer.h
+++ b/include/surfaceflinger/ISurfaceComposer.h
@@ -132,9 +132,10 @@
virtual status_t turnElectronBeamOff(int32_t mode) = 0;
virtual status_t turnElectronBeamOn(int32_t mode) = 0;
- /* verify that an ISurface was created by SurfaceFlinger.
+ /* verify that an ISurfaceTexture was created by SurfaceFlinger.
*/
- virtual bool authenticateSurface(const sp<ISurface>& surface) const = 0;
+ virtual bool authenticateSurfaceTexture(
+ const sp<ISurfaceTexture>& surface) const = 0;
};
// ----------------------------------------------------------------------------
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index c1156d5..030a83e 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -31,6 +31,8 @@
#include <ui/DisplayInfo.h>
+#include <gui/ISurfaceTexture.h>
+
#include <utils/Log.h>
// ---------------------------------------------------------------------------
@@ -166,35 +168,36 @@
return reply.readInt32();
}
- virtual bool authenticateSurface(const sp<ISurface>& surface) const
+ virtual bool authenticateSurfaceTexture(
+ const sp<ISurfaceTexture>& surfaceTexture) const
{
Parcel data, reply;
int err = NO_ERROR;
err = data.writeInterfaceToken(
ISurfaceComposer::getInterfaceDescriptor());
if (err != NO_ERROR) {
- LOGE("ISurfaceComposer::authenticateSurface: error writing "
+ LOGE("ISurfaceComposer::authenticateSurfaceTexture: error writing "
"interface descriptor: %s (%d)", strerror(-err), -err);
return false;
}
- err = data.writeStrongBinder(surface->asBinder());
+ err = data.writeStrongBinder(surfaceTexture->asBinder());
if (err != NO_ERROR) {
- LOGE("ISurfaceComposer::authenticateSurface: error writing strong "
- "binder to parcel: %s (%d)", strerror(-err), -err);
+ LOGE("ISurfaceComposer::authenticateSurfaceTexture: error writing "
+ "strong binder to parcel: %s (%d)", strerror(-err), -err);
return false;
}
err = remote()->transact(BnSurfaceComposer::AUTHENTICATE_SURFACE, data,
&reply);
if (err != NO_ERROR) {
- LOGE("ISurfaceComposer::authenticateSurface: error performing "
- "transaction: %s (%d)", strerror(-err), -err);
+ LOGE("ISurfaceComposer::authenticateSurfaceTexture: error "
+ "performing transaction: %s (%d)", strerror(-err), -err);
return false;
}
int32_t result = 0;
err = reply.readInt32(&result);
if (err != NO_ERROR) {
- LOGE("ISurfaceComposer::authenticateSurface: error retrieving "
- "result: %s (%d)", strerror(-err), -err);
+ LOGE("ISurfaceComposer::authenticateSurfaceTexture: error "
+ "retrieving result: %s (%d)", strerror(-err), -err);
return false;
}
return result != 0;
@@ -291,8 +294,9 @@
} break;
case AUTHENTICATE_SURFACE: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder());
- int32_t result = authenticateSurface(surface) ? 1 : 0;
+ sp<ISurfaceTexture> surfaceTexture =
+ interface_cast<ISurfaceTexture>(data.readStrongBinder());
+ int32_t result = authenticateSurfaceTexture(surfaceTexture) ? 1 : 0;
reply->writeInt32(result);
} break;
default:
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 2c70251..54d04aa 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -342,9 +342,6 @@
int Surface::query(int what, int* value) const {
switch (what) {
- case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
- *value = 1;
- return NO_ERROR;
case NATIVE_WINDOW_CONCRETE_TYPE:
*value = NATIVE_WINDOW_SURFACE;
return NO_ERROR;
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index e91be84..5a35b4d 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -18,6 +18,8 @@
//#define LOG_NDEBUG 0
#include <gui/SurfaceTextureClient.h>
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
#include <utils/Log.h>
@@ -234,7 +236,15 @@
}
break;
case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
- *value = 0;
+ {
+ sp<ISurfaceComposer> composer(
+ ComposerService::getComposerService());
+ if (composer->authenticateSurfaceTexture(mSurfaceTexture)) {
+ *value = 1;
+ } else {
+ *value = 0;
+ }
+ }
return NO_ERROR;
case NATIVE_WINDOW_CONCRETE_TYPE:
*value = NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT;
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 99242ab..f2673b3 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -59,6 +59,7 @@
#include <cutils/properties.h>
#define USE_SURFACE_ALLOC 1
+#define FRAME_DROP_FREQ 0
namespace android {
@@ -548,7 +549,7 @@
mVideoTimeUs = 0;
mSeeking = NO_SEEK;
- mSeekNotificationSent = false;
+ mSeekNotificationSent = true;
mSeekTimeUs = 0;
mUri.setTo("");
@@ -820,7 +821,12 @@
return;
}
- if (mFlags & (LOOPING | AUTO_LOOPING)) {
+ if ((mFlags & LOOPING)
+ || ((mFlags & AUTO_LOOPING)
+ && (mAudioSink == NULL || mAudioSink->realtime()))) {
+ // Don't AUTO_LOOP if we're being recorded, since that cannot be
+ // turned off and recording would go on indefinitely.
+
seekTo_l(0);
if (mVideoSource != NULL) {
@@ -1204,7 +1210,6 @@
if (mLastVideoTimeUs >= 0) {
mSeeking = SEEK;
- mSeekNotificationSent = true;
mSeekTimeUs = mLastVideoTimeUs;
modifyFlags((AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS), CLEAR);
}
@@ -1305,8 +1310,10 @@
}
void AwesomePlayer::onRTSPSeekDone() {
- notifyListener_l(MEDIA_SEEK_COMPLETE);
- mSeekNotificationSent = true;
+ if (!mSeekNotificationSent) {
+ notifyListener_l(MEDIA_SEEK_COMPLETE);
+ mSeekNotificationSent = true;
+ }
}
status_t AwesomePlayer::seekTo_l(int64_t timeUs) {
@@ -1518,14 +1525,29 @@
}
if (mVideoSource != NULL) {
- Mutex::Autolock autoLock(mStatsLock);
- TrackStat *stat = &mStats.mTracks.editItemAt(mStats.mVideoTrackIndex);
-
- const char *component;
+ const char *componentName;
CHECK(mVideoSource->getFormat()
- ->findCString(kKeyDecoderComponent, &component));
+ ->findCString(kKeyDecoderComponent, &componentName));
- stat->mDecoderName = component;
+ {
+ Mutex::Autolock autoLock(mStatsLock);
+ TrackStat *stat = &mStats.mTracks.editItemAt(mStats.mVideoTrackIndex);
+
+ stat->mDecoderName = componentName;
+ }
+
+ static const char *kPrefix = "OMX.Nvidia.";
+ static const char *kSuffix = ".decode";
+ static const size_t kSuffixLength = strlen(kSuffix);
+
+ size_t componentNameLength = strlen(componentName);
+
+ if (!strncmp(componentName, kPrefix, strlen(kPrefix))
+ && componentNameLength >= kSuffixLength
+ && !strcmp(&componentName[
+ componentNameLength - kSuffixLength], kSuffix)) {
+ modifyFlags(SLOW_DECODER_HACK, SET);
+ }
}
return mVideoSource != NULL ? OK : UNKNOWN_ERROR;
@@ -1705,6 +1727,7 @@
if (mFlags & FIRST_FRAME) {
modifyFlags(FIRST_FRAME, CLEAR);
+ mSinceLastDropped = 0;
mTimeSourceDeltaUs = ts->getRealTimeUs() - timeUs;
}
@@ -1751,18 +1774,28 @@
if (latenessUs > 40000) {
// We're more than 40ms late.
- LOGV("we're late by %lld us (%.2f secs), dropping frame",
+ LOGV("we're late by %lld us (%.2f secs)",
latenessUs, latenessUs / 1E6);
- mVideoBuffer->release();
- mVideoBuffer = NULL;
+ if (!(mFlags & SLOW_DECODER_HACK)
+ || mSinceLastDropped > FRAME_DROP_FREQ)
{
- Mutex::Autolock autoLock(mStatsLock);
- ++mStats.mNumVideoFramesDropped;
- }
+ LOGV("we're late by %lld us (%.2f secs) dropping "
+ "one after %d frames",
+ latenessUs, latenessUs / 1E6, mSinceLastDropped);
- postVideoEvent_l();
- return;
+ mSinceLastDropped = 0;
+ mVideoBuffer->release();
+ mVideoBuffer = NULL;
+
+ {
+ Mutex::Autolock autoLock(mStatsLock);
+ ++mStats.mNumVideoFramesDropped;
+ }
+
+ postVideoEvent_l();
+ return;
+ }
}
if (latenessUs < -10000) {
@@ -1781,6 +1814,7 @@
}
if (mVideoRenderer != NULL) {
+ mSinceLastDropped++;
mVideoRenderer->render(mVideoBuffer);
}
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 95f2ae8..14476d3 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -141,6 +141,8 @@
TEXT_RUNNING = 0x10000,
TEXTPLAYER_STARTED = 0x20000,
+
+ SLOW_DECODER_HACK = 0x40000,
};
mutable Mutex mLock;
@@ -181,6 +183,7 @@
uint32_t mFlags;
uint32_t mExtractorFlags;
+ uint32_t mSinceLastDropped;
int64_t mTimeSourceDeltaUs;
int64_t mVideoTimeUs;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 1e27233..a90eb3f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -59,13 +59,17 @@
mNotification = notification;
setContentDescription(notification);
- final int outerBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
- final int imageBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size);
- final float scale = (float)imageBounds / (float)outerBounds;
- setScaleX(scale);
- setScaleY(scale);
- final float alpha = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1);
- setAlpha(alpha);
+ // We do not resize and scale system icons (on the right), only notification icons (on the
+ // left).
+ if (notification != null) {
+ final int outerBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
+ final int imageBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size);
+ final float scale = (float)imageBounds / (float)outerBounds;
+ setScaleX(scale);
+ setScaleY(scale);
+ final float alpha = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1);
+ setAlpha(alpha);
+ }
}
private static boolean streq(String a, String b) {
@@ -247,4 +251,9 @@
}
}
}
+
+ public String toString() {
+ return "StatusBarIconView(slot=" + mSlot + " icon=" + mIcon
+ + " notification=" + mNotification + ")";
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 1edc351..68f6dcf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -91,6 +91,7 @@
static final String TAG = "PhoneStatusBar";
public static final boolean DEBUG = false;
public static final boolean SPEW = false;
+ public static final boolean DUMPTRUCK = true; // extra dumpsys info
// additional instrumentation for testing purposes; intended to be left on during development
public static final boolean CHATTY = DEBUG || true;
@@ -316,8 +317,8 @@
mPile = (ViewGroup)expanded.findViewById(R.id.latestItems);
mExpandedContents = mPile; // was: expanded.findViewById(R.id.notificationLinearLayout);
mNoNotificationsTitle = (TextView)expanded.findViewById(R.id.noNotificationsTitle);
- mNoNotificationsTitle.setAlpha(0f);
- mNoNotificationsTitle.setVisibility(View.VISIBLE);
+ mNoNotificationsTitle.setVisibility(View.GONE); // disabling for now
+
mClearButton = expanded.findViewById(R.id.clear_all_button);
mClearButton.setOnClickListener(mClearButtonListener);
mClearButton.setAlpha(0f);
@@ -1026,6 +1027,7 @@
mClearButton.setAlpha(clearable ? 1.0f : 0.0f);
}
+ /*
if (mNoNotificationsTitle.isShown()) {
if (any != (mNoNotificationsTitle.getAlpha() == 0.0f)) {
ObjectAnimator a = ObjectAnimator.ofFloat(mNoNotificationsTitle, "alpha",
@@ -1037,6 +1039,7 @@
} else {
mNoNotificationsTitle.setAlpha(any ? 0.0f : 0.75f);
}
+ */
}
@@ -1697,26 +1700,28 @@
pw.println(" mScrollView: " + viewInfo(mScrollView)
+ " scroll " + mScrollView.getScrollX() + "," + mScrollView.getScrollY());
}
- /*
- synchronized (mNotificationData) {
- int N = mNotificationData.ongoingCount();
- pw.println(" ongoingCount.size=" + N);
- for (int i=0; i<N; i++) {
- StatusBarNotification n = mNotificationData.getOngoing(i);
- pw.println(" [" + i + "] key=" + n.key + " view=" + n.view);
- pw.println(" data=" + n.data);
- }
- N = mNotificationData.latestCount();
- pw.println(" ongoingCount.size=" + N);
- for (int i=0; i<N; i++) {
- StatusBarNotification n = mNotificationData.getLatest(i);
- pw.println(" [" + i + "] key=" + n.key + " view=" + n.view);
- pw.println(" data=" + n.data);
- }
- }
- */
- if (false) {
+ if (DUMPTRUCK) {
+ synchronized (mNotificationData) {
+ int N = mNotificationData.size();
+ pw.println(" notification icons: " + N);
+ for (int i=0; i<N; i++) {
+ NotificationData.Entry e = mNotificationData.get(i);
+ pw.println(" [" + i + "] key=" + e.key + " icon=" + e.icon);
+ StatusBarNotification n = e.notification;
+ pw.println(" pkg=" + n.pkg + " id=" + n.id + " priority=" + n.priority);
+ pw.println(" notification=" + n.notification);
+ pw.println(" tickerText=\"" + n.notification.tickerText + "\"");
+ }
+ }
+
+ int N = mStatusIcons.getChildCount();
+ pw.println(" system icons: " + N);
+ for (int i=0; i<N; i++) {
+ StatusBarIconView ic = (StatusBarIconView) mStatusIcons.getChildAt(i);
+ pw.println(" [" + i + "] icon=" + ic);
+ }
+
pw.println("see the logcat for a dump of the views we have created.");
// must happen on ui thread
mHandler.post(new Runnable() {
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index 9d360ac..4f6df36 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -23,7 +23,6 @@
import com.android.internal.widget.multiwaveview.MultiWaveView;
import android.app.ActivityManager;
-import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
@@ -46,6 +45,7 @@
*/
class LockScreen extends LinearLayout implements KeyguardScreen {
+ private static final int ON_RESUME_PING_DELAY = 500; // delay first ping until the screen is on
private static final boolean DBG = false;
private static final String TAG = "LockScreen";
private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key";
@@ -441,10 +441,16 @@
mUnlockWidgetMethods.reset(false);
}
+ private final Runnable mOnResumePing = new Runnable() {
+ public void run() {
+ mUnlockWidgetMethods.ping();
+ }
+ };
+
/** {@inheritDoc} */
public void onResume() {
mStatusViewManager.onResume();
- mUnlockWidgetMethods.ping();
+ postDelayed(mOnResumePing, ON_RESUME_PING_DELAY);
}
/** {@inheritDoc} */
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 73e4338..c580f08 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -386,8 +386,10 @@
// Ditch the menu created above
st.menu = null;
- // Don't show it in the action bar either
- mActionBar.setMenu(null, mActionMenuPresenterCallback);
+ if (mActionBar != null) {
+ // Don't show it in the action bar either
+ mActionBar.setMenu(null, mActionMenuPresenterCallback);
+ }
return false;
}
@@ -409,9 +411,11 @@
}
if (!cb.onPreparePanel(st.featureId, st.createdPanelView, st.menu)) {
- // The app didn't want to show the menu for now but it still exists.
- // Clear it out of the action bar.
- mActionBar.setMenu(null, mActionMenuPresenterCallback);
+ if (mActionBar != null) {
+ // The app didn't want to show the menu for now but it still exists.
+ // Clear it out of the action bar.
+ mActionBar.setMenu(null, mActionMenuPresenterCallback);
+ }
st.menu.startDispatchingItemsChanged();
return false;
}
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 22ce484..1341dd4 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -163,8 +163,6 @@
private boolean mTestMode;
private static ConnectivityService sServiceInstance;
- private AtomicBoolean mBackgroundDataEnabled = new AtomicBoolean(true);
-
private INetworkManagementService mNetd;
private INetworkPolicyManager mPolicyManager;
@@ -213,13 +211,6 @@
MAX_NETWORK_STATE_TRACKER_EVENT + 5;
/**
- * used internally to set the background data preference
- * arg1 = TRUE for enabled, FALSE for disabled
- */
- private static final int EVENT_SET_BACKGROUND_DATA =
- MAX_NETWORK_STATE_TRACKER_EVENT + 6;
-
- /**
* used internally to set enable/disable cellular data
* arg1 = ENBALED or DISABLED
*/
@@ -317,9 +308,6 @@
handlerThread.start();
mHandler = new MyHandler(handlerThread.getLooper());
- mBackgroundDataEnabled.set(Settings.Secure.getInt(context.getContentResolver(),
- Settings.Secure.BACKGROUND_DATA, 1) == 1);
-
// setup our unique device name
if (TextUtils.isEmpty(SystemProperties.get("net.hostname"))) {
String id = Settings.Secure.getString(context.getContentResolver(),
@@ -1209,35 +1197,6 @@
}
/**
- * @see ConnectivityManager#getBackgroundDataSetting()
- */
- public boolean getBackgroundDataSetting() {
- return mBackgroundDataEnabled.get();
- }
-
- /**
- * @see ConnectivityManager#setBackgroundDataSetting(boolean)
- */
- public void setBackgroundDataSetting(boolean allowBackgroundDataUsage) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.CHANGE_BACKGROUND_DATA_SETTING,
- "ConnectivityService");
-
- mBackgroundDataEnabled.set(allowBackgroundDataUsage);
-
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_BACKGROUND_DATA,
- (allowBackgroundDataUsage ? ENABLED : DISABLED), 0));
- }
-
- private void handleSetBackgroundData(boolean enabled) {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.BACKGROUND_DATA, enabled ? 1 : 0);
- Intent broadcast = new Intent(
- ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED);
- mContext.sendBroadcast(broadcast);
- }
-
- /**
* @see ConnectivityManager#getMobileDataEnabled()
*/
public boolean getMobileDataEnabled() {
@@ -2273,12 +2232,6 @@
handleSetNetworkPreference(preference);
break;
}
- case EVENT_SET_BACKGROUND_DATA:
- {
- boolean enabled = (msg.arg1 == ENABLED);
- handleSetBackgroundData(enabled);
- break;
- }
case EVENT_SET_MOBILE_DATA:
{
boolean enabled = (msg.arg1 == ENABLED);
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 9c3d166..14d9665 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -89,6 +89,7 @@
import android.os.Message;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
+import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.format.Formatter;
import android.text.format.Time;
@@ -168,6 +169,12 @@
private static final String ATTR_UID = "uid";
private static final String ATTR_POLICY = "policy";
+ private static final String TAG_ALLOW_BACKGROUND = TAG + ":allowBackground";
+
+ // @VisibleForTesting
+ public static final String ACTION_ALLOW_BACKGROUND =
+ "com.android.server.action.ACTION_ALLOW_BACKGROUND";
+
private static final long TIME_CACHE_MAX_AGE = DAY_IN_MILLIS;
private static final int MSG_RULES_CHANGED = 0x1;
@@ -185,8 +192,8 @@
private final Object mRulesLock = new Object();
- private boolean mScreenOn;
- private boolean mRestrictBackground;
+ private volatile boolean mScreenOn;
+ private volatile boolean mRestrictBackground;
/** Defined network policies. */
private HashMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = Maps.newHashMap();
@@ -265,6 +272,7 @@
if (mRestrictBackground) {
updateRulesForRestrictBackgroundLocked();
+ updateNotificationsLocked();
}
}
@@ -309,6 +317,10 @@
mContext.registerReceiver(
mStatsReceiver, statsFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
+ // listen for restrict background changes from notifications
+ final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND);
+ mContext.registerReceiver(mAllowReceiver, allowFilter, MANAGE_NETWORK_POLICY, mHandler);
+
}
private IProcessObserver mProcessObserver = new IProcessObserver.Stub() {
@@ -402,6 +414,20 @@
};
/**
+ * Receiver that watches for {@link Notification} control of
+ * {@link #mRestrictBackground}.
+ */
+ private BroadcastReceiver mAllowReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // on background handler thread, and verified MANAGE_NETWORK_POLICY
+ // permission above.
+
+ setRestrictBackground(false);
+ }
+ };
+
+ /**
* Observer that watches for {@link INetworkManagementService} alerts.
*/
private INetworkManagementEventObserver mAlertObserver = new NetworkAlertObserver() {
@@ -494,6 +520,13 @@
notifyUnderLimitLocked(policy.template);
}
}
+
+ // ongoing notification when restricting background data
+ if (mRestrictBackground) {
+ enqueueRestrictedNotification(TAG_ALLOW_BACKGROUND);
+ } else {
+ cancelNotification(TAG_ALLOW_BACKGROUND);
+ }
}
/**
@@ -614,16 +647,52 @@
}
/**
- * Cancel any notification for combined {@link NetworkPolicy} and specific
- * type, like {@link #TYPE_LIMIT}.
+ * Show ongoing notification to reflect that {@link #mRestrictBackground}
+ * has been enabled.
*/
- private void cancelNotification(NetworkPolicy policy, int type) {
- final String tag = buildNotificationTag(policy, type);
+ private void enqueueRestrictedNotification(String tag) {
+ final Resources res = mContext.getResources();
+ final Notification.Builder builder = new Notification.Builder(mContext);
+
+ final CharSequence title = res.getText(R.string.data_usage_restricted_title);
+ final CharSequence body = res.getString(R.string.data_usage_restricted_body);
+
+ builder.setOnlyAlertOnce(true);
+ builder.setOngoing(true);
+ builder.setSmallIcon(R.drawable.ic_menu_info_details);
+ builder.setTicker(title);
+ builder.setContentTitle(title);
+ builder.setContentText(body);
+
+ final Intent intent = buildAllowBackgroundDataIntent();
+ builder.setContentIntent(
+ PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
// TODO: move to NotificationManager once we can mock it
try {
final String packageName = mContext.getPackageName();
- mNotifManager.cancelNotificationWithTag(packageName, tag, 0x0);
+ final int[] idReceived = new int[1];
+ mNotifManager.enqueueNotificationWithTag(packageName, tag,
+ 0x0, builder.getNotification(), idReceived);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "problem during enqueueNotification: " + e);
+ }
+ }
+
+ /**
+ * Cancel any notification for combined {@link NetworkPolicy} and specific
+ * type, like {@link #TYPE_LIMIT}.
+ */
+ private void cancelNotification(NetworkPolicy policy, int type) {
+ cancelNotification(buildNotificationTag(policy, type));
+ }
+
+ private void cancelNotification(String tag) {
+ // TODO: move to NotificationManager once we can mock it
+ try {
+ final String packageName = mContext.getPackageName();
+ mNotifManager.cancelNotificationWithTag(
+ packageName, tag, 0x0);
} catch (RemoteException e) {
Slog.w(TAG, "problem during enqueueNotification: " + e);
}
@@ -731,15 +800,9 @@
final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED;
final boolean hasWarning = policy.warningBytes != WARNING_DISABLED;
- if (hasLimit || hasWarning) {
- final long quotaBytes;
- if (hasLimit) {
- // remaining "quota" is based on usage in current cycle
- quotaBytes = Math.max(0, policy.limitBytes - total);
- } else {
- // to track warning alert later, use a high quota
- quotaBytes = Long.MAX_VALUE;
- }
+ if (hasLimit) {
+ // remaining "quota" is based on usage in current cycle
+ final long quotaBytes = Math.max(0, policy.limitBytes - total);
if (ifaces.length > 1) {
// TODO: switch to shared quota once NMS supports
@@ -754,16 +817,6 @@
}
}
}
-
- if (hasWarning) {
- final long alertBytes = Math.max(0, policy.warningBytes - total);
- for (String iface : ifaces) {
- removeInterfaceAlert(iface);
- if (alertBytes > 0) {
- setInterfaceAlert(iface, alertBytes);
- }
- }
- }
}
// remove quota on any trailing interfaces
@@ -839,11 +892,7 @@
mRestrictBackground = readBooleanAttribute(
in, ATTR_RESTRICT_BACKGROUND);
} else {
- try {
- mRestrictBackground = !mConnManager.getBackgroundDataSetting();
- } catch (RemoteException e) {
- mRestrictBackground = false;
- }
+ mRestrictBackground = false;
}
} else if (TAG_NETWORK_POLICY.equals(tag)) {
@@ -879,6 +928,7 @@
} catch (FileNotFoundException e) {
// missing policy is okay, probably first boot
+ upgradeLegacyBackgroundData();
} catch (IOException e) {
Slog.e(TAG, "problem reading network stats", e);
} catch (XmlPullParserException e) {
@@ -888,6 +938,22 @@
}
}
+ /**
+ * Upgrade legacy background data flags, notifying listeners of one last
+ * change to always-true.
+ */
+ private void upgradeLegacyBackgroundData() {
+ mRestrictBackground = Settings.Secure.getInt(
+ mContext.getContentResolver(), Settings.Secure.BACKGROUND_DATA, 1) != 1;
+
+ // kick off one last broadcast if restricted
+ if (mRestrictBackground) {
+ final Intent broadcast = new Intent(
+ ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED);
+ mContext.sendBroadcast(broadcast);
+ }
+ }
+
private void writePolicyLocked() {
if (LOGV) Slog.v(TAG, "writePolicyLocked()");
@@ -1057,6 +1123,7 @@
synchronized (mRulesLock) {
mRestrictBackground = restrictBackground;
updateRulesForRestrictBackgroundLocked();
+ updateNotificationsLocked();
writePolicyLocked();
}
}
@@ -1420,6 +1487,10 @@
return telephony.getSubscriberId();
}
+ private static Intent buildAllowBackgroundDataIntent() {
+ return new Intent(ACTION_ALLOW_BACKGROUND);
+ }
+
private static Intent buildNetworkOverLimitIntent(NetworkTemplate template) {
final Intent intent = new Intent();
intent.setComponent(new ComponentName(
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 0425fc3..64eaecc 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -133,6 +133,11 @@
return sur;
}
+wp<IBinder> Layer::getSurfaceTextureBinder() const
+{
+ return mSurfaceTexture->asBinder();
+}
+
status_t Layer::setBuffers( uint32_t w, uint32_t h,
PixelFormat format, uint32_t flags)
{
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index d3ddab4..5f0be80 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -74,6 +74,9 @@
virtual bool isProtected() const;
virtual void onRemoved();
+ // LayerBaseClient interface
+ virtual wp<IBinder> getSurfaceTextureBinder() const;
+
// only for debugging
inline const sp<FreezeLock>& getFreezeLock() const { return mFreezeLock; }
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index e04c533..7bf73d9 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -544,6 +544,10 @@
return mClientSurfaceBinder;
}
+wp<IBinder> LayerBaseClient::getSurfaceTextureBinder() const {
+ return 0;
+}
+
void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const
{
LayerBase::dump(result, buffer, SIZE);
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index faf71dd..a3d3644 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -288,6 +288,7 @@
sp<ISurface> getSurface();
wp<IBinder> getSurfaceBinder() const;
+ virtual wp<IBinder> getSurfaceTextureBinder() const;
virtual sp<LayerBaseClient> getLayerBaseClient() const {
return const_cast<LayerBaseClient*>(this); }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index a68ab30..50afb3d 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -353,9 +353,10 @@
mEventQueue.invalidate();
}
-bool SurfaceFlinger::authenticateSurface(const sp<ISurface>& surface) const {
+bool SurfaceFlinger::authenticateSurfaceTexture(
+ const sp<ISurfaceTexture>& surfaceTexture) const {
Mutex::Autolock _l(mStateLock);
- sp<IBinder> surfBinder(surface->asBinder());
+ sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
// Check the visible layer list for the ISurface
const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
@@ -363,14 +364,17 @@
for (size_t i=0 ; i<count ; i++) {
const sp<LayerBase>& layer(currentLayers[i]);
sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
- if (lbc != NULL && lbc->getSurfaceBinder() == surfBinder) {
- return true;
+ if (lbc != NULL) {
+ wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
+ if (lbcBinder == surfaceTextureBinder) {
+ return true;
+ }
}
}
// Check the layers in the purgatory. This check is here so that if a
- // Surface gets destroyed before all the clients are done using it, the
- // error will not be reported as "surface XYZ is not authenticated", but
+ // SurfaceTexture gets destroyed before all the clients are done using it,
+ // the error will not be reported as "surface XYZ is not authenticated", but
// will instead fail later on when the client tries to use the surface,
// which should be reported as "surface XYZ returned an -ENODEV". The
// purgatorized layers are no less authentic than the visible ones, so this
@@ -379,8 +383,11 @@
for (size_t i=0 ; i<purgatorySize ; i++) {
const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
- if (lbc != NULL && lbc->getSurfaceBinder() == surfBinder) {
- return true;
+ if (lbc != NULL) {
+ wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
+ if (lbcBinder == surfaceTextureBinder) {
+ return true;
+ }
}
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 89df0de..1738238 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -171,7 +171,7 @@
virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags);
virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags);
virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags);
- virtual bool authenticateSurface(const sp<ISurface>& surface) const;
+ virtual bool authenticateSurfaceTexture(const sp<ISurfaceTexture>& surface) const;
virtual status_t captureScreen(DisplayID dpy,
sp<IMemoryHeap>* heap,
diff --git a/tests/BiDiTests/res/layout/basic.xml b/tests/BiDiTests/res/layout/basic.xml
index e8f67a6..8a27213 100644
--- a/tests/BiDiTests/res/layout/basic.xml
+++ b/tests/BiDiTests/res/layout/basic.xml
@@ -34,6 +34,19 @@
android:textSize="32dip"
/>
+ <TextView android:id="@+id/textview_default"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:textSize="32dip"
+ android:text="@string/textview_default_text"
+ />
+
+ <EditText android:id="@+id/edittext_default"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:textSize="32dip"
+ />
+
<TextView android:id="@+id/textview_ltr"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
@@ -46,7 +59,6 @@
android:layout_width="match_parent"
android:textSize="32dip"
android:textDirection="ltr"
- android:text="@string/url"
/>
<TextView android:id="@+id/textview_rtl"
diff --git a/tests/BiDiTests/res/values/strings.xml b/tests/BiDiTests/res/values/strings.xml
index fde0ecf..b0809da 100644
--- a/tests/BiDiTests/res/values/strings.xml
+++ b/tests/BiDiTests/res/values/strings.xml
@@ -27,6 +27,7 @@
<string name="textview_text">This is a text for a TextView</string>
<string name="textview_ltr_text">This is a text for a LTR TextView</string>
<string name="textview_rtl_text">This is a text for a RTL TextView</string>
+ <string name="textview_default_text">This is a text for a default TextView</string>
<string name="edittext_text">mmmmmmmmmmmmmmmmmmmmmmmm</string>
<string name="normal_text">Normal String</string>
<string name="normal_long_text">mmmmmmmmmmmmmmmmmmmmmmmm</string>
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index daf53e0..178e7fd 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -1546,7 +1546,9 @@
assets = new AaptAssets();
// Set up the resource gathering in assets if we're going to generate
- // dependency files
+ // dependency files. Every time we encounter a resource while slurping
+ // the tree, we'll add it to these stores so we have full resource paths
+ // to write to a dependency file.
if (bundle->getGenDependencies()) {
sp<FilePathStore> resPathStore = new FilePathStore;
assets->setFullResPaths(resPathStore);
@@ -1577,15 +1579,20 @@
goto bail;
}
+ // If we've been asked to generate a dependency file, do that here
if (bundle->getGenDependencies()) {
+ // If this is the packaging step, generate the dependency file next to
+ // the output apk (e.g. bin/resources.ap_.d)
if (outputAPKFile) {
dependencyFile = String8(outputAPKFile);
- // Strip the extension and add new one
- dependencyFile = dependencyFile.getBasePath();
+ // Add the .d extension to the dependency file.
dependencyFile.append(".d");
} else {
+ // Else if this is the R.java dependency generation step,
+ // generate the dependency file in the R.java package subdirectory
+ // e.g. gen/com/foo/app/R.java.d
dependencyFile = String8(bundle->getRClassDir());
- dependencyFile.appendPath("R.d");
+ dependencyFile.appendPath("R.java.d");
}
// Make sure we have a clean dependency file to start with
fp = fopen(dependencyFile, "w");
@@ -1595,13 +1602,18 @@
// Write out R.java constants
if (assets->getPackage() == assets->getSymbolsPrivatePackage()) {
if (bundle->getCustomPackage() == NULL) {
+ // Write the R.java file into the appropriate class directory
+ // e.g. gen/com/foo/app/R.java
err = writeResourceSymbols(bundle, assets, assets->getPackage(), true);
- // Copy R.java for libraries
+ // If we have library files, we're going to write our R.java file into
+ // the appropriate class directory for those libraries as well.
+ // e.g. gen/com/foo/app/lib/R.java
if (bundle->getExtraPackages() != NULL) {
// Split on colon
String8 libs(bundle->getExtraPackages());
char* packageString = strtok(libs.lockBuffer(libs.length()), ":");
while (packageString != NULL) {
+ // Write the R.java file out with the correct package name
err = writeResourceSymbols(bundle, assets, String8(packageString), true);
packageString = strtok(NULL, ":");
}
@@ -1640,6 +1652,10 @@
}
}
+ // If we've been asked to generate a dependency file, we need to finish up here.
+ // the writeResourceSymbols and writeAPK functions have already written the target
+ // half of the dependency file, now we need to write the prerequisites. (files that
+ // the R.java file or .ap_ file depend on)
if (bundle->getGenDependencies()) {
// Now that writeResourceSymbols or writeAPK has taken care of writing
// the targets to our dependency file, we'll write the prereqs
@@ -1647,7 +1663,8 @@
fprintf(fp, " : ");
bool includeRaw = (outputAPKFile != NULL);
err = writeDependencyPreReqs(bundle, assets, fp, includeRaw);
- // Also manually add the AndroidManifeset since it's a non-asset
+ // Also manually add the AndroidManifeset since it's not under res/ or assets/
+ // and therefore was not added to our pathstores during slurping
fprintf(fp, "%s \\\n", bundle->getAndroidManifestFile());
fclose(fp);
}
diff --git a/tools/aapt/Package.cpp b/tools/aapt/Package.cpp
index c9f6870..1e3efde 100644
--- a/tools/aapt/Package.cpp
+++ b/tools/aapt/Package.cpp
@@ -177,12 +177,17 @@
}
}
+ // If we've been asked to generate a dependency file for the .ap_ package,
+ // do so here
if (bundle->getGenDependencies()) {
- // Add this file to the dependency file
- String8 dependencyFile = outputFile.getBasePath();
+ // The dependency file gets output to the same directory
+ // as the specified output file with an additional .d extension.
+ // e.g. bin/resources.ap_.d
+ String8 dependencyFile = outputFile;
dependencyFile.append(".d");
FILE* fp = fopen(dependencyFile.string(), "a");
+ // Add this file to the dependency file
fprintf(fp, "%s \\\n", outputFile.string());
fclose(fp);
}
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index cb6484f..2e796a2 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -1958,10 +1958,12 @@
}
fclose(fp);
+ // If we were asked to generate a dependency file, we'll go ahead and add this R.java
+ // as a target in the dependency file right next to it.
if (bundle->getGenDependencies()) {
// Add this R.java to the dependency file
String8 dependencyFile(bundle->getRClassDir());
- dependencyFile.appendPath("R.d");
+ dependencyFile.appendPath("R.java.d");
fp = fopen(dependencyFile.string(), "a");
fprintf(fp,"%s \\\n", dest.string());
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 3b043b3..bfc4d5e 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -203,70 +203,42 @@
private native static boolean doBooleanCommand(String command);
- //STOPSHIP: remove this after native interface works and replace all
- //calls to doBooleanTempCommand() with doBooleanCommand()
- private static boolean doBooleanTempCommand(String command) {
- try {
- String str = "/system/bin/wpa_cli " + command;
- Log.e("WifiNative", "===> " + str);
- Runtime.getRuntime()
- .exec(str).waitFor();
- } catch (Exception e) {
- Log.e("WifiNative", "exception with doBooleanTempCommand");
- return false;
- }
- return true;
- }
-
- private static String doStringTempCommand(String command) {
- String lines[] = null;
- try {
- String str = "/system/bin/wpa_cli " + command;
- Log.e("WifiNative", "===> " + str);
- Process p = Runtime.getRuntime()
- .exec(str);
- InputStream in = p.getInputStream();
- p.waitFor();
- byte[] bytes=new byte[in.available()];
- in.read(bytes);
- String s = new String(bytes);
- Log.e("WifiNative", "====> doString: " + s);
- lines = s.split("\\r?\\n");
- } catch (Exception e) {
- Log.e("WifiNative", "exception with doBooleanTempCommand");
- return null;
- }
- return lines[1];
- }
-
private native static int doIntCommand(String command);
private native static String doStringCommand(String command);
+ public static boolean wpsPbc() {
+ return doBooleanCommand("WPS_PBC");
+ }
+
+ public static boolean wpsPin(String pin) {
+ return doBooleanCommand("WPS_PIN any " + pin);
+ }
+
public static boolean p2pFind() {
- return doBooleanTempCommand("p2p_find");
+ return doBooleanCommand("P2P_FIND");
}
public static boolean p2pFind(int timeout) {
if (timeout <= 0) {
return p2pFind();
}
- return doBooleanTempCommand("p2p_find " + timeout);
+ return doBooleanCommand("P2P_FIND " + timeout);
}
public static boolean p2pListen() {
- return doBooleanTempCommand("p2p_listen");
+ return doBooleanCommand("P2P_LISTEN");
}
public static boolean p2pListen(int timeout) {
if (timeout <= 0) {
return p2pListen();
}
- return doBooleanTempCommand("p2p_listen " + timeout);
+ return doBooleanCommand("P2P_LISTEN " + timeout);
}
public static boolean p2pFlush() {
- return doBooleanTempCommand("p2p_flush");
+ return doBooleanCommand("P2P_FLUSH");
}
/* p2p_connect <peer device address> <pbc|pin|PIN#> [label|display|keypad]
@@ -300,41 +272,36 @@
if (config.isPersistent) args.add("persistent");
if (config.joinExistingGroup) args.add("join");
- args.add("go_intent=" + config.groupOwnerIntent);
+ int groupOwnerIntent = config.groupOwnerIntent;
+ if (groupOwnerIntent < 0 || groupOwnerIntent > 15) {
+ groupOwnerIntent = 3; //default value
+ }
+ args.add("go_intent=" + groupOwnerIntent);
if (config.channel > 0) args.add("freq=" + config.channel);
- String command = "p2p_connect ";
+ String command = "P2P_CONNECT ";
for (String s : args) command += s + " ";
- return doStringTempCommand(command);
+ return doStringCommand(command);
}
public static boolean p2pGroupAdd() {
- return doBooleanTempCommand("p2p_group_add");
+ return doBooleanCommand("P2P_GROUP_ADD");
}
public static boolean p2pGroupRemove(String iface) {
if (iface == null) return false;
- return doBooleanTempCommand("p2p_group_remove " + iface);
+ return doBooleanCommand("P2P_GROUP_REMOVE " + iface);
}
public static boolean p2pReject(String deviceAddress) {
- return doBooleanTempCommand("p2p_reject " + deviceAddress);
+ return doBooleanCommand("P2P_REJECT " + deviceAddress);
}
/* Invite a peer to a group */
public static boolean p2pInvite(WifiP2pGroup group, String deviceAddress) {
if (group == null || deviceAddress == null) return false;
- return doBooleanTempCommand("p2p_invite group=" + group.getInterface()
+ return doBooleanCommand("P2P_INVITE group=" + group.getInterface()
+ " peer=" + deviceAddress + " go_dev_addr=" + group.getOwner().deviceAddress);
}
-
- public static boolean p2pWpsPbc() {
- return doBooleanTempCommand("wps_pbc");
- }
-
- public static boolean p2pWpsPin(String pin) {
- return doBooleanTempCommand("wps_pin any " + pin);
- }
-
}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
index fff5ee3..b77fd76 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
@@ -46,8 +46,10 @@
* This is an integer value between 0 and 15 where 0 indicates the least
* inclination to be a group owner and 15 indicates the highest inclination
* to be a group owner.
+ *
+ * A value of -1 indicates the system can choose an appropriate value.
*/
- public int groupOwnerIntent;
+ public int groupOwnerIntent = -1;
public boolean isPersistent;
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 176191e..49ce124 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -767,10 +767,10 @@
notifyP2pProvDiscPinRequest((WifiP2pDevice) message.obj);
break;
case WifiP2pManager.WPS_PBC:
- WifiNative.p2pWpsPbc();
+ WifiNative.wpsPbc();
break;
case WifiP2pManager.WPS_PIN:
- WifiNative.p2pWpsPin((String) message.obj);
+ WifiNative.wpsPin((String) message.obj);
break;
default:
return NOT_HANDLED;