Merge "Fix bug 5099037 - No delete option when multiple videos are selected"
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/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 17dfbe05..5d776fd 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -9278,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/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/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/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 8b23da7..f2673b3 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -549,7 +549,7 @@
mVideoTimeUs = 0;
mSeeking = NO_SEEK;
- mSeekNotificationSent = false;
+ mSeekNotificationSent = true;
mSeekTimeUs = 0;
mUri.setTo("");
@@ -1210,7 +1210,6 @@
if (mLastVideoTimeUs >= 0) {
mSeeking = SEEK;
- mSeekNotificationSent = true;
mSeekTimeUs = mLastVideoTimeUs;
modifyFlags((AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS), CLEAR);
}
@@ -1311,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) {
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());