summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt2
-rw-r--r--core/java/android/app/SearchManager.java9
-rw-r--r--core/java/android/net/INetworkStatsService.aidl3
-rw-r--r--core/java/android/net/NetworkStatsHistory.java13
-rw-r--r--core/java/android/nfc/Tag.java16
-rw-r--r--core/java/android/os/INetworkManagementService.aidl2
-rw-r--r--core/java/android/provider/VoicemailContract.java104
-rw-r--r--core/java/android/view/ViewAncestor.java19
-rw-r--r--core/java/android/view/ViewConfiguration.java39
-rw-r--r--core/java/android/webkit/L10nUtils.java6
-rw-r--r--core/java/com/android/internal/net/VpnConfig.java23
-rw-r--r--core/java/com/android/internal/view/menu/ActionMenuPresenter.java5
-rw-r--r--core/res/res/layout-land/ssl_certificate.xml1
-rw-r--r--core/res/res/layout/ssl_certificate.xml1
-rwxr-xr-xcore/res/res/values/config.xml4
-rwxr-xr-xcore/res/res/values/strings.xml18
-rw-r--r--include/gui/SurfaceTexture.h4
-rw-r--r--include/media/stagefright/MediaSource.h10
-rw-r--r--include/media/stagefright/MetaData.h2
-rw-r--r--include/media/stagefright/OMXCodec.h20
-rw-r--r--libs/gui/SurfaceTexture.cpp11
-rwxr-xr-xlocation/java/com/android/internal/location/GpsNetInitiatedHandler.java2
-rw-r--r--media/libstagefright/OMXCodec.cpp188
-rw-r--r--media/libstagefright/WVMExtractor.cpp36
-rw-r--r--media/libstagefright/chromium_http/support.cpp34
-rw-r--r--media/libstagefright/codecs/avc/enc/AVCEncoder.cpp4
-rw-r--r--media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp9
-rw-r--r--media/libstagefright/httplive/LiveSession.cpp45
-rw-r--r--media/libstagefright/httplive/M3UParser.cpp13
-rw-r--r--media/libstagefright/include/WVMExtractor.h5
-rw-r--r--packages/SystemUI/res/values/config.xml4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java2
-rw-r--r--packages/VpnDialogs/Android.mk2
-rw-r--r--packages/VpnDialogs/AndroidManifest.xml3
-rw-r--r--packages/VpnDialogs/res/values/strings.xml1
-rw-r--r--packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java37
-rw-r--r--services/input/EventHub.cpp31
-rw-r--r--services/input/EventHub.h4
-rw-r--r--services/input/InputDispatcher.cpp5
-rw-r--r--services/input/InputReader.cpp21
-rw-r--r--services/input/tests/InputReader_test.cpp20
-rw-r--r--services/java/com/android/server/ConnectivityService.java2
-rw-r--r--services/java/com/android/server/NetworkManagementService.java51
-rw-r--r--services/java/com/android/server/SystemServer.java2
-rw-r--r--services/java/com/android/server/connectivity/Vpn.java205
-rw-r--r--services/java/com/android/server/net/NetworkPolicyManagerService.java7
-rw-r--r--services/java/com/android/server/net/NetworkStatsService.java39
-rw-r--r--services/jni/com_android_server_connectivity_Vpn.cpp4
-rw-r--r--services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java4
-rw-r--r--telephony/java/android/telephony/ServiceState.java25
-rw-r--r--telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java8
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java31
-rw-r--r--voip/java/com/android/server/sip/SipWakeupTimer.java6
53 files changed, 815 insertions, 347 deletions
diff --git a/api/current.txt b/api/current.txt
index 309e747a20f3..5053859bc69c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3453,6 +3453,7 @@ package android.app {
field public static final java.lang.String SUGGEST_COLUMN_INTENT_DATA = "suggest_intent_data";
field public static final java.lang.String SUGGEST_COLUMN_INTENT_DATA_ID = "suggest_intent_data_id";
field public static final java.lang.String SUGGEST_COLUMN_INTENT_EXTRA_DATA = "suggest_intent_extra_data";
+ field public static final java.lang.String SUGGEST_COLUMN_LAST_ACCESS_HINT = "suggest_last_access_hint";
field public static final java.lang.String SUGGEST_COLUMN_QUERY = "suggest_intent_query";
field public static final java.lang.String SUGGEST_COLUMN_SHORTCUT_ID = "suggest_shortcut_id";
field public static final java.lang.String SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING = "suggest_spinner_while_refreshing";
@@ -22263,6 +22264,7 @@ package android.view {
method public static deprecated int getTouchSlop();
method public static deprecated int getWindowTouchSlop();
method public static long getZoomControlsTimeout();
+ method public boolean hasPermanentMenuKey();
}
public class ViewDebug {
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 85a2fa831f65..7274362e77b5 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -329,6 +329,15 @@ public class SearchManager
public final static String SUGGEST_COLUMN_FLAGS = "suggest_flags";
/**
+ * Column name for suggestions cursor. <i>Optional.</i> This column may be
+ * used to specify the time in (@link System#currentTimeMillis
+ * System.currentTImeMillis()} (wall time in UTC) when an item was last
+ * accessed within the results-providing application. If set, this may be
+ * used to show more-recently-used items first.
+ */
+ public final static String SUGGEST_COLUMN_LAST_ACCESS_HINT = "suggest_last_access_hint";
+
+ /**
* Column value for suggestion column {@link #SUGGEST_COLUMN_SHORTCUT_ID} when a suggestion
* should not be stored as a shortcut in global search.
*/
diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl
index ae9aa05e0bce..054825024b9a 100644
--- a/core/java/android/net/INetworkStatsService.aidl
+++ b/core/java/android/net/INetworkStatsService.aidl
@@ -33,4 +33,7 @@ interface INetworkStatsService {
/** Return usage summary per UID for traffic that matches template. */
NetworkStats getSummaryForAllUid(in NetworkTemplate template, long start, long end, boolean includeTags);
+ /** Force update of statistics. */
+ void forceUpdate();
+
}
diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java
index ff6e220cac41..dd2945ca18af 100644
--- a/core/java/android/net/NetworkStatsHistory.java
+++ b/core/java/android/net/NetworkStatsHistory.java
@@ -279,10 +279,17 @@ public class NetworkStatsHistory implements Parcelable {
return (long) (start + (r.nextFloat() * (end - start)));
}
- public void dump(String prefix, PrintWriter pw) {
+ public void dump(String prefix, PrintWriter pw, boolean fullHistory) {
pw.print(prefix);
pw.print("NetworkStatsHistory: bucketDuration="); pw.println(bucketDuration);
- for (int i = 0; i < bucketCount; i++) {
+
+ final int start = fullHistory ? 0 : Math.max(0, bucketCount - 32);
+ if (start > 0) {
+ pw.print(prefix);
+ pw.print(" (omitting "); pw.print(start); pw.println(" buckets)");
+ }
+
+ for (int i = start; i < bucketCount; i++) {
pw.print(prefix);
pw.print(" bucketStart="); pw.print(bucketStart[i]);
pw.print(" rx="); pw.print(rx[i]);
@@ -293,7 +300,7 @@ public class NetworkStatsHistory implements Parcelable {
@Override
public String toString() {
final CharArrayWriter writer = new CharArrayWriter();
- dump("", new PrintWriter(writer));
+ dump("", new PrintWriter(writer), false);
return writer.toString();
}
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index 54583d61f4f9..a73067a5f709 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -313,14 +313,16 @@ public final class Tag implements Parcelable {
*/
@Override
public String toString() {
- StringBuilder sb = new StringBuilder("TAG ")
- .append("uid = ")
- .append(mId)
- .append(" Tech [");
- for (int i : mTechList) {
- sb.append(i)
- .append(", ");
+ StringBuilder sb = new StringBuilder("TAG: Tech [");
+ String[] techList = getTechList();
+ int length = techList.length;
+ for (int i = 0; i < length; i++) {
+ sb.append(techList[i]);
+ if (i < length - 1) {
+ sb.append(", ");
+ }
}
+ sb.append("]");
return sb.toString();
}
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index c9b6121adcf9..fcf479631b03 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -241,6 +241,4 @@ interface INetworkManagementService
*/
int getInterfaceTxThrottle(String iface);
- void setBandwidthControlEnabled(boolean enabled);
-
}
diff --git a/core/java/android/provider/VoicemailContract.java b/core/java/android/provider/VoicemailContract.java
index ab0cb505eb2d..41d3e7173eaf 100644
--- a/core/java/android/provider/VoicemailContract.java
+++ b/core/java/android/provider/VoicemailContract.java
@@ -52,18 +52,24 @@ public class VoicemailContract {
/** The authority used by the voicemail provider. */
public static final String AUTHORITY = "com.android.voicemail";
-
/** URI to insert/retrieve all voicemails. */
public static final Uri CONTENT_URI =
Uri.parse("content://" + AUTHORITY + "/voicemail");
/** URI to insert/retrieve voicemails by a given voicemail source. */
public static final Uri CONTENT_URI_SOURCE =
Uri.parse("content://" + AUTHORITY + "/voicemail/source/");
+ /** URI to insert/retrieve status of voicemail source. */
+ public static final Uri STATUS_CONTENT_URI =
+ Uri.parse("content://" + AUTHORITY + "/status");
+ /**
+ * Parameter key used in the URI to specify the voicemail source package name.
+ * <p> This field must be set in all requests that originate from a voicemail source.
+ */
+ public static final String PARAM_KEY_SOURCE_PACKAGE = "source_package";
// TODO: Move ACTION_NEW_VOICEMAIL to the Intent class.
/** Broadcast intent when a new voicemail record is inserted. */
public static final String ACTION_NEW_VOICEMAIL = "android.intent.action.NEW_VOICEMAIL";
-
/**
* Extra included in {@value Intent#ACTION_PROVIDER_CHANGED} and
* {@value #ACTION_NEW_VOICEMAIL} broadcast intents to indicate if the receiving
@@ -72,9 +78,27 @@ public class VoicemailContract {
public static final String EXTRA_SELF_CHANGE = "com.android.voicemail.extra.SELF_CHANGE";
/** The mime type for a collection of voicemails. */
- public static final String DIR_TYPE =
- "vnd.android.cursor.dir/voicemails";
+ public static final String DIR_TYPE = "vnd.android.cursor.dir/voicemails";
+
+ /**
+ * A convenience method to build voicemail URI specific to a source package. Appends URI param
+ * {@link #PARAM_KEY_SOURCE_PACKAGE} to the base voicemail content URI.
+ */
+ public static Uri buildSourceVoicemailUri(String packageName) {
+ return CONTENT_URI.buildUpon()
+ .appendQueryParameter(PARAM_KEY_SOURCE_PACKAGE, packageName).build();
+ }
+
+ /**
+ * A convenience method to build status URI specific to a source package. Appends URI param
+ * {@link #PARAM_KEY_SOURCE_PACKAGE} to the base status content URI.
+ */
+ public static Uri buildSourceStatusUri(String packageName) {
+ return STATUS_CONTENT_URI.buildUpon()
+ .appendQueryParameter(PARAM_KEY_SOURCE_PACKAGE, packageName).build();
+ }
+ /** Defines fields exposed through the /voicemail path of this content provider. */
public static final class Voicemails implements BaseColumns {
/** Not instantiable. */
private Voicemails() {
@@ -144,4 +168,76 @@ public class VoicemailContract {
*/
public static final String _DATA = "_data";
}
+
+ /** Defines fields exposed through the /status path of this content provider. */
+ public static final class Status implements BaseColumns {
+ /** Not instantiable. */
+ private Status() {
+ }
+ /**
+ * The package name of the voicemail source. There can only be a one entry per source.
+ * <P>Type: TEXT</P>
+ */
+ public static final String SOURCE_PACKAGE = "source_package";
+ /**
+ * The URI to call to invoke source specific voicemail settings screen. On a user request
+ * to setup voicemail an intent with action VIEW with this URI will be fired by the system.
+ * <P>Type: TEXT</P>
+ */
+ public static final String SETTINGS_URI = "settings_uri";
+ /**
+ * The URI to call when the user requests to directly access the voicemail from the remote
+ * server. In case of an IVR voicemail system this is typically set to the the voicemail
+ * number specified using a tel:/ URI.
+ * <P>Type: TEXT</P>
+ */
+ public static final String VOICEMAIL_ACCESS_URI = "voicemail_access_uri";
+ /**
+ * The configuration state of the voicemail source.
+ * <P> Possible values:
+ * {@link #CONFIGURATION_STATE_OK},
+ * {@link #CONFIGURATION_STATE_NOT_CONFIGURED},
+ * {@link #CONFIGURATION_STATE_CAN_BE_CONFIGURED}
+ * <P>Type: INTEGER</P>
+ */
+ public static final String CONFIGURATION_STATE = "configuration_state";
+ public static final int CONFIGURATION_STATE_OK = 0;
+ public static final int CONFIGURATION_STATE_NOT_CONFIGURED = 1;
+ /**
+ * This state must be used when the source has verified that the current user can be
+ * upgraded to visual voicemail and would like to show a set up invitation message.
+ */
+ public static final int CONFIGURATION_STATE_CAN_BE_CONFIGURED = 2;
+ /**
+ * The data channel state of the voicemail source. This the channel through which the source
+ * pulls voicemail data from a remote server.
+ * <P> Possible values:
+ * {@link #DATA_CHANNEL_STATE_OK},
+ * {@link #DATA_CHANNEL_STATE_NO_CONNECTION}
+ * </P>
+ * <P>Type: INTEGER</P>
+ */
+ public static final String DATA_CHANNEL_STATE = "data_channel_state";
+ public static final int DATA_CHANNEL_STATE_OK = 0;
+ public static final int DATA_CHANNEL_STATE_NO_CONNECTION = 1;
+ /**
+ * The notification channel state of the voicemail source. This is the channel through which
+ * the source gets notified of new voicemails on the remote server.
+ * <P> Possible values:
+ * {@link #NOTIFICATION_CHANNEL_STATE_OK},
+ * {@link #NOTIFICATION_CHANNEL_STATE_NO_CONNECTION},
+ * {@link #NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING}
+ * </P>
+ * <P>Type: INTEGER</P>
+ */
+ public static final String NOTIFICATION_CHANNEL_STATE = "notification_channel_state";
+ public static final int NOTIFICATION_CHANNEL_STATE_OK = 0;
+ public static final int NOTIFICATION_CHANNEL_STATE_NO_CONNECTION = 1;
+ /**
+ * Use this state when the notification can only tell that there are pending messages on
+ * the server but no details of the sender/time etc are known.
+ */
+ public static final int NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING = 2;
+
+ }
}
diff --git a/core/java/android/view/ViewAncestor.java b/core/java/android/view/ViewAncestor.java
index 2b692f3e93f1..d70c79850a18 100644
--- a/core/java/android/view/ViewAncestor.java
+++ b/core/java/android/view/ViewAncestor.java
@@ -4637,13 +4637,18 @@ public final class ViewAncestor extends Handler implements ViewParent,
public void run() {
if (mView != null) {
- // Send the event directly since we do not want to append the
- // source text because this is the text for the entire window
- // and we just want to notify that the content has changed.
- AccessibilityEvent event = AccessibilityEvent.obtain(
- AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
- mView.onInitializeAccessibilityEvent(event);
- AccessibilityManager.getInstance(mView.mContext).sendAccessibilityEvent(event);
+ // Check again for accessibility state since this is executed delayed.
+ AccessibilityManager accessibilityManager =
+ AccessibilityManager.getInstance(mView.mContext);
+ if (accessibilityManager.isEnabled()) {
+ // Send the event directly since we do not want to append the
+ // source text because this is the text for the entire window
+ // and we just want to notify that the content has changed.
+ AccessibilityEvent event = AccessibilityEvent.obtain(
+ AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
+ mView.onInitializeAccessibilityEvent(event);
+ accessibilityManager.sendAccessibilityEvent(event);
+ }
mIsPending = false;
}
}
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index f3a5050001ea..dbcbd6e5ae1f 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -19,6 +19,8 @@ package android.view;
import android.app.AppGlobals;
import android.content.Context;
import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.os.RemoteException;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.SparseArray;
@@ -219,6 +221,9 @@ public class ViewConfiguration {
private final int mOverscrollDistance;
private final int mOverflingDistance;
+ private boolean sHasPermanentMenuKey;
+ private boolean sHasPermanentMenuKeySet;
+
private static final SparseArray<ViewConfiguration> sConfigurations =
new SparseArray<ViewConfiguration>(2);
@@ -254,11 +259,12 @@ public class ViewConfiguration {
* @see android.util.DisplayMetrics
*/
private ViewConfiguration(Context context) {
- final DisplayMetrics metrics = context.getResources().getDisplayMetrics();
+ final Resources res = context.getResources();
+ final DisplayMetrics metrics = res.getDisplayMetrics();
+ final Configuration config = res.getConfiguration();
final float density = metrics.density;
final float sizeAndDensity;
- if (context.getResources().getConfiguration().isLayoutSizeAtLeast(
- Configuration.SCREENLAYOUT_SIZE_XLARGE)) {
+ if (config.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_XLARGE)) {
sizeAndDensity = density * 1.5f;
} else {
sizeAndDensity = density;
@@ -280,6 +286,17 @@ public class ViewConfiguration {
mOverscrollDistance = (int) (sizeAndDensity * OVERSCROLL_DISTANCE + 0.5f);
mOverflingDistance = (int) (sizeAndDensity * OVERFLING_DISTANCE + 0.5f);
+
+ if (!sHasPermanentMenuKeySet) {
+ IWindowManager wm = Display.getWindowManager();
+ try {
+ sHasPermanentMenuKey = wm.canStatusBarHide() && !res.getBoolean(
+ com.android.internal.R.bool.config_showNavigationBar);
+ sHasPermanentMenuKeySet = true;
+ } catch (RemoteException ex) {
+ sHasPermanentMenuKey = false;
+ }
+ }
}
/**
@@ -640,4 +657,20 @@ public class ViewConfiguration {
public static float getScrollFriction() {
return SCROLL_FRICTION;
}
+
+ /**
+ * Report if the device has a permanent menu key available to the user.
+ *
+ * <p>As of Android 3.0, devices may not have a permanent menu key available.
+ * Apps should use the action bar to present menu options to users.
+ * However, there are some apps where the action bar is inappropriate
+ * or undesirable. This method may be used to detect if a menu key is present.
+ * If not, applications should provide another on-screen affordance to access
+ * functionality.
+ *
+ * @return true if a permanent menu key is present, false otherwise.
+ */
+ public boolean hasPermanentMenuKey() {
+ return sHasPermanentMenuKey;
+ }
}
diff --git a/core/java/android/webkit/L10nUtils.java b/core/java/android/webkit/L10nUtils.java
index 5b4fb1df72de..4c42cde5b693 100644
--- a/core/java/android/webkit/L10nUtils.java
+++ b/core/java/android/webkit/L10nUtils.java
@@ -70,7 +70,11 @@ public class L10nUtils {
com.android.internal.R.string.autofill_expiration_month_re, // IDS_AUTOFILL_EXPIRATION_MONTH_RE
com.android.internal.R.string.autofill_expiration_date_re, // IDS_AUTOFILL_EXPIRATION_DATE_RE
com.android.internal.R.string.autofill_card_ignored_re, // IDS_AUTOFILL_CARD_IGNORED_RE
- com.android.internal.R.string.autofill_fax_re // IDS_AUTOFILL_FAX_RE
+ com.android.internal.R.string.autofill_fax_re, // IDS_AUTOFILL_FAX_RE
+ com.android.internal.R.string.autofill_country_code_re, // IDS_AUTOFILL_COUNTRY_CODE_RE
+ com.android.internal.R.string.autofill_area_code_notext_re, // IDS_AUTOFILL_AREA_CODE_NOTEXT_RE
+ com.android.internal.R.string.autofill_phone_prefix_separator_re, // IDS_AUTOFILL_PHONE_PREFIX_SEPARATOR_RE
+ com.android.internal.R.string.autofill_phone_suffix_separator_re // IDS_AUTOFILL_PHONE_SUFFIX_SEPARATOR_RE
};
private static Context mApplicationContext;
diff --git a/core/java/com/android/internal/net/VpnConfig.java b/core/java/com/android/internal/net/VpnConfig.java
index 773be5bc2b21..572a1d761d65 100644
--- a/core/java/com/android/internal/net/VpnConfig.java
+++ b/core/java/com/android/internal/net/VpnConfig.java
@@ -23,6 +23,8 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
+import java.util.List;
+
/**
* A simple container used to carry information in VpnBuilder, VpnDialogs,
* and com.android.server.connectivity.Vpn. Internal use only.
@@ -33,12 +35,6 @@ public class VpnConfig implements Parcelable {
public static final String ACTION_VPN_REVOKED = "android.net.vpn.action.REVOKED";
- public static void enforceCallingPackage(String packageName) {
- if (!"com.android.vpndialogs".equals(packageName)) {
- throw new SecurityException("Unauthorized Caller");
- }
- }
-
public static Intent getIntentForConfirmation() {
Intent intent = new Intent();
intent.setClassName("com.android.vpndialogs", "com.android.vpndialogs.ConfirmDialog");
@@ -58,11 +54,12 @@ public class VpnConfig implements Parcelable {
public String packageName;
public String sessionName;
public String interfaceName;
- public String configureActivity;
+ public PendingIntent configureIntent;
public int mtu = -1;
public String addresses;
public String routes;
- public String dnsServers;
+ public List<String> dnsServers;
+ public List<String> searchDomains;
public long startTime = -1;
@Override
@@ -75,11 +72,12 @@ public class VpnConfig implements Parcelable {
out.writeString(packageName);
out.writeString(sessionName);
out.writeString(interfaceName);
- out.writeString(configureActivity);
+ out.writeParcelable(configureIntent, flags);
out.writeInt(mtu);
out.writeString(addresses);
out.writeString(routes);
- out.writeString(dnsServers);
+ out.writeStringList(dnsServers);
+ out.writeStringList(searchDomains);
out.writeLong(startTime);
}
@@ -91,11 +89,12 @@ public class VpnConfig implements Parcelable {
config.packageName = in.readString();
config.sessionName = in.readString();
config.interfaceName = in.readString();
- config.configureActivity = in.readString();
+ config.configureIntent = in.readParcelable(null);
config.mtu = in.readInt();
config.addresses = in.readString();
config.routes = in.readString();
- config.dnsServers = in.readString();
+ config.dnsServers = in.createStringArrayList();
+ config.searchDomains = in.createStringArrayList();
config.startTime = in.readLong();
return config;
}
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index 322a8545d559..2fec9cd09f5b 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -26,6 +26,7 @@ import android.view.MenuItem;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.View.MeasureSpec;
+import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.ImageButton;
@@ -69,9 +70,7 @@ public class ActionMenuPresenter extends BaseMenuPresenter {
final Resources res = context.getResources();
if (!mReserveOverflowSet) {
- // TODO Use the no-buttons specifier instead here
- mReserveOverflow = res.getConfiguration()
- .isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE);
+ mReserveOverflow = !ViewConfiguration.get(context).hasPermanentMenuKey();
}
if (!mWidthLimitSet) {
diff --git a/core/res/res/layout-land/ssl_certificate.xml b/core/res/res/layout-land/ssl_certificate.xml
index 56e4e70ca033..c3e6deb832e3 100644
--- a/core/res/res/layout-land/ssl_certificate.xml
+++ b/core/res/res/layout-land/ssl_certificate.xml
@@ -20,6 +20,7 @@
android:layout_height="wrap_content" >
<LinearLayout
+ android:id="@+id/body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
diff --git a/core/res/res/layout/ssl_certificate.xml b/core/res/res/layout/ssl_certificate.xml
index 7206077ce6f5..ae661ce8ef67 100644
--- a/core/res/res/layout/ssl_certificate.xml
+++ b/core/res/res/layout/ssl_certificate.xml
@@ -20,6 +20,7 @@
android:layout_height="wrap_content" >
<LinearLayout
+ android:id="@+id/body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 827153e7243e..2c10b3dabe8f 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -658,4 +658,8 @@
This is intended to allow packaging drivers or tools for installation on a PC. -->
<string translatable="false" name="config_isoImagePath"></string>
+ <!-- Whether a software navigation bar should be shown. NOTE: in the future this may be
+ autodetected from the Configuration. -->
+ <bool name="config_showNavigationBar">false</bool>
+
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 88ed9c6bc586..29fca74c4e14 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2073,6 +2073,18 @@
<!-- Do not translate. Regex used by AutoFill. -->
<string name="autofill_fax_re">fax<!-- fr-FR -->|télécopie|telecopie<!-- ja-JP -->|ファックス<!-- ru -->|факс<!-- zh-CN -->|传真<!-- zh-TW -->|傳真</string>
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_country_code_re">country.*code|ccode|_cc</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_area_code_notext_re">^\($</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_phone_prefix_separator_re">^-$|^\)$</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_phone_suffix_separator_re">^-$</string>
+
<!-- Title of an application permission, listed so the user can choose whether
they want to allow the application to do this. -->
<string name="permlab_readHistoryBookmarks">read Browser\'s history and bookmarks</string>
@@ -2788,10 +2800,10 @@
<string name="l2tp_ipsec_psk_vpn_description">Pre-shared key based L2TP/IPSec VPN</string>
<string name="l2tp_ipsec_crt_vpn_description">Certificate based L2TP/IPSec VPN</string>
- <!-- Ticker text to show when VPN is active. -->
- <string name="vpn_ticker"><xliff:g id="app" example="FooVPN client">%s</xliff:g> is activating VPN...</string>
<!-- The title of the notification when VPN is active. -->
- <string name="vpn_title">VPN is activated by <xliff:g id="app" example="FooVPN client">%s</xliff:g></string>
+ <string name="vpn_title">VPN is activated.</string>
+ <!-- The title of the notification when VPN is active with an application name. -->
+ <string name="vpn_title_long">VPN is activated by <xliff:g id="app" example="FooVPN client">%s</xliff:g></string>
<!-- The text of the notification when VPN is active. -->
<string name="vpn_text">Tap to manage the network.</string>
<!-- The text of the notification when VPN is active with a session name. -->
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index c82fb9b77ed4..e36360c167a8 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -139,7 +139,7 @@ public:
// setFrameAvailableListener sets the listener object that will be notified
// when a new frame becomes available.
- void setFrameAvailableListener(const sp<FrameAvailableListener>& l);
+ void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);
// getAllocator retrieves the binder object that must be referenced as long
// as the GraphicBuffers dequeued from this SurfaceTexture are referenced.
@@ -343,7 +343,7 @@ private:
uint32_t mNextTransform;
// mTexName is the name of the OpenGL texture to which streamed images will
- // be bound when updateTexImage is called. It is set at construction time
+ // be bound when updateTexImage is called. It is set at construction time
// changed with a call to setTexName.
const GLuint mTexName;
diff --git a/include/media/stagefright/MediaSource.h b/include/media/stagefright/MediaSource.h
index a31395ed9509..37dbcd8eae84 100644
--- a/include/media/stagefright/MediaSource.h
+++ b/include/media/stagefright/MediaSource.h
@@ -22,6 +22,7 @@
#include <media/stagefright/MediaErrors.h>
#include <utils/RefBase.h>
+#include <utils/Vector.h>
namespace android {
@@ -99,6 +100,15 @@ struct MediaSource : public RefBase {
return ERROR_UNSUPPORTED;
}
+ // The consumer of this media source requests that the given buffers
+ // are to be returned exclusively in response to read calls.
+ // This will be called after a successful start() and before the
+ // first read() call.
+ // Callee assumes ownership of the buffers if no error is returned.
+ virtual status_t setBuffers(const Vector<MediaBuffer *> &buffers) {
+ return ERROR_UNSUPPORTED;
+ }
+
protected:
virtual ~MediaSource();
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index 99b72ad86415..57f678c75512 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -121,6 +121,8 @@ enum {
// To store the timed text format data
kKeyTextFormatData = 'text', // raw data
+
+ kKeyRequiresSecureBuffers = 'secu', // bool (int32_t)
};
enum {
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 92331a16f96a..7f3c497ecb32 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -53,6 +53,9 @@ struct OMXCodec : public MediaSource,
// Enable GRALLOC_USAGE_PROTECTED for output buffers from native window
kEnableGrallocUsageProtected = 128,
+
+ // Secure decoding mode
+ kUseSecureInputBuffers = 256,
};
static sp<MediaSource> Create(
const sp<IOMX> &omx,
@@ -164,6 +167,10 @@ private:
bool mOMXLivesLocally;
IOMX::node_id mNode;
uint32_t mQuirks;
+
+ // Flags specified in the creation of the codec.
+ uint32_t mFlags;
+
bool mIsEncoder;
char *mMIME;
char *mComponentName;
@@ -205,15 +212,12 @@ private:
List<size_t> mFilledBuffers;
Condition mBufferFilled;
- bool mIsMetaDataStoredInVideoBuffers;
- bool mOnlySubmitOneBufferAtOneTime;
- bool mEnableGrallocUsageProtected;
-
// Used to record the decoding time for an output picture from
// a video encoder.
List<int64_t> mDecodingTimeList;
- OMXCodec(const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks,
+ OMXCodec(const sp<IOMX> &omx, IOMX::node_id node,
+ uint32_t quirks, uint32_t flags,
bool isEncoder, const char *mime, const char *componentName,
const sp<MediaSource> &source,
const sp<ANativeWindow> &nativeWindow);
@@ -287,6 +291,10 @@ private:
void drainInputBuffers();
void fillOutputBuffers();
+ bool drainAnyInputBuffer();
+ BufferInfo *findInputBufferByDataPointer(void *ptr);
+ BufferInfo *findEmptyInputBuffer();
+
// Returns true iff a flush was initiated and a completion event is
// upcoming, false otherwise (A flush was not necessary as we own all
// the buffers on that port).
@@ -313,7 +321,7 @@ private:
void dumpPortStatus(OMX_U32 portIndex);
- status_t configureCodec(const sp<MetaData> &meta, uint32_t flags);
+ status_t configureCodec(const sp<MetaData> &meta);
static uint32_t getComponentQuirks(
const char *componentName, bool isEncoder);
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 0925001965dd..3bf6477cf208 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -148,6 +148,11 @@ status_t SurfaceTexture::setBufferCount(int bufferCount) {
LOGV("SurfaceTexture::setBufferCount");
Mutex::Autolock lock(mMutex);
+ if (bufferCount > NUM_BUFFER_SLOTS) {
+ LOGE("setBufferCount: bufferCount larger than slots available");
+ return BAD_VALUE;
+ }
+
// Error out if the user has dequeued buffers
for (int i=0 ; i<mBufferCount ; i++) {
if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) {
@@ -208,7 +213,7 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
uint32_t format, uint32_t usage) {
LOGV("SurfaceTexture::dequeueBuffer");
- if ((w && !h) || (!w & h)) {
+ if ((w && !h) || (!w && h)) {
LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h);
return BAD_VALUE;
}
@@ -699,10 +704,10 @@ nsecs_t SurfaceTexture::getTimestamp() {
}
void SurfaceTexture::setFrameAvailableListener(
- const sp<FrameAvailableListener>& l) {
+ const sp<FrameAvailableListener>& listener) {
LOGV("SurfaceTexture::setFrameAvailableListener");
Mutex::Autolock lock(mMutex);
- mFrameAvailableListener = l;
+ mFrameAvailableListener = listener;
}
sp<IBinder> SurfaceTexture::getAllocator() {
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index ffc3346da993..29dec6373b19 100755
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -205,7 +205,7 @@ public class GpsNetInitiatedHandler {
mNiNotification.defaults &= ~Notification.DEFAULT_SOUND;
}
- mNiNotification.flags = Notification.FLAG_ONGOING_EVENT;
+ mNiNotification.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_AUTO_CANCEL;
mNiNotification.tickerText = getNotifTicker(notif, mContext);
// if not to popup dialog immediately, pending intent will open the dialog
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index e36b01fbd7a8..1ac2c1fbbfb4 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -477,6 +477,15 @@ sp<MediaSource> OMXCodec::Create(
const char *matchComponentName,
uint32_t flags,
const sp<ANativeWindow> &nativeWindow) {
+ int32_t requiresSecureBuffers;
+ if (source->getFormat()->findInt32(
+ kKeyRequiresSecureBuffers,
+ &requiresSecureBuffers)
+ && requiresSecureBuffers) {
+ flags |= kIgnoreCodecSpecificData;
+ flags |= kUseSecureInputBuffers;
+ }
+
const char *mime;
bool success = meta->findCString(kKeyMIMEType, &mime);
CHECK(success);
@@ -530,17 +539,17 @@ sp<MediaSource> OMXCodec::Create(
LOGV("Successfully allocated OMX node '%s'", componentName);
sp<OMXCodec> codec = new OMXCodec(
- omx, node, quirks,
+ omx, node, quirks, flags,
createEncoder, mime, componentName,
source, nativeWindow);
observer->setCodec(codec);
- err = codec->configureCodec(meta, flags);
+ err = codec->configureCodec(meta);
if (err == OK) {
if (!strcmp("OMX.Nvidia.mpeg2v.decode", componentName)) {
- codec->mOnlySubmitOneBufferAtOneTime = true;
+ codec->mFlags |= kOnlySubmitOneInputBufferAtOneTime;
}
return codec;
@@ -553,24 +562,11 @@ sp<MediaSource> OMXCodec::Create(
return NULL;
}
-status_t OMXCodec::configureCodec(const sp<MetaData> &meta, uint32_t flags) {
- mIsMetaDataStoredInVideoBuffers = false;
- if (flags & kStoreMetaDataInVideoBuffers) {
- mIsMetaDataStoredInVideoBuffers = true;
- }
-
- mOnlySubmitOneBufferAtOneTime = false;
- if (flags & kOnlySubmitOneInputBufferAtOneTime) {
- mOnlySubmitOneBufferAtOneTime = true;
- }
+status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
+ LOGV("configureCodec protected=%d",
+ (mFlags & kEnableGrallocUsageProtected) ? 1 : 0);
- mEnableGrallocUsageProtected = false;
- if (flags & kEnableGrallocUsageProtected) {
- mEnableGrallocUsageProtected = true;
- }
- LOGV("configureCodec protected=%d", mEnableGrallocUsageProtected);
-
- if (!(flags & kIgnoreCodecSpecificData)) {
+ if (!(mFlags & kIgnoreCodecSpecificData)) {
uint32_t type;
const void *data;
size_t size;
@@ -745,7 +741,7 @@ status_t OMXCodec::configureCodec(const sp<MetaData> &meta, uint32_t flags) {
initOutputFormat(meta);
- if ((flags & kClientNeedsFramebuffer)
+ if ((mFlags & kClientNeedsFramebuffer)
&& !strncmp(mComponentName, "OMX.SEC.", 8)) {
OMX_INDEXTYPE index;
@@ -1468,7 +1464,8 @@ status_t OMXCodec::setVideoOutputFormat(
}
OMXCodec::OMXCodec(
- const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks,
+ const sp<IOMX> &omx, IOMX::node_id node,
+ uint32_t quirks, uint32_t flags,
bool isEncoder,
const char *mime,
const char *componentName,
@@ -1478,6 +1475,7 @@ OMXCodec::OMXCodec(
mOMXLivesLocally(omx->livesLocally(getpid())),
mNode(node),
mQuirks(quirks),
+ mFlags(flags),
mIsEncoder(isEncoder),
mMIME(strdup(mime)),
mComponentName(strdup(componentName)),
@@ -1645,13 +1643,14 @@ status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
return allocateOutputBuffersFromNativeWindow();
}
- if (mEnableGrallocUsageProtected && portIndex == kPortIndexOutput) {
+ if ((mFlags & kEnableGrallocUsageProtected) && portIndex == kPortIndexOutput) {
LOGE("protected output buffers must be stent to an ANativeWindow");
return PERMISSION_DENIED;
}
status_t err = OK;
- if (mIsMetaDataStoredInVideoBuffers && portIndex == kPortIndexInput) {
+ if ((mFlags & kStoreMetaDataInVideoBuffers)
+ && portIndex == kPortIndexInput) {
err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
if (err != OK) {
LOGE("Storing meta data in video buffers is not supported");
@@ -1687,7 +1686,8 @@ status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
IOMX::buffer_id buffer;
if (portIndex == kPortIndexInput
- && (mQuirks & kRequiresAllocateBufferOnInputPorts)) {
+ && ((mQuirks & kRequiresAllocateBufferOnInputPorts)
+ || (mFlags & kUseSecureInputBuffers))) {
if (mOMXLivesLocally) {
mem.clear();
@@ -1748,6 +1748,31 @@ status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
// dumpPortStatus(portIndex);
+ if (portIndex == kPortIndexInput && (mFlags & kUseSecureInputBuffers)) {
+ Vector<MediaBuffer *> buffers;
+ for (size_t i = 0; i < def.nBufferCountActual; ++i) {
+ const BufferInfo &info = mPortBuffers[kPortIndexInput].itemAt(i);
+
+ MediaBuffer *mbuf = new MediaBuffer(info.mData, info.mSize);
+ buffers.push(mbuf);
+ }
+
+ status_t err = mSource->setBuffers(buffers);
+
+ if (err != OK) {
+ for (size_t i = 0; i < def.nBufferCountActual; ++i) {
+ buffers.editItemAt(i)->release();
+ }
+ buffers.clear();
+
+ CODEC_LOGE(
+ "Codec requested to use secure input buffers but "
+ "upstream source didn't support that.");
+
+ return err;
+ }
+ }
+
return OK;
}
@@ -1815,7 +1840,7 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() {
// XXX: Currently this error is logged, but not fatal.
usage = 0;
}
- if (mEnableGrallocUsageProtected) {
+ if (mFlags & kEnableGrallocUsageProtected) {
usage |= GRALLOC_USAGE_PROTECTED;
}
@@ -2067,7 +2092,12 @@ void OMXCodec::on_message(const omx_message &msg) {
} else if (mState != ERROR
&& mPortStatus[kPortIndexInput] != SHUTTING_DOWN) {
CHECK_EQ((int)mPortStatus[kPortIndexInput], (int)ENABLED);
- drainInputBuffer(&buffers->editItemAt(i));
+
+ if (mFlags & kUseSecureInputBuffers) {
+ drainAnyInputBuffer();
+ } else {
+ drainInputBuffer(&buffers->editItemAt(i));
+ }
}
break;
}
@@ -2804,32 +2834,81 @@ void OMXCodec::fillOutputBuffers() {
void OMXCodec::drainInputBuffers() {
CHECK(mState == EXECUTING || mState == RECONFIGURING);
- Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
- for (size_t i = 0; i < buffers->size(); ++i) {
- BufferInfo *info = &buffers->editItemAt(i);
+ if (mFlags & kUseSecureInputBuffers) {
+ Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
+ for (size_t i = 0; i < buffers->size(); ++i) {
+ if (!drainAnyInputBuffer()
+ || (mFlags & kOnlySubmitOneInputBufferAtOneTime)) {
+ break;
+ }
+ }
+ } else {
+ Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
+ for (size_t i = 0; i < buffers->size(); ++i) {
+ BufferInfo *info = &buffers->editItemAt(i);
- if (info->mStatus != OWNED_BY_US) {
- continue;
+ if (info->mStatus != OWNED_BY_US) {
+ continue;
+ }
+
+ if (!drainInputBuffer(info)) {
+ break;
+ }
+
+ if (mFlags & kOnlySubmitOneInputBufferAtOneTime) {
+ break;
+ }
}
+ }
+}
- if (!drainInputBuffer(info)) {
- break;
+bool OMXCodec::drainAnyInputBuffer() {
+ return drainInputBuffer((BufferInfo *)NULL);
+}
+
+OMXCodec::BufferInfo *OMXCodec::findInputBufferByDataPointer(void *ptr) {
+ Vector<BufferInfo> *infos = &mPortBuffers[kPortIndexInput];
+ for (size_t i = 0; i < infos->size(); ++i) {
+ BufferInfo *info = &infos->editItemAt(i);
+
+ if (info->mData == ptr) {
+ CODEC_LOGV(
+ "input buffer data ptr = %p, buffer_id = %p",
+ ptr,
+ info->mBuffer);
+
+ return info;
}
+ }
- if (mOnlySubmitOneBufferAtOneTime) {
- break;
+ TRESPASS();
+}
+
+OMXCodec::BufferInfo *OMXCodec::findEmptyInputBuffer() {
+ Vector<BufferInfo> *infos = &mPortBuffers[kPortIndexInput];
+ for (size_t i = 0; i < infos->size(); ++i) {
+ BufferInfo *info = &infos->editItemAt(i);
+
+ if (info->mStatus == OWNED_BY_US) {
+ return info;
}
}
+
+ TRESPASS();
}
bool OMXCodec::drainInputBuffer(BufferInfo *info) {
- CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
+ if (info != NULL) {
+ CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
+ }
if (mSignalledEOS) {
return false;
}
if (mCodecSpecificDataIndex < mCodecSpecificData.size()) {
+ CHECK(!(mFlags & kUseSecureInputBuffers));
+
const CodecSpecificData *specific =
mCodecSpecificData[mCodecSpecificDataIndex];
@@ -2925,6 +3004,11 @@ bool OMXCodec::drainInputBuffer(BufferInfo *info) {
break;
}
+ if (mFlags & kUseSecureInputBuffers) {
+ info = findInputBufferByDataPointer(srcBuffer->data());
+ CHECK(info != NULL);
+ }
+
size_t remainingBytes = info->mSize - offset;
if (srcBuffer->range_length() > remainingBytes) {
@@ -2960,14 +3044,24 @@ bool OMXCodec::drainInputBuffer(BufferInfo *info) {
releaseBuffer = false;
info->mMediaBuffer = srcBuffer;
} else {
- if (mIsMetaDataStoredInVideoBuffers) {
+ if (mFlags & kStoreMetaDataInVideoBuffers) {
releaseBuffer = false;
info->mMediaBuffer = srcBuffer;
}
- memcpy((uint8_t *)info->mData + offset,
- (const uint8_t *)srcBuffer->data()
- + srcBuffer->range_offset(),
- srcBuffer->range_length());
+
+ if (mFlags & kUseSecureInputBuffers) {
+ // Data in "info" is already provided at this time.
+
+ releaseBuffer = false;
+
+ CHECK(info->mMediaBuffer == NULL);
+ info->mMediaBuffer = srcBuffer;
+ } else {
+ memcpy((uint8_t *)info->mData + offset,
+ (const uint8_t *)srcBuffer->data()
+ + srcBuffer->range_offset(),
+ srcBuffer->range_length());
+ }
}
int64_t lastBufferTimeUs;
@@ -3036,6 +3130,16 @@ bool OMXCodec::drainInputBuffer(BufferInfo *info) {
info->mBuffer, offset,
timestampUs, timestampUs / 1E6);
+ if (info == NULL) {
+ CHECK(mFlags & kUseSecureInputBuffers);
+ CHECK(signalEOS);
+
+ // This is fishy, there's still a MediaBuffer corresponding to this
+ // info available to the source at this point even though we're going
+ // to use it to signal EOS to the codec.
+ info = findEmptyInputBuffer();
+ }
+
err = mOMX->emptyBuffer(
mNode, info->mBuffer, 0, offset,
flags, timestampUs);
diff --git a/media/libstagefright/WVMExtractor.cpp b/media/libstagefright/WVMExtractor.cpp
index 7072d58d6cce..26eda0c4cfb1 100644
--- a/media/libstagefright/WVMExtractor.cpp
+++ b/media/libstagefright/WVMExtractor.cpp
@@ -33,25 +33,26 @@
#include <utils/Errors.h>
+/* The extractor lifetime is short - just long enough to get
+ * the media sources constructed - so the shared lib needs to remain open
+ * beyond the lifetime of the extractor. So keep the handle as a global
+ * rather than a member of the extractor
+ */
+void *gVendorLibHandle = NULL;
+
namespace android {
-Mutex WVMExtractor::sMutex;
-uint32_t WVMExtractor::sActiveExtractors = 0;
-void *WVMExtractor::sVendorLibHandle = NULL;
+static Mutex gWVMutex;
WVMExtractor::WVMExtractor(const sp<DataSource> &source)
: mDataSource(source) {
{
- Mutex::Autolock autoLock(sMutex);
-
- if (sVendorLibHandle == NULL) {
- CHECK(sActiveExtractors == 0);
- sVendorLibHandle = dlopen("libwvm.so", RTLD_NOW);
+ Mutex::Autolock autoLock(gWVMutex);
+ if (gVendorLibHandle == NULL) {
+ gVendorLibHandle = dlopen("libwvm.so", RTLD_NOW);
}
- sActiveExtractors++;
-
- if (sVendorLibHandle == NULL) {
+ if (gVendorLibHandle == NULL) {
LOGE("Failed to open libwvm.so");
return;
}
@@ -59,7 +60,7 @@ WVMExtractor::WVMExtractor(const sp<DataSource> &source)
typedef WVMLoadableExtractor *(*GetInstanceFunc)(sp<DataSource>);
GetInstanceFunc getInstanceFunc =
- (GetInstanceFunc) dlsym(sVendorLibHandle,
+ (GetInstanceFunc) dlsym(gVendorLibHandle,
"_ZN7android11GetInstanceENS_2spINS_10DataSourceEEE");
if (getInstanceFunc) {
@@ -71,17 +72,6 @@ WVMExtractor::WVMExtractor(const sp<DataSource> &source)
}
WVMExtractor::~WVMExtractor() {
- Mutex::Autolock autoLock(sMutex);
-
- CHECK(sActiveExtractors > 0);
- sActiveExtractors--;
-
- // Close lib after last use
- if (sActiveExtractors == 0) {
- if (sVendorLibHandle != NULL)
- dlclose(sVendorLibHandle);
- sVendorLibHandle = NULL;
- }
}
size_t WVMExtractor::countTracks() {
diff --git a/media/libstagefright/chromium_http/support.cpp b/media/libstagefright/chromium_http/support.cpp
index 967f126c8adf..f4b36688f4cd 100644
--- a/media/libstagefright/chromium_http/support.cpp
+++ b/media/libstagefright/chromium_http/support.cpp
@@ -115,31 +115,31 @@ SfRequestContext::SfRequestContext() {
mUserAgent = ua.c_str();
- net_log_ = new SfNetLog;
+ set_net_log(new SfNetLog());
- host_resolver_ =
+ set_host_resolver(
net::CreateSystemHostResolver(
net::HostResolver::kDefaultParallelism,
NULL /* resolver_proc */,
- net_log_);
+ net_log()));
- ssl_config_service_ =
- net::SSLConfigService::CreateSystemSSLConfigService();
+ set_ssl_config_service(
+ net::SSLConfigService::CreateSystemSSLConfigService());
- proxy_service_ = net::ProxyService::CreateWithoutProxyResolver(
- new net::ProxyConfigServiceAndroid, net_log_);
+ set_proxy_service(net::ProxyService::CreateWithoutProxyResolver(
+ new net::ProxyConfigServiceAndroid, net_log()));
- http_transaction_factory_ = new net::HttpCache(
- host_resolver_,
+ set_http_transaction_factory(new net::HttpCache(
+ host_resolver(),
new net::CertVerifier(),
- dnsrr_resolver_,
- dns_cert_checker_.get(),
- proxy_service_.get(),
- ssl_config_service_.get(),
- net::HttpAuthHandlerFactory::CreateDefault(host_resolver_),
- network_delegate_,
- net_log_,
- NULL); // backend_factory
+ dnsrr_resolver(),
+ dns_cert_checker(),
+ proxy_service(),
+ ssl_config_service(),
+ net::HttpAuthHandlerFactory::CreateDefault(host_resolver()),
+ network_delegate(),
+ net_log(),
+ NULL)); // backend_factory
}
const std::string &SfRequestContext::GetUserAgent(const GURL &url) const {
diff --git a/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp b/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp
index e3292e63c679..009676011714 100644
--- a/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp
+++ b/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp
@@ -475,7 +475,9 @@ status_t AVCEncoder::read(
}
status_t err = mSource->read(&mInputBuffer, options);
if (err != OK) {
- LOGE("Failed to read input video frame: %d", err);
+ if (err != ERROR_END_OF_STREAM) {
+ LOGE("Failed to read input video frame: %d", err);
+ }
outputBuffer->release();
return err;
}
diff --git a/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp
index 15ed2193ae61..d7249c1ebb4f 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp
@@ -398,10 +398,13 @@ status_t M4vH263Encoder::read(
}
// Ready for accepting an input video frame
- if (OK != mSource->read(&mInputBuffer, options)) {
- LOGE("Failed to read from data source");
+ status_t err = mSource->read(&mInputBuffer, options);
+ if (OK != err) {
+ if (err != ERROR_END_OF_STREAM) {
+ LOGE("Failed to read from data source");
+ }
outputBuffer->release();
- return UNKNOWN_ERROR;
+ return err;
}
if (mInputBuffer->size() - ((mVideoWidth * mVideoHeight * 3) >> 1) != 0) {
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 165683e986b6..f1a2a60b9495 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -408,13 +408,20 @@ rinse_repeat:
if (firstTime) {
Mutex::Autolock autoLock(mLock);
- int32_t targetDuration;
- if (!mPlaylist->isComplete()
- || !mPlaylist->meta()->findInt32(
- "target-duration", &targetDuration)) {
+ if (!mPlaylist->isComplete()) {
mDurationUs = -1;
} else {
- mDurationUs = 1000000ll * targetDuration * mPlaylist->size();
+ mDurationUs = 0;
+ for (size_t i = 0; i < mPlaylist->size(); ++i) {
+ sp<AMessage> itemMeta;
+ CHECK(mPlaylist->itemAt(
+ i, NULL /* uri */, &itemMeta));
+
+ int64_t itemDurationUs;
+ CHECK(itemMeta->findInt64("durationUs", &itemDurationUs));
+
+ mDurationUs += itemDurationUs;
+ }
}
}
@@ -431,14 +438,26 @@ rinse_repeat:
bool bandwidthChanged = false;
if (mSeekTimeUs >= 0) {
- int32_t targetDuration;
- if (mPlaylist->isComplete() &&
- mPlaylist->meta()->findInt32(
- "target-duration", &targetDuration)) {
- int64_t seekTimeSecs = (mSeekTimeUs + 500000ll) / 1000000ll;
- int64_t index = seekTimeSecs / targetDuration;
-
- if (index >= 0 && index < mPlaylist->size()) {
+ if (mPlaylist->isComplete()) {
+ size_t index = 0;
+ int64_t segmentStartUs = 0;
+ while (index < mPlaylist->size()) {
+ sp<AMessage> itemMeta;
+ CHECK(mPlaylist->itemAt(
+ index, NULL /* uri */, &itemMeta));
+
+ int64_t itemDurationUs;
+ CHECK(itemMeta->findInt64("durationUs", &itemDurationUs));
+
+ if (mSeekTimeUs < segmentStartUs + itemDurationUs) {
+ break;
+ }
+
+ segmentStartUs += itemDurationUs;
+ ++index;
+ }
+
+ if (index < mPlaylist->size()) {
int32_t newSeqNumber = firstSeqNumberInPlaylist + index;
if (newSeqNumber != mSeqNumber) {
diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp
index 765f79565d5a..123fbf8b23e4 100644
--- a/media/libstagefright/httplive/M3UParser.cpp
+++ b/media/libstagefright/httplive/M3UParser.cpp
@@ -64,14 +64,21 @@ size_t M3UParser::size() {
}
bool M3UParser::itemAt(size_t index, AString *uri, sp<AMessage> *meta) {
- uri->clear();
- if (meta) { *meta = NULL; }
+ if (uri) {
+ uri->clear();
+ }
+
+ if (meta) {
+ *meta = NULL;
+ }
if (index >= mItems.size()) {
return false;
}
- *uri = mItems.itemAt(index).mURI;
+ if (uri) {
+ *uri = mItems.itemAt(index).mURI;
+ }
if (meta) {
*meta = mItems.itemAt(index).mMeta;
diff --git a/media/libstagefright/include/WVMExtractor.h b/media/libstagefright/include/WVMExtractor.h
index 0817babb45e0..deecd2543a92 100644
--- a/media/libstagefright/include/WVMExtractor.h
+++ b/media/libstagefright/include/WVMExtractor.h
@@ -18,7 +18,6 @@
#define WVM_EXTRACTOR_H_
-#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaExtractor.h>
#include <utils/Errors.h>
@@ -68,10 +67,6 @@ private:
WVMExtractor(const WVMExtractor &);
WVMExtractor &operator=(const WVMExtractor &);
-
- static Mutex sMutex;
- static uint32_t sActiveExtractors;
- static void *sVendorLibHandle;
};
} // namespace android
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 7a4ac5d816f6..5298f2e66927 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -36,10 +36,6 @@
<!-- Whether or not we show the number in the bar. -->
<bool name="config_statusBarShowNumber">true</bool>
- <!-- Whether a software navigation bar should be shown. NOTE: in the future this may be
- autodetected from the Configuration. -->
- <bool name="config_showNavigationBar">false</bool>
-
<!-- How many icons may be shown at once in the system bar. Includes any
slots that may be reused for things like IME control. -->
<integer name="config_maxNotificationIcons">5</integer>
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 d8474db3c2ef..4c7b0dd2ca54 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -246,7 +246,7 @@ public class PhoneStatusBar extends StatusBar {
mIntruderAlertView.setClickable(true);
try {
- boolean showNav = res.getBoolean(R.bool.config_showNavigationBar);
+ boolean showNav = res.getBoolean(com.android.internal.R.bool.config_showNavigationBar);
if (showNav) {
mNavigationBarView =
(NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
diff --git a/packages/VpnDialogs/Android.mk b/packages/VpnDialogs/Android.mk
index 89f010aaebcb..ac84125f8f4e 100644
--- a/packages/VpnDialogs/Android.mk
+++ b/packages/VpnDialogs/Android.mk
@@ -20,6 +20,8 @@ include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
+LOCAL_CERTIFICATE := platform
+
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := VpnDialogs
diff --git a/packages/VpnDialogs/AndroidManifest.xml b/packages/VpnDialogs/AndroidManifest.xml
index 4e6784ce0884..c0b0a08067cf 100644
--- a/packages/VpnDialogs/AndroidManifest.xml
+++ b/packages/VpnDialogs/AndroidManifest.xml
@@ -1,5 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.vpndialogs">
+ package="com.android.vpndialogs"
+ android:sharedUserId="android.uid.system">
<application android:label="VpnDialogs">
<activity android:name=".ConfirmDialog"
diff --git a/packages/VpnDialogs/res/values/strings.xml b/packages/VpnDialogs/res/values/strings.xml
index 8186e2629173..df6d36bd2814 100644
--- a/packages/VpnDialogs/res/values/strings.xml
+++ b/packages/VpnDialogs/res/values/strings.xml
@@ -29,6 +29,7 @@
<string name="accept">I trust this application.</string>
+ <string name="legacy_title">VPN is connected</string>
<string name="configure">Configure</string>
<string name="disconnect">Disconnect</string>
diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
index ba3f3448f066..c076ba0bfd2f 100644
--- a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
@@ -64,9 +64,6 @@ public class ManageDialog extends Activity implements Handler.Callback,
mService = IConnectivityManager.Stub.asInterface(
ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
- PackageManager pm = getPackageManager();
- ApplicationInfo app = pm.getApplicationInfo(mConfig.packageName, 0);
-
View view = View.inflate(this, R.layout.manage, null);
if (mConfig.sessionName != null) {
((TextView) view.findViewById(R.id.session)).setText(mConfig.sessionName);
@@ -75,15 +72,29 @@ public class ManageDialog extends Activity implements Handler.Callback,
mDataTransmitted = (TextView) view.findViewById(R.id.data_transmitted);
mDataReceived = (TextView) view.findViewById(R.id.data_received);
- mDialog = new AlertDialog.Builder(this)
- .setIcon(app.loadIcon(pm))
- .setTitle(app.loadLabel(pm))
- .setView(view)
- .setNeutralButton(R.string.disconnect, this)
- .setNegativeButton(android.R.string.cancel, this)
- .create();
+ if (mConfig.packageName == null) {
+ // Legacy VPN does not have a package name.
+ mDialog = new AlertDialog.Builder(this)
+ .setIcon(android.R.drawable.ic_dialog_info)
+ .setTitle(R.string.legacy_title)
+ .setView(view)
+ .setNeutralButton(R.string.disconnect, this)
+ .setNegativeButton(android.R.string.cancel, this)
+ .create();
+ } else {
+ PackageManager pm = getPackageManager();
+ ApplicationInfo app = pm.getApplicationInfo(mConfig.packageName, 0);
+
+ mDialog = new AlertDialog.Builder(this)
+ .setIcon(app.loadIcon(pm))
+ .setTitle(app.loadLabel(pm))
+ .setView(view)
+ .setNeutralButton(R.string.disconnect, this)
+ .setNegativeButton(android.R.string.cancel, this)
+ .create();
+ }
- if (mConfig.configureActivity != null) {
+ if (mConfig.configureIntent != null) {
mDialog.setButton(DialogInterface.BUTTON_POSITIVE,
getText(R.string.configure), this);
}
@@ -113,9 +124,7 @@ public class ManageDialog extends Activity implements Handler.Callback,
public void onClick(DialogInterface dialog, int which) {
try {
if (which == AlertDialog.BUTTON_POSITIVE) {
- Intent intent = new Intent();
- intent.setClassName(mConfig.packageName, mConfig.configureActivity);
- startActivity(intent);
+ mConfig.configureIntent.send();
} else if (which == AlertDialog.BUTTON_NEUTRAL) {
mService.prepareVpn("");
}
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp
index 95b8a5723e2f..ca2540bfad20 100644
--- a/services/input/EventHub.cpp
+++ b/services/input/EventHub.cpp
@@ -212,8 +212,8 @@ status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis,
struct input_absinfo info;
if(ioctl(device->fd, EVIOCGABS(axis), &info)) {
- LOGW("Error reading absolute controller %d for device %s fd %d\n",
- axis, device->identifier.name.string(), device->fd);
+ LOGW("Error reading absolute controller %d for device %s fd %d, errno=%d",
+ axis, device->identifier.name.string(), device->fd, errno);
return -errno;
}
@@ -335,6 +335,33 @@ int32_t EventHub::getSwitchStateLocked(Device* device, int32_t sw) const {
return AKEY_STATE_UNKNOWN;
}
+status_t EventHub::getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* outValue) const {
+ if (axis >= 0 && axis <= ABS_MAX) {
+ AutoMutex _l(mLock);
+
+ Device* device = getDeviceLocked(deviceId);
+ if (device != NULL) {
+ return getAbsoluteAxisValueLocked(device, axis, outValue);
+ }
+ }
+ *outValue = 0;
+ return -1;
+}
+
+status_t EventHub::getAbsoluteAxisValueLocked(Device* device, int32_t axis,
+ int32_t* outValue) const {
+ struct input_absinfo info;
+
+ if(ioctl(device->fd, EVIOCGABS(axis), &info)) {
+ LOGW("Error reading absolute controller %d for device %s fd %d, errno=%d",
+ axis, device->identifier.name.string(), device->fd, errno);
+ return -errno;
+ }
+
+ *outValue = info.value;
+ return OK;
+}
+
bool EventHub::markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
const int32_t* keyCodes, uint8_t* outFlags) const {
AutoMutex _l(mLock);
diff --git a/services/input/EventHub.h b/services/input/EventHub.h
index 0a34e45a565c..695dfdfb25e6 100644
--- a/services/input/EventHub.h
+++ b/services/input/EventHub.h
@@ -186,6 +186,8 @@ public:
virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const = 0;
virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const = 0;
virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const = 0;
+ virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
+ int32_t* outValue) const = 0;
/*
* Examine key input devices for specific framework keycode support
@@ -237,6 +239,7 @@ public:
virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const;
virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const;
virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const;
+ virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* outValue) const;
virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
const int32_t* keyCodes, uint8_t* outFlags) const;
@@ -305,6 +308,7 @@ private:
int32_t getScanCodeStateLocked(Device* device, int32_t scanCode) const;
int32_t getKeyCodeStateLocked(Device* device, int32_t keyCode) const;
int32_t getSwitchStateLocked(Device* device, int32_t sw) const;
+ int32_t getAbsoluteAxisValueLocked(Device* device, int32_t axis, int32_t* outValue) const;
bool markSupportedKeyCodesLocked(Device* device, size_t numCodes,
const int32_t* keyCodes, uint8_t* outFlags) const;
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 85ce38ae2020..10b9083549f2 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -1239,8 +1239,9 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
const InputWindow* newHoverWindow = NULL;
bool isSplit = mTouchState.split;
- bool switchedDevice = mTouchState.deviceId != entry->deviceId
- || mTouchState.source != entry->source;
+ bool switchedDevice = mTouchState.deviceId >= 0
+ && (mTouchState.deviceId != entry->deviceId
+ || mTouchState.source != entry->source);
bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
|| maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
|| maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 82c3af370ea8..79218a5581ca 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -5394,7 +5394,6 @@ void SingleTouchInputMapper::configureRawAxes() {
MultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device) :
TouchInputMapper(device), mSlotCount(0), mUsingSlotsProtocol(false) {
- clearState();
}
MultiTouchInputMapper::~MultiTouchInputMapper() {
@@ -5404,6 +5403,24 @@ void MultiTouchInputMapper::clearState() {
mAccumulator.clearSlots(mSlotCount);
mAccumulator.clearButtons();
mButtonState = 0;
+
+ if (mUsingSlotsProtocol) {
+ // Query the driver for the current slot index and use it as the initial slot
+ // before we start reading events from the device. It is possible that the
+ // current slot index will not be the same as it was when the first event was
+ // written into the evdev buffer, which means the input mapper could start
+ // out of sync with the initial state of the events in the evdev buffer.
+ // In the extremely unlikely case that this happens, the data from
+ // two slots will be confused until the next ABS_MT_SLOT event is received.
+ // This can cause the touch point to "jump", but at least there will be
+ // no stuck touches.
+ status_t status = getEventHub()->getAbsoluteAxisValue(getDeviceId(), ABS_MT_SLOT,
+ &mAccumulator.currentSlot);
+ if (status) {
+ LOGW("Could not retrieve current multitouch slot index. status=%d", status);
+ mAccumulator.currentSlot = -1;
+ }
+ }
}
void MultiTouchInputMapper::reset() {
@@ -5682,6 +5699,8 @@ void MultiTouchInputMapper::configureRawAxes() {
}
mAccumulator.allocateSlots(mSlotCount);
+
+ clearState();
}
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index e349248b1c5a..d3c5ece7cbef 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -429,6 +429,7 @@ class FakeEventHub : public EventHubInterface {
KeyedVector<int32_t, int32_t> keyCodeStates;
KeyedVector<int32_t, int32_t> scanCodeStates;
KeyedVector<int32_t, int32_t> switchStates;
+ KeyedVector<int32_t, int32_t> absoluteAxisValue;
KeyedVector<int32_t, KeyInfo> keys;
KeyedVector<int32_t, bool> leds;
Vector<VirtualKeyDefinition> virtualKeys;
@@ -514,6 +515,11 @@ public:
device->switchStates.replaceValueFor(switchCode, state);
}
+ void setAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t value) {
+ Device* device = getDevice(deviceId);
+ device->absoluteAxisValue.replaceValueFor(axis, value);
+ }
+
void addKey(int32_t deviceId, int32_t scanCode, int32_t keyCode, uint32_t flags) {
Device* device = getDevice(deviceId);
KeyInfo info;
@@ -677,6 +683,20 @@ private:
return AKEY_STATE_UNKNOWN;
}
+ virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
+ int32_t* outValue) const {
+ Device* device = getDevice(deviceId);
+ if (device) {
+ ssize_t index = device->absoluteAxisValue.indexOfKey(axis);
+ if (index >= 0) {
+ *outValue = device->absoluteAxisValue.valueAt(index);
+ return OK;
+ }
+ }
+ *outValue = 0;
+ return -1;
+ }
+
virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes,
uint8_t* outFlags) const {
bool result = false;
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 8fb6274a7afb..663f4f47f56e 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -2533,7 +2533,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
private VpnCallback() {
}
- public synchronized void override(String[] dnsServers) {
+ public synchronized void override(List<String> dnsServers, List<String> searchDomains) {
// TODO: override DNS servers and http proxy.
}
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index adc65708d5ef..1c150f8a65ea 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -16,10 +16,11 @@
package com.android.server;
+import static android.Manifest.permission.MANAGE_NETWORK_POLICY;
import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
-import static android.Manifest.permission.MANAGE_NETWORK_POLICY;
+import static android.provider.Settings.Secure.NETSTATS_ENABLED;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -35,6 +36,7 @@ import android.os.Binder;
import android.os.INetworkManagementService;
import android.os.SystemClock;
import android.os.SystemProperties;
+import android.provider.Settings;
import android.util.Log;
import android.util.Slog;
import android.util.SparseBooleanArray;
@@ -123,6 +125,8 @@ class NetworkManagementService extends INetworkManagementService.Stub {
/** Set of UIDs with active reject rules. */
private SparseBooleanArray mUidRejectOnQuota = new SparseBooleanArray();
+ private boolean mBandwidthControlEnabled;
+
/**
* Constructs a new NetworkManagementService instance
*
@@ -161,6 +165,29 @@ class NetworkManagementService extends INetworkManagementService.Stub {
return new NetworkManagementService(context, procRoot);
}
+ public void systemReady() {
+
+ // only enable bandwidth control when support exists, and requested by
+ // system setting.
+ // TODO: eventually migrate to be always enabled
+ final boolean hasKernelSupport = new File("/proc/net/xt_qtaguid/ctrl").exists();
+ final boolean shouldEnable =
+ Settings.Secure.getInt(mContext.getContentResolver(), NETSTATS_ENABLED, 0) != 0;
+
+ mBandwidthControlEnabled = false;
+ if (hasKernelSupport && shouldEnable) {
+ Slog.d(TAG, "enabling bandwidth control");
+ try {
+ mConnector.doCommand("bandwidth enable");
+ mBandwidthControlEnabled = true;
+ } catch (NativeDaemonConnectorException e) {
+ Slog.e(TAG, "problem enabling bandwidth controls", e);
+ }
+ } else {
+ Slog.d(TAG, "not enabling bandwidth control");
+ }
+ }
+
public void registerObserver(INetworkManagementEventObserver obs) {
Slog.d(TAG, "Registering observer");
mObservers.add(obs);
@@ -919,7 +946,7 @@ class NetworkManagementService extends INetworkManagementService.Stub {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
- if (mProcStatsNetfilter.exists()) {
+ if (mBandwidthControlEnabled) {
return getNetworkStatsDetailNetfilter(UID_ALL);
} else {
return getNetworkStatsDetailUidstat(UID_ALL);
@@ -930,6 +957,10 @@ class NetworkManagementService extends INetworkManagementService.Stub {
public void setInterfaceQuota(String iface, long quota) {
mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
+ // silently discard when control disabled
+ // TODO: eventually migrate to be always enabled
+ if (!mBandwidthControlEnabled) return;
+
synchronized (mInterfaceQuota) {
if (mInterfaceQuota.contains(iface)) {
// TODO: eventually consider throwing
@@ -953,6 +984,10 @@ class NetworkManagementService extends INetworkManagementService.Stub {
public void removeInterfaceQuota(String iface) {
mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
+ // silently discard when control disabled
+ // TODO: eventually migrate to be always enabled
+ if (!mBandwidthControlEnabled) return;
+
synchronized (mInterfaceQuota) {
if (!mInterfaceQuota.contains(iface)) {
// TODO: eventually consider throwing
@@ -976,6 +1011,10 @@ class NetworkManagementService extends INetworkManagementService.Stub {
public void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces) {
mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
+ // silently discard when control disabled
+ // TODO: eventually migrate to be always enabled
+ if (!mBandwidthControlEnabled) return;
+
synchronized (mUidRejectOnQuota) {
final boolean oldRejectOnQuota = mUidRejectOnQuota.get(uid, false);
if (oldRejectOnQuota == rejectOnQuotaInterfaces) {
@@ -1011,7 +1050,7 @@ class NetworkManagementService extends INetworkManagementService.Stub {
android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
}
- if (mProcStatsNetfilter.exists()) {
+ if (mBandwidthControlEnabled) {
return getNetworkStatsDetailNetfilter(uid);
} else {
return getNetworkStatsDetailUidstat(uid);
@@ -1151,12 +1190,6 @@ class NetworkManagementService extends INetworkManagementService.Stub {
return getInterfaceThrottle(iface, false);
}
- @Override
- public void setBandwidthControlEnabled(boolean enabled) {
- mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
- mConnector.doCommand(String.format("bandwidth %s", (enabled ? "enable" : "disable")));
- }
-
/**
* Split given line into {@link ArrayList}.
*/
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index dbfd145bc65f..8c7e279b7132 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -523,6 +523,7 @@ class ServerThread extends Thread {
// These are needed to propagate to the runnable below.
final Context contextF = context;
final BatteryService batteryF = battery;
+ final NetworkManagementService networkManagementF = networkManagement;
final NetworkStatsService networkStatsF = networkStats;
final NetworkPolicyManagerService networkPolicyF = networkPolicy;
final ConnectivityService connectivityF = connectivity;
@@ -550,6 +551,7 @@ class ServerThread extends Thread {
startSystemUi(contextF);
if (batteryF != null) batteryF.systemReady();
+ if (networkManagementF != null) networkManagementF.systemReady();
if (networkStatsF != null) networkStatsF.systemReady();
if (networkPolicyF != null) networkPolicyF.systemReady();
if (connectivityF != null) connectivityF.systemReady();
diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java
index 54bddb258aaf..a8be916427f3 100644
--- a/services/java/com/android/server/connectivity/Vpn.java
+++ b/services/java/com/android/server/connectivity/Vpn.java
@@ -40,9 +40,9 @@ import com.android.internal.R;
import com.android.internal.net.VpnConfig;
import com.android.server.ConnectivityService.VpnCallback;
-import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charsets;
+import java.util.Arrays;
/**
* @hide
@@ -77,11 +77,13 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
return mPackageName;
}
- // Check the permission of the caller.
- PackageManager pm = mContext.getPackageManager();
- VpnConfig.enforceCallingPackage(pm.getNameForUid(Binder.getCallingUid()));
+ // Only system user can call this method.
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("Unauthorized Caller");
+ }
// Check the permission of the given package.
+ PackageManager pm = mContext.getPackageManager();
if (packageName.isEmpty()) {
packageName = null;
} else if (pm.checkPermission(VPN, packageName) != PackageManager.PERMISSION_GRANTED) {
@@ -104,6 +106,12 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
mContext.sendBroadcast(intent);
}
+ // Stop legacy VPN if it has been started.
+ if (mLegacyVpnRunner != null) {
+ mLegacyVpnRunner.exit();
+ mLegacyVpnRunner = null;
+ }
+
Log.i(TAG, "Switched from " + mPackageName + " to " + packageName);
mPackageName = packageName;
return mPackageName;
@@ -132,7 +140,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
/**
* Configure a TUN interface and return its file descriptor.
*
- * @param configuration The parameters to configure the interface.
+ * @param config The parameters to configure the interface.
* @return The file descriptor of the interface.
*/
public synchronized ParcelFileDescriptor establish(VpnConfig config) {
@@ -151,11 +159,25 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
return null;
}
- // Create and configure the interface.
+ // Load the label.
+ String label = app.loadLabel(pm).toString();
+
+ // Load the icon and convert it into a bitmap.
+ Drawable icon = app.loadIcon(pm);
+ Bitmap bitmap = null;
+ if (icon.getIntrinsicWidth() > 0 && icon.getIntrinsicHeight() > 0) {
+ int width = mContext.getResources().getDimensionPixelSize(
+ android.R.dimen.notification_large_icon_width);
+ int height = mContext.getResources().getDimensionPixelSize(
+ android.R.dimen.notification_large_icon_height);
+ icon.setBounds(0, 0, width, height);
+ bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ icon.draw(new Canvas(bitmap));
+ }
+
+ // Create the interface and abort if any of the following steps fails.
ParcelFileDescriptor descriptor =
ParcelFileDescriptor.adoptFd(jniCreateInterface(config.mtu));
-
- // Abort if any of the following steps fails.
try {
String name = jniGetInterfaceName(descriptor.getFd());
if (jniSetAddresses(name, config.addresses) < 1) {
@@ -177,12 +199,15 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
throw e;
}
- String dnsServers = (config.dnsServers == null) ? "" : config.dnsServers.trim();
- mCallback.override(dnsServers.isEmpty() ? null : dnsServers.split(" "));
+ // Override DNS servers and search domains.
+ mCallback.override(config.dnsServers, config.searchDomains);
+ // Fill more values.
config.packageName = mPackageName;
config.interfaceName = mInterfaceName;
- showNotification(pm, app, config);
+
+ // Show the notification!
+ showNotification(config, label, bitmap);
return descriptor;
}
@@ -202,41 +227,26 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
public synchronized void interfaceRemoved(String name) {
if (name.equals(mInterfaceName) && jniCheckInterface(name) == 0) {
hideNotification();
- mInterfaceName = null;
mCallback.restore();
+ mInterfaceName = null;
}
}
- private void showNotification(PackageManager pm, ApplicationInfo app, VpnConfig config) {
+ private void showNotification(VpnConfig config, String label, Bitmap icon) {
NotificationManager nm = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
if (nm != null) {
- // Load the icon and convert it into a bitmap.
- Drawable icon = app.loadIcon(pm);
- Bitmap bitmap = null;
- if (icon.getIntrinsicWidth() > 0 && icon.getIntrinsicHeight() > 0) {
- int width = mContext.getResources().getDimensionPixelSize(
- android.R.dimen.notification_large_icon_width);
- int height = mContext.getResources().getDimensionPixelSize(
- android.R.dimen.notification_large_icon_height);
- icon.setBounds(0, 0, width, height);
- bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- icon.draw(new Canvas(bitmap));
- }
-
- // Load the label.
- String label = app.loadLabel(pm).toString();
-
- // Build the notification.
+ String title = (label == null) ? mContext.getString(R.string.vpn_title) :
+ mContext.getString(R.string.vpn_title_long, label);
String text = (config.sessionName == null) ? mContext.getString(R.string.vpn_text) :
mContext.getString(R.string.vpn_text_long, config.sessionName);
+
long identity = Binder.clearCallingIdentity();
Notification notification = new Notification.Builder(mContext)
.setSmallIcon(R.drawable.vpn_connected)
- .setLargeIcon(bitmap)
- .setTicker(mContext.getString(R.string.vpn_ticker, label))
- .setContentTitle(mContext.getString(R.string.vpn_title, label))
+ .setLargeIcon(icon)
+ .setContentTitle(title)
.setContentText(text)
.setContentIntent(VpnConfig.getIntentForNotification(mContext, config))
.setDefaults(Notification.DEFAULT_ALL)
@@ -267,27 +277,22 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
private native void jniProtectSocket(int fd, String name);
/**
- * Handle legacy VPN requests. This method stops the services and restart
+ * Handle legacy VPN requests. This method stops the daemons and restart
* them if their arguments are not null. Heavy things are offloaded to
* another thread, so callers will not be blocked too long.
*
* @param raoocn The arguments to be passed to racoon.
* @param mtpd The arguments to be passed to mtpd.
*/
- public synchronized void doLegacyVpn(String[] racoon, String[] mtpd) {
- // Currently only system user is allowed.
- if (Binder.getCallingUid() != Process.SYSTEM_UID) {
- throw new SecurityException("Unauthorized Caller");
- }
+ public synchronized void startLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd) {
+ // Stop the current VPN just like a normal VPN application.
+ prepare("");
- // If the previous runner is still alive, interrupt it.
- if (mLegacyVpnRunner != null && mLegacyVpnRunner.isAlive()) {
- mLegacyVpnRunner.interrupt();
- }
+ // Legacy VPN does not have a package name.
+ config.packageName = null;
// Start a new runner and we are done!
- mLegacyVpnRunner = new LegacyVpnRunner(
- new String[] {"racoon", "mtpd"}, racoon, mtpd);
+ mLegacyVpnRunner = new LegacyVpnRunner(config, racoon, mtpd);
mLegacyVpnRunner.start();
}
@@ -300,17 +305,25 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
*/
private class LegacyVpnRunner extends Thread {
private static final String TAG = "LegacyVpnRunner";
-
private static final String NONE = "--";
- private final String[] mServices;
+ private final VpnConfig mConfig;
+ private final String[] mDaemons;
private final String[][] mArguments;
private long mTimer = -1;
- public LegacyVpnRunner(String[] services, String[]... arguments) {
+ public LegacyVpnRunner(VpnConfig config, String[] racoon, String[] mtpd) {
super(TAG);
- mServices = services;
- mArguments = arguments;
+ mConfig = config;
+ mDaemons = new String[] {"racoon", "mtpd"};
+ mArguments = new String[][] {racoon, mtpd};
+ }
+
+ public void exit() {
+ for (String daemon : mDaemons) {
+ SystemProperties.set("ctl.stop", daemon);
+ }
+ interrupt();
}
@Override
@@ -318,9 +331,9 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
// Wait for the previous thread since it has been interrupted.
Log.v(TAG, "wait");
synchronized (TAG) {
- Log.v(TAG, "run");
+ Log.v(TAG, "begin");
execute();
- Log.v(TAG, "exit");
+ Log.v(TAG, "end");
}
}
@@ -342,14 +355,14 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
// Initialize the timer.
checkpoint(false);
- // First stop the services.
- for (String service : mServices) {
- SystemProperties.set("ctl.stop", service);
+ // First stop the daemons.
+ for (String daemon : mDaemons) {
+ SystemProperties.set("ctl.stop", daemon);
}
- // Wait for the services to stop.
- for (String service : mServices) {
- String key = "init.svc." + service;
+ // Wait for the daemons to stop.
+ for (String daemon : mDaemons) {
+ String key = "init.svc." + daemon;
while (!"stopped".equals(SystemProperties.get(key))) {
checkpoint(true);
}
@@ -363,7 +376,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
checkpoint(true);
}
- // Check if we need to restart some services.
+ // Check if we need to restart some daemons.
boolean restart = false;
for (String[] arguments : mArguments) {
restart = restart || (arguments != null);
@@ -372,19 +385,19 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
return;
}
- // Start the service with arguments.
- for (int i = 0; i < mServices.length; ++i) {
+ // Start the daemon with arguments.
+ for (int i = 0; i < mDaemons.length; ++i) {
String[] arguments = mArguments[i];
if (arguments == null) {
continue;
}
- // Start the service.
- String service = mServices[i];
- SystemProperties.set("ctl.start", service);
+ // Start the daemon.
+ String daemon = mDaemons[i];
+ SystemProperties.set("ctl.start", daemon);
- // Wait for the service to start.
- String key = "init.svc." + service;
+ // Wait for the daemon to start.
+ String key = "init.svc." + daemon;
while (!"running".equals(SystemProperties.get(key))) {
checkpoint(true);
}
@@ -392,7 +405,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
// Create the control socket.
LocalSocket socket = new LocalSocket();
LocalSocketAddress address = new LocalSocketAddress(
- service, LocalSocketAddress.Namespace.RESERVED);
+ daemon, LocalSocketAddress.Namespace.RESERVED);
// Wait for the socket to connect.
while (true) {
@@ -407,22 +420,22 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
socket.setSoTimeout(500);
// Send over the arguments.
- OutputStream output = socket.getOutputStream();
+ OutputStream out = socket.getOutputStream();
for (String argument : arguments) {
byte[] bytes = argument.getBytes(Charsets.UTF_8);
if (bytes.length >= 0xFFFF) {
throw new IllegalArgumentException("argument too large");
}
- output.write(bytes.length >> 8);
- output.write(bytes.length);
- output.write(bytes);
+ out.write(bytes.length >> 8);
+ out.write(bytes.length);
+ out.write(bytes);
checkpoint(false);
}
// Send End-Of-Arguments.
- output.write(0xFF);
- output.write(0xFF);
- output.flush();
+ out.write(0xFF);
+ out.write(0xFF);
+ out.flush();
socket.close();
}
@@ -433,25 +446,47 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
while (NONE.equals(SystemProperties.get("vpn.dns")) ||
NONE.equals(SystemProperties.get("vpn.via"))) {
- // Check if a running service is dead.
- for (int i = 0; i < mServices.length; ++i) {
- String service = mServices[i];
+ // Check if a running daemon is dead.
+ for (int i = 0; i < mDaemons.length; ++i) {
+ String daemon = mDaemons[i];
if (mArguments[i] != null && !"running".equals(
- SystemProperties.get("init.svc." + service))) {
- throw new IllegalArgumentException(service + " is dead");
+ SystemProperties.get("init.svc." + daemon))) {
+ throw new IllegalArgumentException(daemon + " is dead");
}
}
checkpoint(true);
}
- // Great! Now we are connected!
- Log.i(TAG, "connected!");
- // TODO:
+ // Now we are connected. Get the interface.
+ mConfig.interfaceName = SystemProperties.get("vpn.via");
+
+ // Get the DNS servers if they are not set in config.
+ if (mConfig.dnsServers == null || mConfig.dnsServers.size() == 0) {
+ String dnsServers = SystemProperties.get("vpn.dns").trim();
+ if (!dnsServers.isEmpty()) {
+ mConfig.dnsServers = Arrays.asList(dnsServers.split(" "));
+ }
+ }
+
+ // TODO: support routes and search domains for IPSec Mode-CFG.
+
+ // This is it! Here is the end of our journey!
+ synchronized (Vpn.this) {
+ // Check if the thread is interrupted while we are waiting.
+ checkpoint(false);
+ if (mConfig.routes != null) {
+ jniSetRoutes(mConfig.interfaceName, mConfig.routes);
+ }
+ mInterfaceName = mConfig.interfaceName;
+ mCallback.override(mConfig.dnsServers, mConfig.searchDomains);
+ showNotification(mConfig, null, null);
+ }
+ Log.i(TAG, "Connected!");
} catch (Exception e) {
- Log.i(TAG, e.getMessage());
- for (String service : mServices) {
- SystemProperties.set("ctl.stop", service);
+ Log.i(TAG, "Abort due to " + e.getMessage());
+ for (String daemon : mDaemons) {
+ SystemProperties.set("ctl.stop", daemon);
}
}
}
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 1f2ec2ca8279..2a17cbe7afda 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -1044,8 +1044,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// TODO: only dispatch when rules actually change
- // record rule locally to dispatch to new listeners
- mUidRules.put(uid, uidRules);
+ if (uidRules == RULE_ALLOW_ALL) {
+ mUidRules.delete(uid);
+ } else {
+ mUidRules.put(uid, uidRules);
+ }
final boolean rejectMetered = (uidRules & RULE_REJECT_METERED) != 0;
setUidNetworkRules(uid, rejectMetered);
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index 7610a1181d60..b4bd17690605 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -134,7 +134,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
* Settings that can be changed externally.
*/
public interface NetworkStatsSettings {
- public boolean getEnabled();
public long getPollInterval();
public long getPersistThreshold();
public long getNetworkBucketDuration();
@@ -207,20 +206,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
public void systemReady() {
- if (mSettings.getEnabled()) {
- try {
- // enable low-level bandwidth stats and control
- // TODO: consider shipping with this enabled by default
- mNetworkManager.setBandwidthControlEnabled(true);
- } catch (RemoteException e) {
- Slog.e(TAG, "problem talking to netd while enabling bandwidth controls", e);
- } catch (NativeDaemonConnectorException ndce) {
- Slog.e(TAG, "problem enabling bandwidth controls", ndce);
- }
- } else {
- Slog.w(TAG, "detailed network stats disabled");
- }
-
synchronized (mStatsLock) {
// read historical network stats from disk, since policy service
// might need them right away. we delay loading detailed UID stats
@@ -389,6 +374,15 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
}
+ @Override
+ public void forceUpdate() {
+ mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
+
+ synchronized (mStatsLock) {
+ performPollLocked(true, false);
+ }
+ }
+
/**
* Receiver that watches for {@link IConnectivityManager} to claim network
* interfaces. Used to associate {@link TelephonyManager#getSubscriberId()}
@@ -905,6 +899,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
argSet.add(arg);
}
+ final boolean fullHistory = argSet.contains("full");
+
synchronized (mStatsLock) {
// TODO: remove this testing code, since it corrupts stats
if (argSet.contains("generate")) {
@@ -930,7 +926,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
for (NetworkIdentitySet ident : mNetworkStats.keySet()) {
final NetworkStatsHistory history = mNetworkStats.get(ident);
pw.print(" ident="); pw.println(ident.toString());
- history.dump(" ", pw);
+ history.dump(" ", pw, fullHistory);
}
if (argSet.contains("detail")) {
@@ -950,7 +946,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final NetworkStatsHistory history = uidStats.valueAt(i);
pw.print(" UID="); pw.print(uid);
pw.print(" tag="); pw.println(tag);
- history.dump(" ", pw);
+ history.dump(" ", pw, fullHistory);
}
}
}
@@ -1058,15 +1054,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
return Settings.Secure.getLong(mResolver, name, def);
}
- public boolean getEnabled() {
- if (!new File("/proc/net/xt_qtaguid/ctrl").exists()) {
- Slog.w(TAG, "kernel does not support bandwidth control");
- return false;
- }
- // TODO: once things stabilize, enable by default.
- // For now: ./vendor/google/tools/override-gservices secure:netstats_enabled=1
- return Settings.Secure.getInt(mResolver, NETSTATS_ENABLED, 0) != 0;
- }
public long getPollInterval() {
return getSecureLong(NETSTATS_POLL_INTERVAL, 15 * MINUTE_IN_MILLIS);
}
diff --git a/services/jni/com_android_server_connectivity_Vpn.cpp b/services/jni/com_android_server_connectivity_Vpn.cpp
index a0ea92b91a03..62d7636321c0 100644
--- a/services/jni/com_android_server_connectivity_Vpn.cpp
+++ b/services/jni/com_android_server_connectivity_Vpn.cpp
@@ -244,7 +244,7 @@ static int set_routes(const char *name, const char *routes)
break;
}
- in_addr_t mask = prefix ? (~0 << (32 - prefix)) : 1;
+ in_addr_t mask = prefix ? (~0 << (32 - prefix)) : 0x80000000;
*as_in_addr(&rt4.rt_genmask) = htonl(mask);
if (ioctl(inet4, SIOCADDRT, &rt4) && errno != EEXIST) {
count = (errno == EINVAL) ? BAD_ARGUMENT : SYSTEM_ERROR;
@@ -394,7 +394,7 @@ static jint setRoutes(JNIEnv *env, jobject thiz, jstring jName,
}
count = set_routes(name, routes);
if (count < 0) {
- throwException(env, count, "Cannot set address");
+ throwException(env, count, "Cannot set route");
count = -1;
}
diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
index 903f2b0b6f66..f2c28bb538c8 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
@@ -610,9 +610,6 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
mAlarmManager.setInexactRepeating(
eq(AlarmManager.ELAPSED_REALTIME), anyLong(), anyLong(), isA(PendingIntent.class));
expectLastCall().atLeastOnce();
-
- mNetManager.setBandwidthControlEnabled(true);
- expectLastCall().atLeastOnce();
}
private void expectNetworkState(NetworkState... state) throws Exception {
@@ -633,7 +630,6 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
private void expectSettings(long persistThreshold, long bucketDuration, long maxHistory)
throws Exception {
- expect(mSettings.getEnabled()).andReturn(true).anyTimes();
expect(mSettings.getPollInterval()).andReturn(HOUR_IN_MILLIS).anyTimes();
expect(mSettings.getPersistThreshold()).andReturn(persistThreshold).anyTimes();
expect(mSettings.getNetworkBucketDuration()).andReturn(bucketDuration).anyTimes();
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index fce7cdc82440..2f010e57b161 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -473,8 +473,8 @@ public class ServiceState implements Parcelable {
+ " EmergOnly=" + mIsEmergencyOnly);
}
- public void setStateOutOfService() {
- mState = STATE_OUT_OF_SERVICE;
+ private void setNullState(int state) {
+ mState = state;
mRoaming = false;
mOperatorAlphaLong = null;
mOperatorAlphaShort = null;
@@ -491,23 +491,12 @@ public class ServiceState implements Parcelable {
mIsEmergencyOnly = false;
}
- // TODO - can't this be combined with the above method?
+ public void setStateOutOfService() {
+ setNullState(STATE_OUT_OF_SERVICE);
+ }
+
public void setStateOff() {
- mState = STATE_POWER_OFF;
- mRoaming = false;
- mOperatorAlphaLong = null;
- mOperatorAlphaShort = null;
- mOperatorNumeric = null;
- mIsManualNetworkSelection = false;
- mRadioTechnology = 0;
- mCssIndicator = false;
- mNetworkId = -1;
- mSystemId = -1;
- mCdmaRoamingIndicator = -1;
- mCdmaDefaultRoamingIndicator = -1;
- mCdmaEriIconIndex = -1;
- mCdmaEriIconMode = -1;
- mIsEmergencyOnly = false;
+ setNullState(STATE_POWER_OFF);
}
public void setState(int state) {
diff --git a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
index 910905aa4543..aa7568b108f8 100644
--- a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
+++ b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
@@ -21,6 +21,7 @@ import android.net.LinkProperties;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.util.Log;
@@ -55,8 +56,13 @@ public class DefaultPhoneNotifier implements PhoneNotifier {
}
public void notifyServiceState(Phone sender) {
+ ServiceState ss = sender.getServiceState();
+ if (ss == null) {
+ ss = new ServiceState();
+ ss.setStateOutOfService();
+ }
try {
- mRegistry.notifyServiceState(sender.getServiceState());
+ mRegistry.notifyServiceState(ss);
} catch (RemoteException ex) {
// system process is dead
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index 5fc0bf9b51e2..a6b131a91106 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -556,6 +556,9 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
if (DBG) log("onDataConnectionAttached: start polling notify attached");
startNetStatPoll();
notifyDataConnection(Phone.REASON_DATA_ATTACHED);
+ } else {
+ // update APN availability so that APN can be enabled.
+ notifyDataAvailability(Phone.REASON_DATA_ATTACHED);
}
setupDataOnReadyApns(Phone.REASON_DATA_ATTACHED);
@@ -785,13 +788,13 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
Message msg = obtainMessage(EVENT_DISCONNECT_DONE, apnContext);
apnContext.getDataConnection().tearDown(apnContext.getReason(), msg);
apnContext.setState(State.DISCONNECTING);
- } else {
- // apn is connected but no reference to dcac.
- // Should not be happen, but reset the state in case.
- apnContext.setState(State.IDLE);
- mPhone.notifyDataConnection(apnContext.getReason(),
- apnContext.getApnType());
}
+ } else {
+ // apn is connected but no reference to dcac.
+ // Should not be happen, but reset the state in case.
+ apnContext.setState(State.IDLE);
+ mPhone.notifyDataConnection(apnContext.getReason(),
+ apnContext.getApnType());
}
}
} else {
@@ -1528,13 +1531,16 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
createAllApnList();
if (mRadioAvailable) {
if (DBG) log("onRecordsLoaded: notifying data availability");
- notifyDataAvailability(null);
+ notifyDataAvailability(Phone.REASON_SIM_LOADED);
}
setupDataOnReadyApns(Phone.REASON_SIM_LOADED);
}
@Override
protected void onSetDependencyMet(String apnType, boolean met) {
+ // don't allow users to tweak hipri to work around default dependency not met
+ if (Phone.APN_TYPE_HIPRI.equals(apnType)) return;
+
ApnContext apnContext = mApnContexts.get(apnType);
if (apnContext == null) {
loge("onSetDependencyMet: ApnContext not found in onSetDependencyMet(" +
@@ -1542,6 +1548,11 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
return;
}
applyNewState(apnContext, apnContext.isEnabled(), met);
+ if (Phone.APN_TYPE_DEFAULT.equals(apnType)) {
+ // tie actions on default to similar actions on HIPRI regarding dependencyMet
+ apnContext = mApnContexts.get(Phone.APN_TYPE_HIPRI);
+ if (apnContext != null) applyNewState(apnContext, apnContext.isEnabled(), met);
+ }
}
private void applyNewState(ApnContext apnContext, boolean enabled, boolean met) {
@@ -1627,11 +1638,17 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
@Override
protected void onRoamingOff() {
if (DBG) log("onRoamingOff");
+ // Notify data availability so APN can be enabled.
+ notifyDataAvailability(Phone.REASON_ROAMING_OFF);
+
setupDataOnReadyApns(Phone.REASON_ROAMING_OFF);
}
@Override
protected void onRoamingOn() {
+ // Notify data availability so APN can be enabled.
+ notifyDataAvailability(Phone.REASON_ROAMING_ON);
+
if (getDataOnRoamingEnabled()) {
if (DBG) log("onRoamingOn: setup data on roaming");
setupDataOnReadyApns(Phone.REASON_ROAMING_ON);
diff --git a/voip/java/com/android/server/sip/SipWakeupTimer.java b/voip/java/com/android/server/sip/SipWakeupTimer.java
index 76780c02b3df..00d47ac63ce6 100644
--- a/voip/java/com/android/server/sip/SipWakeupTimer.java
+++ b/voip/java/com/android/server/sip/SipWakeupTimer.java
@@ -83,7 +83,7 @@ class SipWakeupTimer extends BroadcastReceiver {
mEventQueue = null;
}
- private synchronized boolean stopped() {
+ private boolean stopped() {
if (mEventQueue == null) {
Log.w(TAG, "Timer stopped");
return true;
@@ -233,7 +233,7 @@ class SipWakeupTimer extends BroadcastReceiver {
}
@Override
- public void onReceive(Context context, Intent intent) {
+ public synchronized void onReceive(Context context, Intent intent) {
// This callback is already protected by AlarmManager's wake lock.
String action = intent.getAction();
if (getAction().equals(action)
@@ -261,7 +261,7 @@ class SipWakeupTimer extends BroadcastReceiver {
}
}
- private synchronized void execute(long triggerTime) {
+ private void execute(long triggerTime) {
if (DEBUG_TIMER) Log.d(TAG, "time's up, triggerTime = "
+ showTime(triggerTime) + ": " + mEventQueue.size());
if (stopped() || mEventQueue.isEmpty()) return;