Merge "Import translations. DO NOT MERGE" into lmp-mr1-ub-dev
diff --git a/Android.mk b/Android.mk
index ce72a85..39ddb55 100644
--- a/Android.mk
+++ b/Android.mk
@@ -69,6 +69,7 @@
core/java/android/app/IActivityPendingResult.aidl \
core/java/android/app/IAlarmManager.aidl \
core/java/android/app/IAppTask.aidl \
+ core/java/android/app/ITaskStackListener.aidl \
core/java/android/app/IBackupAgent.aidl \
core/java/android/app/IInstrumentationWatcher.aidl \
core/java/android/app/INotificationManager.aidl \
@@ -731,7 +732,8 @@
# Whitelist of valid groups, used for default TOC grouping. Each sample must
# belong to one (and only one) group. Assign samples to groups by setting
# a sample.group var to one of these groups in the sample's _index.jd.
-sample_groups := -samplegroup Background \
+sample_groups := -samplegroup Admin \
+ -samplegroup Background \
-samplegroup Connectivity \
-samplegroup Content \
-samplegroup Input \
diff --git a/api/current.txt b/api/current.txt
index 53aa4a2..8376efe 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8782,11 +8782,9 @@
field public static final java.lang.String FEATURE_CAMERA = "android.hardware.camera";
field public static final java.lang.String FEATURE_CAMERA_ANY = "android.hardware.camera.any";
field public static final java.lang.String FEATURE_CAMERA_AUTOFOCUS = "android.hardware.camera.autofocus";
- field public static final java.lang.String FEATURE_CAMERA_CAPABILITY_BURST_CAPTURE = "android.hardware.camera.capability.burst_capture";
field public static final java.lang.String FEATURE_CAMERA_CAPABILITY_MANUAL_POST_PROCESSING = "android.hardware.camera.capability.manual_post_processing";
field public static final java.lang.String FEATURE_CAMERA_CAPABILITY_MANUAL_SENSOR = "android.hardware.camera.capability.manual_sensor";
field public static final java.lang.String FEATURE_CAMERA_CAPABILITY_RAW = "android.hardware.camera.capability.raw";
- field public static final java.lang.String FEATURE_CAMERA_CAPABILITY_READ_SENSOR_SETTINGS = "android.hardware.camera.capability.read_sensor_settings";
field public static final java.lang.String FEATURE_CAMERA_EXTERNAL = "android.hardware.camera.external";
field public static final java.lang.String FEATURE_CAMERA_FLASH = "android.hardware.camera.flash";
field public static final java.lang.String FEATURE_CAMERA_FRONT = "android.hardware.camera.front";
diff --git a/cmds/appops/src/com/android/commands/appops/AppOpsCommand.java b/cmds/appops/src/com/android/commands/appops/AppOpsCommand.java
index c414f58..3ec63b4 100644
--- a/cmds/appops/src/com/android/commands/appops/AppOpsCommand.java
+++ b/cmds/appops/src/com/android/commands/appops/AppOpsCommand.java
@@ -24,10 +24,12 @@
import android.os.ServiceManager;
import android.os.UserHandle;
+import android.util.TimeUtils;
import com.android.internal.app.IAppOpsService;
import com.android.internal.os.BaseCommand;
import java.io.PrintStream;
+import java.util.List;
/**
* This class is a command line utility for manipulating AppOps permissions.
@@ -40,15 +42,19 @@
@Override
public void onShowUsage(PrintStream out) {
- out.println("usage: adb shell appops set <PACKAGE> <OP> "
- + "<allow|ignore|deny|default> [--user <USER_ID>]\n"
+ out.println("usage: appops set [--user <USER_ID>] <PACKAGE> <OP> <MODE>\n"
+ + " appops get [--user <USER_ID>] <PACKAGE> [<OP>]\n"
+ + " appops reset [--user <USER_ID>] [<PACKAGE>]\n"
+ " <PACKAGE> an Android package name.\n"
+ " <OP> an AppOps operation.\n"
+ + " <MODE> one of allow, ignore, deny, or default\n"
+ " <USER_ID> the user id under which the package is installed. If --user is not\n"
+ " specified, the current user is assumed.\n");
}
private static final String COMMAND_SET = "set";
+ private static final String COMMAND_GET = "get";
+ private static final String COMMAND_RESET = "reset";
@Override
public void onRun() throws Exception {
@@ -58,8 +64,17 @@
runSet();
break;
+ case COMMAND_GET:
+ runGet();
+ break;
+
+ case COMMAND_RESET:
+ runReset();
+ break;
+
default:
- throw new IllegalArgumentException("Unknown command '" + command + "'.");
+ System.err.println("Error: Unknown command: '" + command + "'.");
+ break;
}
}
@@ -71,6 +86,23 @@
private static final String MODE_IGNORE = "ignore";
private static final String MODE_DEFAULT = "default";
+ private int strOpToOp(String op) {
+ try {
+ return AppOpsManager.strOpToOp(op);
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ return Integer.parseInt(op);
+ } catch (NumberFormatException e) {
+ }
+ try {
+ return AppOpsManager.strDebugOpToOp(op);
+ } catch (IllegalArgumentException e) {
+ System.err.println("Error: " + e.getMessage());
+ return -1;
+ }
+ }
+
private void runSet() throws Exception {
String packageName = null;
String op = null;
@@ -87,20 +119,27 @@
} else if (mode == null) {
mode = argument;
} else {
- throw new IllegalArgumentException("Unsupported argument: " + argument);
+ System.err.println("Error: Unsupported argument: " + argument);
+ return;
}
}
}
if (packageName == null) {
- throw new IllegalArgumentException("Package name not specified.");
+ System.err.println("Error: Package name not specified.");
+ return;
} else if (op == null) {
- throw new IllegalArgumentException("Operation not specified.");
+ System.err.println("Error: Operation not specified.");
+ return;
} else if (mode == null) {
- throw new IllegalArgumentException("Mode not specified.");
+ System.err.println("Error: Mode not specified.");
+ return;
}
- final int opInt = AppOpsManager.strOpToOp(op);
+ final int opInt = strOpToOp(op);
+ if (opInt < 0) {
+ return;
+ }
final int modeInt;
switch (mode) {
case MODE_ALLOW:
@@ -116,7 +155,8 @@
modeInt = AppOpsManager.MODE_DEFAULT;
break;
default:
- throw new IllegalArgumentException("Mode is invalid.");
+ System.err.println("Error: Mode " + mode + " is not valid,");
+ return;
}
// Parsing complete, let's execute the command.
@@ -130,8 +170,155 @@
ServiceManager.getService(Context.APP_OPS_SERVICE));
final int uid = pm.getPackageUid(packageName, userId);
if (uid < 0) {
- throw new Exception("No UID for " + packageName + " for user " + userId);
+ System.err.println("Error: No UID for " + packageName + " in user " + userId);
+ return;
}
appOpsService.setMode(opInt, uid, packageName, modeInt);
}
+
+ private void runGet() throws Exception {
+ String packageName = null;
+ String op = null;
+ int userId = UserHandle.USER_CURRENT;
+ for (String argument; (argument = nextArg()) != null;) {
+ if (ARGUMENT_USER.equals(argument)) {
+ userId = Integer.parseInt(nextArgRequired());
+ } else {
+ if (packageName == null) {
+ packageName = argument;
+ } else if (op == null) {
+ op = argument;
+ } else {
+ System.err.println("Error: Unsupported argument: " + argument);
+ return;
+ }
+ }
+ }
+
+ if (packageName == null) {
+ System.err.println("Error: Package name not specified.");
+ return;
+ }
+
+ final int opInt = op != null ? strOpToOp(op) : 0;
+
+ // Parsing complete, let's execute the command.
+
+ if (userId == UserHandle.USER_CURRENT) {
+ userId = ActivityManager.getCurrentUser();
+ }
+
+ final IPackageManager pm = ActivityThread.getPackageManager();
+ final IAppOpsService appOpsService = IAppOpsService.Stub.asInterface(
+ ServiceManager.getService(Context.APP_OPS_SERVICE));
+ final int uid = pm.getPackageUid(packageName, userId);
+ if (uid < 0) {
+ System.err.println("Error: No UID for " + packageName + " in user " + userId);
+ return;
+ }
+ List<AppOpsManager.PackageOps> ops = appOpsService.getOpsForPackage(uid, packageName,
+ op != null ? new int[] {opInt} : null);
+ if (ops == null || ops.size() <= 0) {
+ System.out.println("No operations.");
+ return;
+ }
+ final long now = System.currentTimeMillis();
+ for (int i=0; i<ops.size(); i++) {
+ List<AppOpsManager.OpEntry> entries = ops.get(i).getOps();
+ for (int j=0; j<entries.size(); j++) {
+ AppOpsManager.OpEntry ent = entries.get(j);
+ System.out.print(AppOpsManager.opToName(ent.getOp()));
+ System.out.print(": ");
+ switch (ent.getMode()) {
+ case AppOpsManager.MODE_ALLOWED:
+ System.out.print("allow");
+ break;
+ case AppOpsManager.MODE_IGNORED:
+ System.out.print("ignore");
+ break;
+ case AppOpsManager.MODE_ERRORED:
+ System.out.print("deny");
+ break;
+ case AppOpsManager.MODE_DEFAULT:
+ System.out.print("default");
+ break;
+ default:
+ System.out.print("mode=");
+ System.out.print(ent.getMode());
+ break;
+ }
+ if (ent.getTime() != 0) {
+ System.out.print("; time=");
+ StringBuilder sb = new StringBuilder();
+ TimeUtils.formatDuration(now - ent.getTime(), sb);
+ System.out.print(sb);
+ System.out.print(" ago");
+ }
+ if (ent.getRejectTime() != 0) {
+ System.out.print("; rejectTime=");
+ StringBuilder sb = new StringBuilder();
+ TimeUtils.formatDuration(now - ent.getRejectTime(), sb);
+ System.out.print(sb);
+ System.out.print(" ago");
+ }
+ if (ent.getDuration() == -1) {
+ System.out.print(" (running)");
+ } else if (ent.getDuration() != 0) {
+ System.out.print("; duration=");
+ StringBuilder sb = new StringBuilder();
+ TimeUtils.formatDuration(ent.getDuration(), sb);
+ System.out.print(sb);
+ }
+ System.out.println();
+ }
+ }
+ }
+
+ private void runReset() throws Exception {
+ String packageName = null;
+ int userId = UserHandle.USER_CURRENT;
+ for (String argument; (argument = nextArg()) != null;) {
+ if (ARGUMENT_USER.equals(argument)) {
+ String userStr = nextArgRequired();
+ if ("all".equals(userStr)) {
+ userId = UserHandle.USER_ALL;
+ } else if ("current".equals(userStr)) {
+ userId = UserHandle.USER_CURRENT;
+ } else if ("owner".equals(userStr)) {
+ userId = UserHandle.USER_OWNER;
+ } else {
+ userId = Integer.parseInt(nextArgRequired());
+ }
+ } else {
+ if (packageName == null) {
+ packageName = argument;
+ } else {
+ System.err.println("Error: Unsupported argument: " + argument);
+ return;
+ }
+ }
+ }
+
+ // Parsing complete, let's execute the command.
+
+ if (userId == UserHandle.USER_CURRENT) {
+ userId = ActivityManager.getCurrentUser();
+ }
+
+ final IAppOpsService appOpsService = IAppOpsService.Stub.asInterface(
+ ServiceManager.getService(Context.APP_OPS_SERVICE));
+ appOpsService.resetAllModes(userId, packageName);
+ System.out.print("Reset all modes for: ");
+ if (userId == UserHandle.USER_ALL) {
+ System.out.print("all users");
+ } else {
+ System.out.print("user "); System.out.print(userId);
+ }
+ System.out.print(", ");
+ if (packageName == null) {
+ System.out.println("all packages");
+ } else {
+ System.out.print("package "); System.out.println(packageName);
+ }
+ }
}
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 6ec48e5..06a26ec 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -774,6 +774,14 @@
return true;
}
+ case REGISTER_TASK_STACK_LISTENER_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IBinder token = data.readStrongBinder();
+ registerTaskStackListener(ITaskStackListener.Stub.asInterface(token));
+ reply.writeNoException();
+ return true;
+ }
+
case GET_TASK_FOR_ACTIVITY_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder token = data.readStrongBinder();
@@ -3266,6 +3274,18 @@
data.recycle();
reply.recycle();
}
+ @Override
+ public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException
+ {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeStrongBinder(listener.asBinder());
+ mRemote.transact(REGISTER_TASK_STACK_LISTENER_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException
{
Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index ba9c9d6..95870cf9 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -26,6 +26,7 @@
import android.os.Parcelable;
import android.os.Process;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.os.UserManager;
import android.util.ArrayMap;
@@ -734,6 +735,18 @@
}
/**
+ * @hide
+ */
+ public static int strDebugOpToOp(String op) {
+ for (int i=0; i<sOpNames.length; i++) {
+ if (sOpNames[i].equals(op)) {
+ return i;
+ }
+ }
+ throw new IllegalArgumentException("Unknown operation string: " + op);
+ }
+
+ /**
* Retrieve the permission associated with an operation, or null if there is not one.
* @hide
*/
@@ -996,7 +1009,7 @@
/** @hide */
public void resetAllModes() {
try {
- mService.resetAllModes();
+ mService.resetAllModes(UserHandle.myUserId(), null);
} catch (RemoteException e) {
}
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 5362303..1ccbd27 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -139,6 +139,7 @@
public StackInfo getStackInfo(int stackId) throws RemoteException;
public boolean isInHomeStack(int taskId) throws RemoteException;
public void setFocusedStack(int stackId) throws RemoteException;
+ public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException;
public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException;
public ContentProviderHolder getContentProvider(IApplicationThread caller,
String name, int userId, boolean stable) throws RemoteException;
@@ -788,4 +789,5 @@
int LAUNCH_ASSIST_INTENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+239;
int START_IN_PLACE_ANIMATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+240;
int CHECK_PERMISSION_WITH_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+241;
+ int REGISTER_TASK_STACK_LISTENER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+242;
}
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
new file mode 100644
index 0000000..4b0935c
--- /dev/null
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+/** @hide */
+oneway interface ITaskStackListener {
+ void onTaskStackChanged();
+}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 5c705e6..e9f7c50 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1078,26 +1078,6 @@
"android.hardware.camera.capability.raw";
/**
- * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: At least one
- * of the cameras on the device supports the
- * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE BURST_CAPTURE}
- * capability level.
- */
- @SdkConstant(SdkConstantType.FEATURE)
- public static final String FEATURE_CAMERA_CAPABILITY_BURST_CAPTURE =
- "android.hardware.camera.capability.burst_capture";
-
- /**
- * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: At least one
- * of the cameras on the device supports the
- * {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS READ_SENSOR_SETTINGS}
- * capability level.
- */
- @SdkConstant(SdkConstantType.FEATURE)
- public static final String FEATURE_CAMERA_CAPABILITY_READ_SENSOR_SETTINGS =
- "android.hardware.camera.capability.read_sensor_settings";
-
- /**
* Feature for {@link #getSystemAvailableFeatures} and
* {@link #hasSystemFeature}: The device is capable of communicating with
* consumer IR devices.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 82da7c5..d7d9e8b 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -3528,6 +3528,10 @@
outError[0] = "<provider> does not include authorities attribute";
return null;
}
+ if (cpname.length() <= 0) {
+ outError[0] = "<provider> has empty authorities attribute";
+ return null;
+ }
p.info.authority = cpname.intern();
if (!parseProviderTags(res, parser, attrs, p, outError)) {
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 98096dc..f487f01 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -337,8 +337,7 @@
* supported by a given camera device. This field lists the
* valid anti-banding modes that the application may request
* for this camera device with the
- * {@link CaptureRequest#CONTROL_AE_ANTIBANDING_MODE android.control.aeAntibandingMode} control. This list
- * always includes AUTO.</p>
+ * {@link CaptureRequest#CONTROL_AE_ANTIBANDING_MODE android.control.aeAntibandingMode} control.</p>
* <p><b>Range of valid values:</b><br>
* Any value listed in {@link CaptureRequest#CONTROL_AE_ANTIBANDING_MODE android.control.aeAntibandingMode}</p>
* <p>This key is available on all devices.</p>
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 895ae04..999de8a 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -493,9 +493,11 @@
* {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap}, the minimum frame
* duration for that format and size is <= 1/20 s, and
* the {@link CameraCharacteristics#CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES android.control.aeAvailableTargetFpsRanges} entry
- * lists at least one FPS range where the minimum FPS
- * is >= 1 / minimumFrameDuration for the maximum-size
+ * lists at least one FPS range where the minimum FPS is</p>
+ * <blockquote>
+ * <p>= 1 / minimumFrameDuration for the maximum-size
* YUV_420_888 format.</p>
+ * </blockquote>
* <p>In addition, the {@link CameraCharacteristics#SYNC_MAX_LATENCY android.sync.maxLatency} field is
* guaranted to have a value between 0 and 4, inclusive.</p>
*
@@ -847,7 +849,8 @@
/**
* <p>The camera device will automatically adapt its
* antibanding routine to the current illumination
- * conditions. This is the default.</p>
+ * condition. This is the default mode if AUTO is
+ * available on given camera device.</p>
* @see CaptureRequest#CONTROL_AE_ANTIBANDING_MODE
*/
public static final int CONTROL_AE_ANTIBANDING_MODE_AUTO = 3;
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 48af67c..e89a402 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -642,8 +642,10 @@
* options for the antibanding mode. The
* {@link CameraCharacteristics#CONTROL_AE_AVAILABLE_ANTIBANDING_MODES android.control.aeAvailableAntibandingModes} key contains
* the available modes for a given camera device.</p>
- * <p>The default mode is AUTO, which is supported by all
- * camera devices.</p>
+ * <p>AUTO mode is the default if it is available on given
+ * camera device. When AUTO mode is not available, the
+ * default will be either 50HZ or 60HZ, and both 50HZ
+ * and 60HZ will be available.</p>
* <p>If manual exposure control is enabled (by setting
* {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} or {@link CaptureRequest#CONTROL_MODE android.control.mode} to OFF),
* then this setting has no effect, and the application must
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index c5c843d..2c3b85f 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -493,8 +493,10 @@
* options for the antibanding mode. The
* {@link CameraCharacteristics#CONTROL_AE_AVAILABLE_ANTIBANDING_MODES android.control.aeAvailableAntibandingModes} key contains
* the available modes for a given camera device.</p>
- * <p>The default mode is AUTO, which is supported by all
- * camera devices.</p>
+ * <p>AUTO mode is the default if it is available on given
+ * camera device. When AUTO mode is not available, the
+ * default will be either 50HZ or 60HZ, and both 50HZ
+ * and 60HZ will be available.</p>
* <p>If manual exposure control is enabled (by setting
* {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} or {@link CaptureRequest#CONTROL_MODE android.control.mode} to OFF),
* then this setting has no effect, and the application must
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index ff1a441..4215f20 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -721,6 +721,19 @@
}
/**
+ * Returns an array of of {@link NetworkCapabilities} objects, representing
+ * the Networks that applications run by the given user will use by default.
+ * @hide
+ */
+ public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId) {
+ try {
+ return mService.getDefaultNetworkCapabilitiesForUser(userId);
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /**
* Returns details about the Provisioning or currently active default data network. When
* connected, this network is the default route for outgoing connections.
* You should always check {@link NetworkInfo#isConnected()} before initiating
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 79f920e..8021210 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -49,6 +49,7 @@
NetworkInfo[] getAllNetworkInfo();
Network getNetworkForType(int networkType);
Network[] getAllNetworks();
+ NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId);
NetworkInfo getProvisioningOrActiveNetworkInfo();
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index ce7ad65..a7f9c5b 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -154,9 +154,16 @@
*/
public static final int NET_CAPABILITY_NOT_VPN = 15;
+ /**
+ * Indicates that connectivity on this network was successfully validated. For example, for a
+ * network with NET_CAPABILITY_INTERNET, it means that Internet connectivity was successfully
+ * detected.
+ * @hide
+ */
+ public static final int NET_CAPABILITY_VALIDATED = 16;
private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
- private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_NOT_VPN;
+ private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_VALIDATED;
/**
* Adds the given capability to this {@code NetworkCapability} instance.
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index 78b9c18..f6b6978 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -291,16 +291,16 @@
/**
* Sets the underlying networks used by the VPN for its upstream connections.
*
- * Used by the system to know the actual networks that carry traffic for apps affected by this
- * VPN in order to present this information to the user (e.g., via status bar icons).
+ * <p>Used by the system to know the actual networks that carry traffic for apps affected by
+ * this VPN in order to present this information to the user (e.g., via status bar icons).
*
- * This method only needs to be called if the VPN has explicitly bound its underlying
+ * <p>This method only needs to be called if the VPN has explicitly bound its underlying
* communications channels — such as the socket(s) passed to {@link #protect(int)} —
* to a {@code Network} using APIs such as {@link Network#bindSocket(Socket)} or
* {@link Network#bindSocket(DatagramSocket)}. The VPN should call this method every time
* the set of {@code Network}s it is using changes.
*
- * {@code networks} is one of the following:
+ * <p>{@code networks} is one of the following:
* <ul>
* <li><strong>a non-empty array</strong>: an array of one or more {@link Network}s, in
* decreasing preference order. For example, if this VPN uses both wifi and mobile (cellular)
@@ -310,11 +310,11 @@
* underlying network connection, and thus, app traffic will not be sent or received.</li>
* <li><strong>null</strong>: (default) signifies that the VPN uses whatever is the system's
* default network. I.e., it doesn't use the {@code bindSocket} or {@code bindDatagramSocket}
- * APIs mentioned above to send traffic over specific channels.
+ * APIs mentioned above to send traffic over specific channels.</li>
* </ul>
*
- * This call will succeed only if the VPN is currently established. For setting this value when
- * the VPN has not yet been established, see {@link Builder#setUnderlyingNetworks}.
+ * <p>This call will succeed only if the VPN is currently established. For setting this value
+ * when the VPN has not yet been established, see {@link Builder#setUnderlyingNetworks}.
*
* @param networks An array of networks the VPN uses to tunnel traffic to/from its servers.
*
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 5e5fbc7..0c036d51 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6608,6 +6608,14 @@
public static final String ENHANCED_4G_MODE_ENABLED = "volte_vt_enabled";
/**
+ * Global override to disable VoLTE (independent of user setting)
+ * <p>
+ * Type: int (1 for disable VoLTE, 0 to use user configuration)
+ * @hide
+ */
+ public static final String VOLTE_FEATURE_DISABLED = "volte_feature_disabled";
+
+ /**
* Whether user can enable/disable LTE as a preferred network. A carrier might control
* this via gservices, OMA-DM, carrier app, etc.
* <p>
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index a52dd48..99bf9f3 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -36,7 +36,7 @@
List<AppOpsManager.PackageOps> getPackagesForOps(in int[] ops);
List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, in int[] ops);
void setMode(int code, int uid, String packageName, int mode);
- void resetAllModes();
+ void resetAllModes(int reqUserId, String reqPackageName);
int checkAudioOperation(int code, int usage, int uid, String packageName);
void setAudioRestriction(int code, int usage, int uid, int mode, in String[] exceptionPackages);
diff --git a/core/res/res/values-mcc310-mnc120/config.xml b/core/res/res/values-mcc310-mnc120/config.xml
index 774732d..4b61688 100644
--- a/core/res/res/values-mcc310-mnc120/config.xml
+++ b/core/res/res/values-mcc310-mnc120/config.xml
@@ -31,4 +31,31 @@
<!-- If this value is true, The mms content-disposition field is supported correctly.
If false, Content-disposition fragments are ignored -->
<bool name="config_mms_content_disposition_support">false</bool>
+
+ <!-- An array of CDMA roaming indicators which means international roaming -->
+ <integer-array translatable="false" name="config_cdma_international_roaming_indicators" >
+ <item>2</item>
+ <item>74</item>
+ <item>124</item>
+ <item>125</item>
+ <item>126</item>
+ <item>157</item>
+ <item>158</item>
+ <item>159</item>
+ <item>193</item>
+ <item>194</item>
+ <item>195</item>
+ <item>196</item>
+ <item>197</item>
+ <item>198</item>
+ <item>228</item>
+ <item>229</item>
+ <item>230</item>
+ <item>231</item>
+ <item>232</item>
+ <item>233</item>
+ <item>234</item>
+ <item>235</item>
+ </integer-array>
+
</resources>
diff --git a/core/res/res/values-mcc311-mnc490/config.xml b/core/res/res/values-mcc311-mnc490/config.xml
index defe78d..d481c97 100644
--- a/core/res/res/values-mcc311-mnc490/config.xml
+++ b/core/res/res/values-mcc311-mnc490/config.xml
@@ -23,4 +23,31 @@
<!-- Sprint need a 70 ms delay for 3way call -->
<integer name="config_cdma_3waycall_flash_delay">70</integer>
+
+ <!-- An array of CDMA roaming indicators which means international roaming -->
+ <integer-array translatable="false" name="config_cdma_international_roaming_indicators" >
+ <item>2</item>
+ <item>74</item>
+ <item>124</item>
+ <item>125</item>
+ <item>126</item>
+ <item>157</item>
+ <item>158</item>
+ <item>159</item>
+ <item>193</item>
+ <item>194</item>
+ <item>195</item>
+ <item>196</item>
+ <item>197</item>
+ <item>198</item>
+ <item>228</item>
+ <item>229</item>
+ <item>230</item>
+ <item>231</item>
+ <item>232</item>
+ <item>233</item>
+ <item>234</item>
+ <item>235</item>
+ </integer-array>
+
</resources>
diff --git a/core/res/res/values-mcc311-mnc870/config.xml b/core/res/res/values-mcc311-mnc870/config.xml
index 24e55b1..98cb72e 100644
--- a/core/res/res/values-mcc311-mnc870/config.xml
+++ b/core/res/res/values-mcc311-mnc870/config.xml
@@ -27,4 +27,31 @@
<!-- Sprint need a 70 ms delay for 3way call -->
<integer name="config_cdma_3waycall_flash_delay">70</integer>
+
+ <!-- An array of CDMA roaming indicators which means international roaming -->
+ <integer-array translatable="false" name="config_cdma_international_roaming_indicators" >
+ <item>2</item>
+ <item>74</item>
+ <item>124</item>
+ <item>125</item>
+ <item>126</item>
+ <item>157</item>
+ <item>158</item>
+ <item>159</item>
+ <item>193</item>
+ <item>194</item>
+ <item>195</item>
+ <item>196</item>
+ <item>197</item>
+ <item>198</item>
+ <item>228</item>
+ <item>229</item>
+ <item>230</item>
+ <item>231</item>
+ <item>232</item>
+ <item>233</item>
+ <item>234</item>
+ <item>235</item>
+ </integer-array>
+
</resources>
diff --git a/core/res/res/values-mcc312-mnc530/config.xml b/core/res/res/values-mcc312-mnc530/config.xml
index 24e55b1..98cb72e 100644
--- a/core/res/res/values-mcc312-mnc530/config.xml
+++ b/core/res/res/values-mcc312-mnc530/config.xml
@@ -27,4 +27,31 @@
<!-- Sprint need a 70 ms delay for 3way call -->
<integer name="config_cdma_3waycall_flash_delay">70</integer>
+
+ <!-- An array of CDMA roaming indicators which means international roaming -->
+ <integer-array translatable="false" name="config_cdma_international_roaming_indicators" >
+ <item>2</item>
+ <item>74</item>
+ <item>124</item>
+ <item>125</item>
+ <item>126</item>
+ <item>157</item>
+ <item>158</item>
+ <item>159</item>
+ <item>193</item>
+ <item>194</item>
+ <item>195</item>
+ <item>196</item>
+ <item>197</item>
+ <item>198</item>
+ <item>228</item>
+ <item>229</item>
+ <item>230</item>
+ <item>231</item>
+ <item>232</item>
+ <item>233</item>
+ <item>234</item>
+ <item>235</item>
+ </integer-array>
+
</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index cdbee61..6db8322 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1952,4 +1952,8 @@
<dimen name="config_mediaMetadataBitmapMaxSize">320dp</dimen>
<string translatable="false" name="prohibit_manual_network_selection_in_gobal_mode">false</string>
+
+ <!-- An array of CDMA roaming indicators which means international roaming -->
+ <integer-array translatable="false" name="config_cdma_international_roaming_indicators" />
+
</resources>
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
index f7ebbe4..dd1f815 100644
--- a/core/res/res/values/dimens_material.xml
+++ b/core/res/res/values/dimens_material.xml
@@ -87,9 +87,9 @@
<dimen name="floating_window_margin_bottom">32dp</dimen>
<!-- Elevation when button is pressed -->
- <dimen name="button_elevation_material">1dp</dimen>
+ <dimen name="button_elevation_material">4dp</dimen>
<!-- Z translation to apply when button is pressed -->
- <dimen name="button_pressed_z_material">2dp</dimen>
+ <dimen name="button_pressed_z_material">6dp</dimen>
<!-- Default insets (outer padding) around buttons -->
<dimen name="button_inset_vertical_material">6dp</dimen>
<dimen name="button_inset_horizontal_material">@dimen/control_inset_material</dimen>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index a9123d1..ad2e302 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2138,5 +2138,6 @@
<java-symbol type="string" name="system_error_wipe_data" />
<java-symbol type="string" name="system_error_manufacturer" />
<java-symbol type="dimen" name="fast_scroller_minimum_touch_target" />
+ <java-symbol type="array" name="config_cdma_international_roaming_indicators" />
</resources>
diff --git a/data/keyboards/Vendor_046d_Product_b501.kl b/data/keyboards/Vendor_046d_Product_b501.kl
new file mode 100644
index 0000000..496ddc3
--- /dev/null
+++ b/data/keyboards/Vendor_046d_Product_b501.kl
@@ -0,0 +1,65 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Logitech Bluetooth wireless gamepad (RedHawk)
+
+key 304 BUTTON_A
+key 305 BUTTON_B
+key 307 BUTTON_X
+key 308 BUTTON_Y
+key 310 BUTTON_L1
+key 311 BUTTON_R1
+key 312 BUTTON_L2
+key 313 BUTTON_R2
+
+key 314 BUTTON_SELECT
+key 315 BUTTON_START
+key 316 BUTTON_MODE
+key 317 BUTTON_THUMBL
+key 318 BUTTON_THUMBR
+
+key 103 DPAD_UP
+key 105 DPAD_LEFT
+key 106 DPAD_RIGHT
+key 108 DPAD_DOWN
+key 353 DPAD_CENTER
+
+key 113 VOLUME_MUTE
+key 114 VOLUME_DOWN
+key 115 VOLUME_UP
+key 152 POWER
+key 163 MEDIA_NEXT
+key 164 MEDIA_PLAY_PAUSE
+key 165 MEDIA_PREVIOUS
+
+key 158 BACK
+key 172 HOME
+
+key 217 SEARCH
+key 580 APP_SWITCH
+key 582 ASSIST
+
+axis 0x00 X
+axis 0x01 Y
+axis 0x02 Z
+axis 0x05 RZ
+axis 0x09 RTRIGGER
+axis 0x0a LTRIGGER
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+led 0x00 CONTROLLER_1
+led 0x01 CONTROLLER_2
+led 0x02 CONTROLLER_3
+led 0x03 CONTROLLER_4
diff --git a/data/keyboards/Vendor_1532_Product_0900.kl b/data/keyboards/Vendor_1532_Product_0900.kl
new file mode 100644
index 0000000..c2fc1b4
--- /dev/null
+++ b/data/keyboards/Vendor_1532_Product_0900.kl
@@ -0,0 +1,42 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Razer Serval
+
+key 304 BUTTON_A
+key 305 BUTTON_B
+key 307 BUTTON_X
+key 308 BUTTON_Y
+key 310 BUTTON_L1
+key 311 BUTTON_R1
+key 316 BUTTON_MODE
+key 317 BUTTON_THUMBL
+key 318 BUTTON_THUMBR
+
+key 158 BACK
+key 172 HOME
+
+axis 0x00 X
+axis 0x01 Y
+axis 0x02 Z
+axis 0x05 RZ
+axis 0x09 RTRIGGER
+axis 0x0a LTRIGGER
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+led 0x00 CONTROLLER_1
+led 0x01 CONTROLLER_2
+led 0x02 CONTROLLER_3
+led 0x03 CONTROLLER_4
diff --git a/docs/html/guide/topics/manifest/uses-feature-element.jd b/docs/html/guide/topics/manifest/uses-feature-element.jd
index 775c424..59bf71c 100644
--- a/docs/html/guide/topics/manifest/uses-feature-element.jd
+++ b/docs/html/guide/topics/manifest/uses-feature-element.jd
@@ -560,7 +560,7 @@
<td></td>
</tr>
<tr>
- <td rowspan="12">Camera</td>
+ <td rowspan="10">Camera</td>
<td><code>android.hardware.camera</code></td>
<td>The application uses the device's camera. If the device supports
multiple cameras, the application uses the camera that facing
@@ -609,14 +609,6 @@
<td><code>android.hardware.camera.capability.raw</code></td>
<td>The application uses a a camera device with the <code>RAW</code> capability.</td>
</tr>
-<tr>
- <td><code>android.hardware.camera.capability.burst_capture</code></td>
- <td>The application uses a a camera device with the <code>BURST_CAPTURE</code> capability.</td>
-</tr>
-<tr>
- <td><code>android.hardware.camera.capability.read_sensor_settings</code></td>
- <td>The application uses a a camera device with the <code>READ_SENSOR_SETTINGS</code> capability.</td>
-</tr>
<tr>
<td>Infrared</td>
diff --git a/docs/html/samples/admin.jd b/docs/html/samples/admin.jd
new file mode 100644
index 0000000..c6637d8
--- /dev/null
+++ b/docs/html/samples/admin.jd
@@ -0,0 +1,11 @@
+page.title=Admin
+@jd:body
+
+
+<div id="samples" class="admin">
+</div>
+
+
+<script>
+ $(document).ready(showSamples);
+</script>
diff --git a/docs/html/samples/new/index.jd b/docs/html/samples/new/index.jd
index ba75072..279b910 100644
--- a/docs/html/samples/new/index.jd
+++ b/docs/html/samples/new/index.jd
@@ -2,19 +2,18 @@
@jd:body
-<p>The following code samples were recently published for the L Developer Preview. You can
+<p>The following code samples were recently published. You can
download them in the Android SDK Manager under the <b>SDK Samples</b> component
-for the L Developer Preview.</p>
+for API 21.</p>
<p class="note">
- <strong>Note:</strong> At this time, the downloadable projects are designed
+ <strong>Note:</strong> The downloadable projects are designed
for use with Gradle and Android Studio.
</p>
-
<!-- NOTE TO EDITORS: add most recent samples first -->
-<h3 id="MediaBrowserService">Media Browser Service</h3>
+<h3 id="MediaBrowserService"><a href="/samples/MediaBrowserService/index.html">Media Browser Service</a></h3>
<p>
This sample is a simple audio media app that exposes its media
@@ -29,10 +28,8 @@
href="http://android.com/auto">Android Auto</a>.
</p>
-<p><a href="http://github.com/googlesamples/android-MediaBrowserService">Get it on GitHub</a></p>
-
-<h3 id="MessagingService">Messaging Service</h3>
+<h3 id="MessagingService"><a href="/samples/MessagingService/index.html">Messaging Service</a></h3>
<p>
This sample shows a simple service that sends notifications using
@@ -46,10 +43,8 @@
href="http://android.com/auto">Android Auto</a>.
</p>
-<p><a href="http://github.com/googlesamples/android-MessagingService">Get it on GitHub</a></p>
-
-<h3 id="SpeedTracker">Speed Tracker (Wear)</h3>
+<h3 id="SpeedTracker"><a href="/samples/SpeedTracker/index.html">Speed Tracker (Wear)</a></h3>
<p>
This sample uses the FusedLocation APIs of Google Play Services on Android Wear
@@ -62,10 +57,8 @@
made of those coordinates on a map on the phone.
</p>
-<p><a href="http://github.com/googlesamples/android-SpeedTracker">Get it on GitHub</a></p>
-
-<h3 id="AppRestrictionSchema">AppRestrictionSchema</h3>
+<h3 id="AppRestrictionSchema"><a href="/samples/AppRestrictionSchema/index.html">AppRestrictionSchema</a></h3>
<p>
This sample shows how to use app restrictions. This application has one boolean
@@ -74,29 +67,23 @@
AppRestrictionEnforcer sample to toggle the restriction.
</p>
-<p><a href="http://github.com/googlesamples/android-AppRestrictionSchema">Get it on GitHub</a></p>
-
-<h3 id="AppRestrictionEnforcer">AppRestrictionEnforcer</h3>
+<h3 id="AppRestrictionEnforcer"><a href="/samples/AppRestrictionEnforcer/index.html">AppRestrictionEnforcer</a></h3>
<p>
This sample demonstrates how to set restrictions to other apps as a profile owner.
Use AppRestrictionSchema sample as a app with available restrictions.
</p>
-<p><a href="http://github.com/googlesamples/android-AppRestrictionEnforcer">Get it on GitHub</a></p>
-
-<h3 id="DocumentCentricRelinquishIdentity">DocumentCentricRelinquishIdentity</h3>
+<h3 id="DocumentCentricRelinquishIdentity"><a href="/samples/DocumentCentricRelinquishIdentity/index.html">DocumentCentricRelinquishIdentity</a></h3>
<p>
This sample shows how to relinquish identity to activities above it in the task stack.
</p>
-<p><a href="http://github.com/googlesamples/android-DocumentCentricRelinquishIdentity">Get it on GitHub</a></p>
-
-<h3 id="DocumentCentricApps">DocumentCentricApps</h3>
+<h3 id="DocumentCentricApps"><a href="/samples/DocumentCentricApps/index.html">DocumentCentricApps</a></h3>
<p>
This sample shows the basic usage of the new "Document Centric Apps" API.
@@ -105,10 +92,8 @@
created for every new document in the overview menu.
</p>
-<p><a href="http://github.com/googlesamples/android-DocumentCentricApps">Get it on GitHub</a></p>
-
-<h3 id="HdrViewfinder">HdrViewfinder</h3>
+<h3 id="HdrViewfinder"><a href="/samples/HdrViewfinder/index.html">HdrViewfinder</a></h3>
<p>
This demo implements a real-time high-dynamic-range camera viewfinder, by alternating
@@ -116,10 +101,8 @@
compositing together the latest two frames whenever a new frame is captured.
</p>
-<p><a href="http://github.com/googlesamples/android-HdrViewfinder">Get it on GitHub</a></p>
-
-<h3 id="Interpolator">Interpolator</h3>
+<h3 id="Interpolator"><a href="/samples/Interpolator/index.html">Interpolator</a></h3>
<p>
This sample demonstrates the use of animation interpolators and path animations for
@@ -127,10 +110,8 @@
view (scale X and Y) along a path.
</p>
-<p><a href="http://github.com/googlesamples/android-Interpolator">Get it on GitHub</a></p>
-
-<h3 id="DrawableTinting">DrawableTinting</h3>
+<h3 id="DrawableTinting"><a href="/samples/DrawableTinting/index.html">DrawableTinting</a></h3>
<p>Sample that shows applying tinting and color filters to Drawables both programmatically
and as Drawable resources in XML.</p>
@@ -141,54 +122,43 @@
with a reference to a color and a PorterDuff blend mode. The color and blend mode can be
changed from the UI to see the effect of different options.</p>
-<p><a href="http://github.com/googlesamples/android-DrawableTinting">Get it on GitHub</a></p>
-
-<h3 id="LNotifications">LNotifications</h3>
+<h3 id="LNotifications"><a href="/samples/LNotifications/index.html">LNotifications</a></h3>
<p>
This sample demonstrates how new features for notifications introduced in Android 5.0
are used such as Heads-Up notifications, visibility, people, category and priority
metadata. </p>
-<p><a href="http://github.com/googlesamples/android-LNotifications">Get it on GitHub</a></p>
-<h3 id="CardView">CardView</h3>
+<h3 id="CardView"><a href="/samples/CardView/index.html">CardView</a></h3>
<p>
This sample demonstrates how to use the CardView UI widget introduced in Android 5.0, using the support library for backward compatibility.
</p>
-<p><a href="http://github.com/googlesamples/android-CardView">Get it on GitHub</a></p>
-
-<h3 id="RecyclerView">RecyclerView</h3>
+<h3 id="RecyclerView"><a href="/samples/RecyclerView/index.html">RecyclerView</a></h3>
<p>
Demonstration of using RecyclerView with a LayoutManager to create a vertical ListView.
</p>
-<p><a href="http://github.com/googlesamples/android-RecyclerView">Get it on GitHub</a></p>
-
-<h3 id="RevealEffectBasic">RevealEffectBasic</h3>
+<h3 id="RevealEffectBasic"><a href="/samples/RevealEffectBasic/index.html">RevealEffectBasic</a></h3>
<p>
A sample demonstrating how to perform a reveal effect for UI elements within the Material Design framework.
</p>
-<p><a href="http://github.com/googlesamples/android-RevealEffectBasic">Get it on GitHub</a></p>
-
-<h3 id="FloatingActionButtonBasic">FloatingActionButtonBasic</h3>
+<h3 id="FloatingActionButtonBasic"><a href="/samples/FloatingActionButtonBasic/index.html">FloatingActionButtonBasic</a></h3>
<p>
This sample shows the two sizes of Floating Action Buttons and how to interact with
them.
</p>
-<p><a href="http://github.com/googlesamples/android-FloatingActionButtonBasic">Get it on GitHub</a></p>
-
<!--
<h3 id="">SampleName</h3>
@@ -205,36 +175,15 @@
</p>
-->
-
-<h3 id="NavigationDrawerSample">NavigationDrawerSample</h3>
-<!--
-<div class="figure" style="width:220px">
- <img src="" srcset="@2x.png 2x" alt="" height="375" />
- <p class="img-caption">
- <strong>Figure n.</strong> Single sentence summarizing the figure.
- </p>
-</div>
--->
-
-<p>
-This sample illustrates a common usage of the Android support library's
-{@link android.support.v4.widget.DrawerLayout} widget.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-NavigationDrawer">Get it on GitHub</a></p>
-
-
-<h3 id="JobSchedulerSample">JobSchedulerSample</h3>
+<h3 id="JobSchedulerSample"><a href="/samples/JobScheduler/index.html">JobScheduler</a></h3>
<p>
This sample app allows the user to schedule jobs through the UI, and shows
visual cues when the jobs are executed.
</p>
-<p><a href="http://github.com/googlesamples/android-JobScheduler">Get it on GitHub</a></p>
-
-<h3 id="AndroidTVLeanbackSample">AndroidTVLeanbackSample</h3>
+<h3 id="AndroidTVLeanbackSample"><a href="https://github.com/googlesamples/androidtv-leanback">AndroidTVLeanbackSample</a></h3>
<!--
<div class="figure" style="width:220px">
<img src="" srcset="@2x.png 2x" alt="" height="375" />
@@ -248,10 +197,7 @@
This sample demonstrates use of the Android TV Leanback Support Library.
</p>
-<p><a href="http://github.com/googlesamples/androidtv-Leanback">Get it on GitHub</a></p>
-
-
-<h3 id="Visual-Game-Controller">Visual-Game-Controller</h3>
+<h3 id="Visual-Game-Controller"><a href="https://github.com/googlesamples/androidtv-VisualGameController">Visual-Game-Controller</a></h3>
<!--
<div class="figure" style="width:220px">
<img src="" srcset="@2x.png 2x" alt="" height="375" />
@@ -265,10 +211,8 @@
This sample displays events received from a game controller shown on the screen.
</p>
-<p><a href="http://github.com/googlesamples/androidtv-VisualGameController">Get it on GitHub</a></p>
-
-<h3 id="GameControllerSample">GameControllerSample</h3>
+<h3 id="GameControllerSample"><a href="https://github.com/googlesamples/androidtv-GameController/">GameControllerSample</a></h3>
<!--
<div class="figure" style="width:220px">
<img src="" srcset="@2x.png 2x" alt="" height="375" />
@@ -283,10 +227,8 @@
handling.
</p>
-<p><a href="http://github.com/googlesamples/androidtv-GameController">Get it on GitHub</a></p>
-
-<h3 id="ClippingBasic">ClippingBasic</h3>
+<h3 id="ClippingBasic"><a href="/samples/ClippingBasic/index.html">ClippingBasic</a></h3>
<!--
<div class="figure" style="width:220px">
<img src="" srcset="@2x.png 2x" alt="" height="375" />
@@ -300,19 +242,17 @@
This sample demonstrates clipping on a {@link android.view.View}.
</p>
-<p><a href="http://github.com/googlesamples/android-ClippingBasic">Get it on GitHub</a></p>
-
<div class="figure" style="width:220px">
<img src="{@docRoot}samples/images/JobSchedulerSample.png"
srcset="{@docRoot}samples/images/JobSchedulerSample@2x.png 2x"
alt="" height="375" />
<p class="img-caption">
- <strong>Figure 3.</strong> The JobSchedulerSample sample app.
+ <strong>Figure 1.</strong> The JobSchedulerSample sample app.
</p>
</div>
-<h3 id="ElevationDrag">ElevationDrag</h3>
+<h3 id="ElevationDrag"><a href="/samples/ElevationDrag/index.html">ElevationDrag</a></h3>
<!--
<div class="figure" style="width:220px">
<img src="" srcset="@2x.png 2x" alt="" height="375" />
@@ -326,10 +266,8 @@
Elevation and z-translation are used to render the shadows. The views are
clipped using different outlines.</p>
-<p><a href="http://github.com/googlesamples/android-ElevationDrag">Get it on GitHub</a></p>
-
-<h3 id="ElevationBasic">ElevationBasic</h3>
+<h3 id="ElevationBasic"><a href="/samples/ElevationBasic/index.html">ElevationBasic</a></h3>
<!--
<div class="figure" style="width:220px">
<img src="" srcset="@2x.png 2x" alt="" height="375" />
@@ -348,10 +286,8 @@
<code>setTranslationZ()</code>.</li>
</ul>
-<p><a href="http://github.com/googlesamples/android-ElevationBasic">Get it on GitHub</a></p>
-
-<h3 id="ActivitySceneTransitionBasic">ActivitySceneTransitionBasic</h3>
+<h3 id="ActivitySceneTransitionBasic"><a href="/samples/ActivitySceneTransitionBasic/index.html">ActivitySceneTransitionBasic</a></h3>
<div class="figure" style="width:220px">
<img src="{@docRoot}samples/images/ActivitySceneTransitionBasic.png"
srcset="{@docRoot}samples/images/ActivitySceneTransitionBasic@2x.png 2x"
@@ -366,10 +302,8 @@
of <code>moveImage</code> and <code>changeBounds</code> to nicely transition
from a grid of images to an activity with a large image and detail text. </p>
-<p><a href="http://github.com/googlesamples/android-ActivitySceneTransition">Get it on GitHub</a></p>
-
-<h3 id="Camera2Video">Camera2Video</h3>
+<h3 id="Camera2Video"><a href="/samples/Camera2Video/index.html">Camera2Video</a></h3>
<!--
<div class="figure" style="width:220px">
<img src="" srcset="@2x.png 2x" alt="" height="375" />
@@ -381,10 +315,8 @@
<p>This sample demonstrates how to record video using the Camera2 API.</p>
-<p><a href="http://github.com/googlesamples/android-Camera2Video">Get it on GitHub</a></p>
-
-<h3 id="Camera2Basic">Camera2Basic</h3>
+<h3 id="Camera2Basic"><a href="/samples/Camera2Basic/index.html">Camera2Basic</a></h3>
<!--
<div class="figure" style="width:220px">
@@ -398,16 +330,14 @@
<p>This sample demonstrates the basic use of the Camera2 API. The sample code
demonstrates how you can display camera preview and take pictures.</p>
-<p><a href="http://github.com/googlesamples/android-Camera2Basic">Get it on GitHub</a></p>
-
-<h3 id="BasicManagedProfile">BasicManagedProfile</h3>
+<h3 id="BasicManagedProfile"><a href="/samples/BasicManagedProfile/index.html">BasicManagedProfile</a></h3>
<div class="figure" style="width:220px">
<img src="{@docRoot}samples/images/BasicManagedProfile.png"
srcset="{@docRoot}samples/images/BasicManagedProfile@2x.png 2x"
alt="" height="375" />
<p class="img-caption">
- <strong>Figure 1.</strong> The BasicManagedProfile sample app.
+ <strong>Figure 3.</strong> The BasicManagedProfile sample app.
</p>
</div>
@@ -422,5 +352,3 @@
<p class="note"><strong>Note:</strong> There can be only one managed profile on
a device at a time.</p>
-<p><a href="http://github.com/googlesamples/android-BasicManagedProfile">Get it on GitHub</a></p>
-
diff --git a/packages/Keyguard/res/values-ca/strings.xml b/packages/Keyguard/res/values-ca/strings.xml
index 3ca1368..82023d2 100644
--- a/packages/Keyguard/res/values-ca/strings.xml
+++ b/packages/Keyguard/res/values-ca/strings.xml
@@ -130,18 +130,18 @@
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Has escrit malament el PIN <xliff:g id="NUMBER_0">%d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Has dibuixat el patró de desbloqueig de manera incorrecta <xliff:g id="NUMBER_0">%d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="8774056606869646621">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Et queden <xliff:g id="NUMBER_1">%d</xliff:g> intents més. Si no ho fas bé, la tauleta es restablirà i se n\'esborraran totes les dades."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="1843331751334128428">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Et queden <xliff:g id="NUMBER_1">%d</xliff:g> intents més. Si no ho fas bé, el telèfon es restablirà i se n\'esborraran totes les dades."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="258925501999698032">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. La tauleta es restablirà i se n\'esborraran totes les dades."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="7154028908459817066">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. El telèfon es restablirà i se n\'esborraran totes les dades."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="6159955099372112688">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Et queden <xliff:g id="NUMBER_1">%d</xliff:g> intents més. Si no ho fas bé, l\'usuari se suprimirà, juntament amb totes les seves dades."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="6945823186629369880">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Et queden <xliff:g id="NUMBER_1">%d</xliff:g> intents més. Si no ho fas bé, l\'usuari se suprimirà, juntament amb totes les seves dades."</string>
- <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="3963486905355778734">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. L\'usuari se suprimirà, juntament amb totes les seves dades."</string>
- <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="7729009752252111673">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. L\'usuari se suprimirà, juntament amb totes les seves dades."</string>
- <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="4621778507387853694">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Et queden <xliff:g id="NUMBER_1">%d</xliff:g> intents més. Si no ho fas bé, el perfil professional se suprimirà, juntament amb totes les dades que contingui."</string>
- <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="6853071165802933545">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Et queden <xliff:g id="NUMBER_1">%d</xliff:g> intents més. Si no ho fas bé, el perfil professional se suprimirà, juntament amb totes les dades que contingui."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4686386497449912146">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. El perfil professional se suprimirà, juntament amb totes les dades que contingui."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4951507352869831265">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. El perfil professional se suprimirà, juntament amb totes les dades que contingui."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="8774056606869646621">"Has provat de desbloquejar la tauleta incorrectament <xliff:g id="NUMBER_0">%d</xliff:g> vegades. Et queden <xliff:g id="NUMBER_1">%d</xliff:g> intents més. Si no ho fas bé, la tauleta es restablirà i se n\'esborraran totes les dades."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="1843331751334128428">"Has provat de desbloquejar el telèfon incorrectament <xliff:g id="NUMBER_0">%d</xliff:g> vegades. Et queden <xliff:g id="NUMBER_1">%d</xliff:g> intents més. Si no ho fas bé, el telèfon es restablirà i se n\'esborraran totes les dades."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="258925501999698032">"Has provat de desbloquejar la tauleta incorrectament <xliff:g id="NUMBER">%d</xliff:g> vegades. La tauleta es restablirà i se n\'esborraran totes les dades."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="7154028908459817066">"Has provat de desbloquejar el telèfon incorrectament <xliff:g id="NUMBER">%d</xliff:g> vegades. El telèfon es restablirà i se n\'esborraran totes les dades."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="6159955099372112688">"Has provat de desbloquejar la tauleta incorrectament <xliff:g id="NUMBER_0">%d</xliff:g> vegades. Et queden <xliff:g id="NUMBER_1">%d</xliff:g> intents més. Si no ho fas bé, l\'usuari se suprimirà, juntament amb totes les seves dades."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="6945823186629369880">"Has provat de desbloquejar el telèfon incorrectament <xliff:g id="NUMBER_0">%d</xliff:g> vegades. Et queden <xliff:g id="NUMBER_1">%d</xliff:g> intents més. Si no ho fas bé, l\'usuari se suprimirà, juntament amb totes les seves dades."</string>
+ <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="3963486905355778734">"Has provat de desbloquejar la tauleta incorrectament <xliff:g id="NUMBER">%d</xliff:g> vegades. L\'usuari se suprimirà, juntament amb totes les seves dades."</string>
+ <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="7729009752252111673">"Has provat de desbloquejar el telèfon incorrectament <xliff:g id="NUMBER">%d</xliff:g> vegades. L\'usuari se suprimirà, juntament amb totes les seves dades."</string>
+ <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="4621778507387853694">"Has provat de desbloquejar la tauleta incorrectament <xliff:g id="NUMBER_0">%d</xliff:g> vegades. Et queden <xliff:g id="NUMBER_1">%d</xliff:g> intents més. Si no ho fas bé, el perfil professional se suprimirà, juntament amb totes les dades que contingui."</string>
+ <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="6853071165802933545">"Has provat de desbloquejar el telèfon incorrectament <xliff:g id="NUMBER_0">%d</xliff:g> vegades. Et queden <xliff:g id="NUMBER_1">%d</xliff:g> intents més. Si no ho fas bé, el perfil professional se suprimirà, juntament amb totes les dades que contingui."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4686386497449912146">"Has provat de desbloquejar la tauleta incorrectament <xliff:g id="NUMBER">%d</xliff:g> vegades. El perfil professional se suprimirà, juntament amb totes les dades que contingui."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4951507352869831265">"Has provat de desbloquejar el telèfon incorrectament <xliff:g id="NUMBER">%d</xliff:g> vegades. El perfil professional se suprimirà, juntament amb totes les dades que contingui."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis la tauleta amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis el telèfon amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
<string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
diff --git a/packages/Keyguard/res/values-zh-rHK/strings.xml b/packages/Keyguard/res/values-zh-rHK/strings.xml
index 190a19e..9051a7b 100644
--- a/packages/Keyguard/res/values-zh-rHK/strings.xml
+++ b/packages/Keyguard/res/values-zh-rHK/strings.xml
@@ -130,10 +130,10 @@
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"您已輸入錯誤的 PIN 碼 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"您已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="8774056606869646621">"您已 <xliff:g id="NUMBER_0">%d</xliff:g> 次錯誤解鎖平板電腦。如再解鎖失敗 <xliff:g id="NUMBER_1">%d</xliff:g> 次,該平板電腦將被重設,平板電腦的所有資料將因此被刪除。"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="1843331751334128428">"您已 <xliff:g id="NUMBER_0">%d</xliff:g> 次錯誤解鎖手機。如再解鎖失敗 <xliff:g id="NUMBER_1">%d</xliff:g> 次,該手機將被重設,手機的所有資料將因此被刪除。"</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="258925501999698032">"您已 <xliff:g id="NUMBER">%d</xliff:g> 次錯誤解鎖手機。該平板電腦將被重設,平板電腦的所有資料將因此被刪除。"</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="7154028908459817066">"您已 <xliff:g id="NUMBER">%d</xliff:g> 次錯誤解鎖手機。該手機將被重設,手機的所有資料將因此被刪除。"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="8774056606869646621">"您已 <xliff:g id="NUMBER_0">%d</xliff:g> 次錯誤解鎖平板電腦。如再解鎖失敗 <xliff:g id="NUMBER_1">%d</xliff:g> 次,平板電腦將被重設,平板電腦的所有資料將因此被刪除。"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="1843331751334128428">"您已 <xliff:g id="NUMBER_0">%d</xliff:g> 次錯誤解鎖手機。如再解鎖失敗 <xliff:g id="NUMBER_1">%d</xliff:g> 次,手機將被重設,手機的所有資料將因此被刪除。"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="258925501999698032">"您已 <xliff:g id="NUMBER">%d</xliff:g> 次錯誤解鎖手機。平板電腦將被重設,平板電腦的所有資料將因此被刪除。"</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="7154028908459817066">"您已 <xliff:g id="NUMBER">%d</xliff:g> 次錯誤解鎖手機。手機將被重設,手機的所有資料將因此被刪除。"</string>
<string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="6159955099372112688">"您已 <xliff:g id="NUMBER_0">%d</xliff:g> 次錯誤解鎖平板電腦。如再解鎖失敗 <xliff:g id="NUMBER_1">%d</xliff:g> 次,該使用者將被移除,所有使用者資料將因此被刪除。"</string>
<string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="6945823186629369880">"您已 <xliff:g id="NUMBER_0">%d</xliff:g> 次錯誤解鎖手機。如再解鎖失敗 <xliff:g id="NUMBER_1">%d</xliff:g> 次,該使用者將被移除,所有使用者資料將因此被刪除。"</string>
<string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="3963486905355778734">"您已 <xliff:g id="NUMBER">%d</xliff:g> 次錯誤解鎖平板電腦。該使用者將被移除,所有使用者資料將因此被刪除。"</string>
diff --git a/packages/PrintSpooler/res/values-es-rUS/arrays.xml b/packages/PrintSpooler/res/values-es-rUS/arrays.xml
new file mode 100644
index 0000000..c1b149c
--- /dev/null
+++ b/packages/PrintSpooler/res/values-es-rUS/arrays.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+
+ <string-array name="pdf_printer_media_sizes" translatable="false">
+ <item>NA_LETTER</item>
+ <item>NA_GOVT_LETTER</item>
+ <item>NA_LEGAL</item>
+ <item>NA_JUNIOR_LEGAL</item>
+ <item>NA_LEDGER</item>
+ <item>NA_TABLOID</item>
+ <item>NA_INDEX_3X5</item>
+ <item>NA_INDEX_4X6</item>
+ <item>NA_INDEX_5X8</item>
+ <item>NA_MONARCH</item>
+ <item>NA_QUARTO</item>
+ <item>NA_FOOLSCAP</item>
+ </string-array>
+
+</resources>
diff --git a/packages/SystemUI/res/drawable/pop_ball.xml b/packages/SystemUI/res/drawable/pop_ball.xml
new file mode 100644
index 0000000..ee1220f
--- /dev/null
+++ b/packages/SystemUI/res/drawable/pop_ball.xml
@@ -0,0 +1,29 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="100.0dp"
+ android:height="100.0dp"
+ android:viewportWidth="100.0"
+ android:viewportHeight="100.0">
+ <path
+ android:pathData="M0,50 a50,50 0 1 1 100,0
+ a50,50 0 1 1 -100,0"
+ android:fillColor="#FFFF1744"/>
+ <path
+ android:pathData="M16,36 A24,24 0 1 1 64,36
+ M64,36 A24,24 0 1 1 16,36"
+ android:fillColor="#20FFFFFF"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/pop_belt.xml b/packages/SystemUI/res/drawable/pop_belt.xml
index 5c0c3d7..e0ea575 100644
--- a/packages/SystemUI/res/drawable/pop_belt.xml
+++ b/packages/SystemUI/res/drawable/pop_belt.xml
@@ -20,14 +20,14 @@
android:viewportHeight="100.0">
<path
android:pathData="M50.000000,50.000000m-47.599998,0.000000a47.599998,47.599998 0.000000,1.000000 1.000000,95.199997 0.000000a47.599998,47.599998 0.000000,1.000000 1.000000,-95.199997 0.000000"
- android:fillColor="#D81B60"/>
+ android:fillColor="#9C27B0"/>
<path
android:pathData="M50.000000,2.429000c-26.337999,0.000000 -47.688999,21.351000 -47.688999,47.688999c0.000000,13.168000 5.337000,25.091000 13.968000,33.722000l67.444000,-67.443001C75.092003,7.766000 63.168999,2.429000 50.000000,2.429000z"
- android:fillColor="#F06292"/>
+ android:fillColor="#BA68C8"/>
<path
android:pathData="M0.000000,41.573002l100.000000,0.000000l0.000000,17.090000l-100.000000,0.000000z"
- android:fillColor="#D81B60"/>
+ android:fillColor="#9C27B0"/>
<path
android:pathData="M0.000000,58.662998l0.000000,-17.089996 100.000000,0.000000z"
- android:fillColor="#F06292"/>
+ android:fillColor="#BA68C8"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/pop_pizza.xml b/packages/SystemUI/res/drawable/pop_pizza.xml
index b6d2bb3..1806b5a 100644
--- a/packages/SystemUI/res/drawable/pop_pizza.xml
+++ b/packages/SystemUI/res/drawable/pop_pizza.xml
@@ -20,26 +20,26 @@
android:viewportHeight="100.0">
<path
android:pathData="M14.645000,14.645000C5.597000,23.693001 0.000000,36.193001 0.000000,50.000000l50.000000,0.000000L14.645000,14.645000z"
- android:fillColor="#7BAAF7"/>
+ android:fillColor="#2979FF"/>
<path
android:pathData="M100.000000,50.000000c0.000000,-13.807000 -5.597000,-26.306999 -14.645000,-35.355000L50.000000,50.000000L100.000000,50.000000z"
- android:fillColor="#D81B60"/>
+ android:fillColor="#FF1744"/>
<path
android:pathData="M85.355003,14.645000C76.306999,5.597000 63.806999,0.000000 50.000000,0.000000l0.000000,50.000000L85.355003,14.645000z"
- android:fillColor="#F06292"/>
+ android:fillColor="#0F9D58"/>
<path
android:pathData="M50.000000,0.000000C36.193001,0.000000 23.693001,5.597000 14.645000,14.645000L50.000000,50.000000L50.000000,0.000000z"
- android:fillColor="#FFF176"/>
+ android:fillColor="#FFBC00"/>
<path
android:pathData="M50.000000,50.000000l35.355000,35.355000C94.403000,76.307999 100.000000,63.807999 100.000000,50.000000L50.000000,50.000000z"
- android:fillColor="#7BAAF7"/>
+ android:fillColor="#2979FF"/>
<path
android:pathData="M50.000000,100.000000c13.807000,0.000000 26.306999,-5.596000 35.355000,-14.645000L50.000000,50.000000L50.000000,100.000000z"
- android:fillColor="#FFF176"/>
+ android:fillColor="#FFBC00"/>
<path
android:pathData="M14.645000,85.355003C23.693001,94.403999 36.193001,100.000000 50.000000,100.000000L50.000000,50.000000L14.645000,85.355003z"
- android:fillColor="#F06292"/>
+ android:fillColor="#0F9D58"/>
<path
android:pathData="M0.000000,50.000000c0.000000,13.808000 5.597000,26.308001 14.645000,35.355000L50.000000,50.000000L0.000000,50.000000z"
- android:fillColor="#D81B60"/>
+ android:fillColor="#FF1744"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/pop_swirl.xml b/packages/SystemUI/res/drawable/pop_swirl.xml
index acd6d3d..f87569b 100644
--- a/packages/SystemUI/res/drawable/pop_swirl.xml
+++ b/packages/SystemUI/res/drawable/pop_swirl.xml
@@ -20,7 +20,7 @@
android:viewportHeight="100.0">
<path
android:pathData="M50.000000,50.000000C86.898003,27.834999 79.244003,11.688000 76.177002,7.399000c-7.240000,-4.459000 -15.703000,-7.112000 -24.770000,-7.363000C56.247002,2.253000 70.815002,12.456000 50.000000,50.000000z"
- android:fillColor="#82B1FF"/>
+ android:fillColor="#FFFFFA"/>
<path
android:pathData="M50.000000,50.000000c20.815001,-37.543999 6.247000,-47.747002 1.407000,-49.964001C50.938000,0.022000 50.472000,0.000000 50.000000,0.000000c-8.627000,0.000000 -16.743999,2.186000 -23.827000,6.032000C31.392000,5.514000 49.251999,6.903000 50.000000,50.000000z"
android:fillColor="#76FF03"/>
@@ -32,7 +32,7 @@
android:fillColor="#303F9F"/>
<path
android:pathData="M50.000000,50.000000C27.834000,13.103000 11.687000,20.757000 7.398000,23.823999C2.940000,31.063000 0.287000,39.527000 0.035000,48.592999C2.253000,43.752998 12.456000,29.184999 50.000000,50.000000z"
- android:fillColor="#FAFAFA"/>
+ android:fillColor="#FFFFFA"/>
<path
android:pathData="M50.000000,50.000000C49.251999,6.903000 31.392000,5.514000 26.173000,6.032000c-7.709000,4.187000 -14.188000,10.344000 -18.774000,17.792000C11.687000,20.757000 27.834000,13.103000 50.000000,50.000000z"
android:fillColor="#303F9F"/>
@@ -44,13 +44,13 @@
android:fillColor="#303F9F"/>
<path
android:pathData="M50.000000,50.000000c22.166000,36.897999 38.313000,29.243999 42.602001,26.177999c4.458000,-7.240000 7.111000,-15.703000 7.363000,-24.770000C97.747002,56.248001 87.543999,70.816002 50.000000,50.000000z"
- android:fillColor="#FAFAFA"/>
+ android:fillColor="#FFFFFA"/>
<path
android:pathData="M50.000000,50.000000c-20.815001,37.544998 -6.247000,47.748001 -1.407000,49.965000C49.062000,99.978996 49.528000,100.000000 50.000000,100.000000c8.627000,0.000000 16.743999,-2.185000 23.827000,-6.031000C68.608002,94.486000 50.748001,93.098000 50.000000,50.000000z"
android:fillColor="#76FF03"/>
<path
android:pathData="M50.000000,50.000000C13.103000,72.166000 20.757000,88.313004 23.823000,92.601997c7.240000,4.459000 15.703000,7.112000 24.770000,7.363000C43.752998,97.748001 29.184999,87.544998 50.000000,50.000000z"
- android:fillColor="#82B1FF"/>
+ android:fillColor="#FFFFFA"/>
<path
android:pathData="M50.000000,50.000000C6.902000,50.749001 5.514000,68.609001 6.032000,73.828003c4.186000,7.708000 10.344000,14.188000 17.791000,18.773001C20.757000,88.313004 13.103000,72.166000 50.000000,50.000000z"
android:fillColor="#303F9F"/>
diff --git a/packages/SystemUI/res/drawable/pop_vortex.xml b/packages/SystemUI/res/drawable/pop_vortex.xml
index faefcb1..2380e68 100644
--- a/packages/SystemUI/res/drawable/pop_vortex.xml
+++ b/packages/SystemUI/res/drawable/pop_vortex.xml
@@ -20,7 +20,7 @@
android:viewportHeight="100.0">
<path
android:pathData="M50.000000,50.000000m-50.000000,0.000000a50.000000,50.000000 0.000000,1.000000 1.000000,100.000000 0.000000a50.000000,50.000000 0.000000,1.000000 1.000000,-100.000000 0.000000"
- android:fillColor="#FFF176"/>
+ android:fillColor="#F8F8FF"/>
<path
android:pathData="M58.658001,89.648003c-19.330000,0.000000 -35.000000,-15.670000 -35.000000,-35.000000c0.000000,-13.531000 10.969000,-24.500000 24.500000,-24.500000c9.472000,0.000000 17.150000,7.679000 17.150000,17.150000c0.000000,6.631000 -5.375000,12.006000 -12.006000,12.006000c-3.798000,0.000000 -7.004000,-2.522000 -8.045000,-5.982000c1.021000,1.136000 2.497000,1.854000 4.145000,1.854000c2.644000,0.000000 4.853000,-1.841000 5.428000,-4.310000c0.175000,-0.558000 0.271000,-1.150000 0.271000,-1.766000c0.000000,-4.642000 -3.763000,-8.404000 -8.403000,-8.404000c-6.631000,0.000000 -12.006000,5.375000 -12.006000,12.006000c0.000000,9.472000 7.679000,17.149000 17.150000,17.149000c13.531000,0.000000 24.500000,-10.969000 24.500000,-24.500000c0.000000,-19.330000 -15.670000,-35.000000 -35.000000,-35.000000c-12.963000,0.000000 -24.773001,4.935000 -33.657001,13.025000C2.824000,31.087000 0.000000,40.212002 0.000000,50.000000c0.000000,27.615000 22.386000,50.000000 50.000000,50.000000c17.825001,0.000000 33.462002,-9.335000 42.313999,-23.375999C83.431000,84.714996 71.621002,89.648003 58.658001,89.648003z"
android:fillColor="#7BAAF7"/>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 9a95b37..24830e8 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -251,12 +251,21 @@
<!-- Doze: duration to avoid false pickup gestures triggered by notification vibrations -->
<integer name="doze_pickup_vibration_threshold">2000</integer>
+ <!-- Doze: can we assume the pickup sensor includes a proximity check? -->
+ <bool name="doze_pickup_performs_proximity_check">false</bool>
+
<!-- Doze: pulse parameter - how long does it take to fade in? -->
<integer name="doze_pulse_duration_in">900</integer>
- <!-- Doze: pulse parameter - delay for fading so the screen can wake up before -->
+ <!-- Doze: pulse parameter - how long does it take to fade in after a pickup? -->
+ <integer name="doze_pulse_duration_in_pickup">300</integer>
+
+ <!-- Doze: pulse parameter - delay to wait for the screen to wake up -->
<integer name="doze_pulse_delay_in">200</integer>
+ <!-- Doze: pulse parameter - delay to wait for the screen to wake up after a pickup -->
+ <integer name="doze_pulse_delay_in_pickup">200</integer>
+
<!-- Doze: pulse parameter - once faded in, how long does it stay visible? -->
<integer name="doze_pulse_duration_visible">3000</integer>
diff --git a/packages/SystemUI/res/values/lland_config.xml b/packages/SystemUI/res/values/lland_config.xml
index 5d74082..a9e732e 100644
--- a/packages/SystemUI/res/values/lland_config.xml
+++ b/packages/SystemUI/res/values/lland_config.xml
@@ -26,7 +26,7 @@
<dimen name="obstacle_width">90dp</dimen>
<dimen name="obstacle_stem_width">12dp</dimen>
<dimen name="obstacle_gap">170dp</dimen>
- <dimen name="obstacle_height_min">40dp</dimen>
+ <dimen name="obstacle_height_min">48dp</dimen>
<dimen name="building_width_min">20dp</dimen>
<dimen name="building_width_max">250dp</dimen>
<dimen name="building_height_min">20dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
index 7eb9c6e..1f3a830 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -153,7 +153,7 @@
sProxStats[pulseReason][near ? 0 : 1].append();
}
- private static String pulseReasonToString(int pulseReason) {
+ public static String pulseReasonToString(int pulseReason) {
switch (pulseReason) {
case PULSE_REASON_INTENT: return "intent";
case PULSE_REASON_NOTIFICATION: return "notification";
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index 2341144..36995ff 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -217,7 +217,9 @@
// Here we need a wakelock to stay awake until the pulse is finished.
mWakeLock.acquire();
mPulsing = true;
- if (!mDozeParameters.getProxCheckBeforePulse()) {
+ if (!mDozeParameters.getProxCheckBeforePulse() ||
+ reason == DozeLog.PULSE_REASON_SENSOR_PICKUP
+ && mDozeParameters.getPickupPerformsProxCheck()) {
// skip proximity check
continuePulsing(reason);
return;
@@ -340,7 +342,8 @@
if (DEBUG) Log.d(mTag, "No more schedule resets remaining");
return;
}
- if ((notificationTimeMs - mNotificationPulseTime) < mDozeParameters.getPulseDuration()) {
+ final long pulseDuration = mDozeParameters.getPulseDuration(false /*pickup*/);
+ if ((notificationTimeMs - mNotificationPulseTime) < pulseDuration) {
if (DEBUG) Log.d(mTag, "Recently updated, not resetting schedule");
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/egg/LLand.java b/packages/SystemUI/src/com/android/systemui/egg/LLand.java
index cdfe6e5..5de09a3 100644
--- a/packages/SystemUI/src/com/android/systemui/egg/LLand.java
+++ b/packages/SystemUI/src/com/android/systemui/egg/LLand.java
@@ -29,11 +29,15 @@
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
+import android.media.AudioAttributes;
+import android.media.AudioManager;
+import android.os.Vibrator;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import android.util.Slog;
import android.view.View;
import android.view.ViewOutlineProvider;
import android.view.animation.DecelerateInterpolator;
@@ -51,9 +55,9 @@
public static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
public static final boolean DEBUG_DRAW = false; // DEBUG
- public static final void L(String s, Object ... objects) {
+ public static void L(String s, Object ... objects) {
if (DEBUG) {
- Log.d(TAG, String.format(s, objects));
+ Slog.d(TAG, objects.length == 0 ? s : String.format(s, objects));
}
}
@@ -61,17 +65,18 @@
public static final boolean HAVE_STARS = true;
public static final float DEBUG_SPEED_MULTIPLIER = 1f; // 0.1f;
- public static final boolean DEBUG_IDDQD = false;
+ public static final boolean DEBUG_IDDQD = Log.isLoggable(TAG + ".iddqd", Log.DEBUG);
final static int[] POPS = {
- // resid // spinny!
- R.drawable.pop_belt, 0,
- R.drawable.pop_droid, 0,
- R.drawable.pop_pizza, 1,
- R.drawable.pop_stripes, 0,
- R.drawable.pop_swirl, 1,
- R.drawable.pop_vortex, 1,
- R.drawable.pop_vortex2, 1,
+ // resid // spinny! // alpha
+ R.drawable.pop_belt, 0, 255,
+ R.drawable.pop_droid, 0, 255,
+ R.drawable.pop_pizza, 1, 255,
+ R.drawable.pop_stripes, 0, 255,
+ R.drawable.pop_swirl, 1, 255,
+ R.drawable.pop_vortex, 1, 255,
+ R.drawable.pop_vortex2, 1, 255,
+ R.drawable.pop_ball, 0, 190,
};
private static class Params {
@@ -117,10 +122,20 @@
PLAYER_Z = res.getDimensionPixelSize(R.dimen.player_z);
PLAYER_Z_BOOST = res.getDimensionPixelSize(R.dimen.player_z_boost);
HUD_Z = res.getDimensionPixelSize(R.dimen.hud_z);
+
+ // Sanity checking
+ if (OBSTACLE_MIN <= OBSTACLE_WIDTH / 2) {
+ Slog.e(TAG, "error: obstacles might be too short, adjusting");
+ OBSTACLE_MIN = OBSTACLE_WIDTH / 2 + 1;
+ }
}
}
private TimeAnimator mAnim;
+ private Vibrator mVibrator;
+ private AudioManager mAudioManager;
+ private final AudioAttributes mAudioAttrs = new AudioAttributes.Builder()
+ .setUsage(AudioAttributes.USAGE_GAME).build();
private TextView mScoreField;
private View mSplash;
@@ -158,6 +173,8 @@
public LLand(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
+ mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
+ mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
setFocusable(true);
PARAMS = new Params(getResources());
mTimeOfDay = irand(0, SKIES.length);
@@ -198,7 +215,15 @@
final float hsv[] = {0, 0, 0};
- private void reset() {
+ private void thump() {
+ if (mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT) {
+ // No interruptions. Not even game haptics.
+ return;
+ }
+ mVibrator.vibrate(80, mAudioAttrs);
+ }
+
+ public void reset() {
L("reset");
final Drawable sky = new GradientDrawable(
GradientDrawable.Orientation.BOTTOM_TOP,
@@ -313,14 +338,16 @@
private void setScore(int score) {
mScore = score;
- if (mScoreField != null) mScoreField.setText(String.valueOf(score));
+ if (mScoreField != null) {
+ mScoreField.setText(DEBUG_IDDQD ? "??" : String.valueOf(score));
+ }
}
private void addScore(int incr) {
setScore(mScore + incr);
}
- private void start(boolean startPlaying) {
+ public void start(boolean startPlaying) {
L("start(startPlaying=%s)", startPlaying?"true":"false");
if (startPlaying) {
mPlaying = true;
@@ -352,7 +379,7 @@
}
}
- private void stop() {
+ public void stop() {
if (mAnimating) {
mAnim.cancel();
mAnim = null;
@@ -417,8 +444,10 @@
if (mPlaying && mDroid.below(mHeight)) {
if (DEBUG_IDDQD) {
poke();
+ unpoke();
} else {
L("player hit the floor");
+ thump();
stop();
}
}
@@ -429,6 +458,7 @@
final Obstacle ob = mObstaclesInPlay.get(j);
if (mPlaying && ob.intersects(mDroid) && !DEBUG_IDDQD) {
L("player hit an obstacle");
+ thump();
stop();
} else if (ob.cleared(mDroid)) {
if (ob instanceof Stem) passedBarrier = true;
@@ -459,8 +489,9 @@
// 3. Time for more obstacles!
if (mPlaying && (t - mLastPipeTime) > PARAMS.OBSTACLE_PERIOD) {
mLastPipeTime = t;
- final int obstacley = (int) (Math.random()
- * (mHeight - 2*PARAMS.OBSTACLE_MIN - PARAMS.OBSTACLE_GAP)) + PARAMS.OBSTACLE_MIN;
+ final int obstacley =
+ (int)(frand() * (mHeight - 2*PARAMS.OBSTACLE_MIN - PARAMS.OBSTACLE_GAP)) +
+ PARAMS.OBSTACLE_MIN;
final int inset = (PARAMS.OBSTACLE_WIDTH - PARAMS.OBSTACLE_STEM_WIDTH) / 2;
final int yinset = PARAMS.OBSTACLE_WIDTH/2;
@@ -539,7 +570,7 @@
@Override
public boolean onTouchEvent(MotionEvent ev) {
- if (DEBUG) L("touch: %s", ev);
+ L("touch: %s", ev);
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
poke();
@@ -553,7 +584,7 @@
@Override
public boolean onTrackballEvent(MotionEvent ev) {
- if (DEBUG) L("trackball: %s", ev);
+ L("trackball: %s", ev);
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
poke();
@@ -567,7 +598,7 @@
@Override
public boolean onKeyDown(int keyCode, KeyEvent ev) {
- if (DEBUG) L("keyDown: %d", keyCode);
+ L("keyDown: %d", keyCode);
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_DPAD_UP:
@@ -582,7 +613,7 @@
@Override
public boolean onKeyUp(int keyCode, KeyEvent ev) {
- if (DEBUG) L("keyDown: %d", keyCode);
+ L("keyDown: %d", keyCode);
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_DPAD_UP:
@@ -597,7 +628,7 @@
@Override
public boolean onGenericMotionEvent (MotionEvent ev) {
- if (DEBUG) L("generic: %s", ev);
+ L("generic: %s", ev);
return false;
}
@@ -684,6 +715,10 @@
private boolean mBoosting;
+ private final int[] sColors = new int[] {
+ 0xFF78C557,
+ };
+
private final float[] sHull = new float[] {
0.3f, 0f, // left antenna
0.7f, 0f, // right antenna
@@ -692,7 +727,7 @@
0.6f, 1f, // right foot
0.4f, 1f, // left foot BLUE!
0.08f, 0.75f, // sinistram
- 0.08f, 0.33f, // cold shoulder
+ 0.08f, 0.33f, // cold shoulder
};
public final float[] corners = new float[sHull.length];
@@ -701,7 +736,7 @@
setBackgroundResource(R.drawable.android);
getBackground().setTintMode(PorterDuff.Mode.SRC_ATOP);
- getBackground().setTint(0xFF00FF00);
+ getBackground().setTint(sColors[0]);
setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
@@ -822,8 +857,9 @@
int cx, cy, r;
public Pop(Context context, float h) {
super(context, h);
- int idx = 2*irand(0, POPS.length/2);
+ int idx = 3*irand(0, POPS.length/3);
setBackgroundResource(POPS[idx]);
+ setAlpha((float)(POPS[idx+2])/255);
setScaleX(frand() < 0.5f ? -1 : 1);
mRotate = POPS[idx+1] == 0 ? 0 : (frand() < 0.5f ? -1 : 1);
setOutlineProvider(new ViewOutlineProvider() {
diff --git a/packages/SystemUI/src/com/android/systemui/egg/LLandActivity.java b/packages/SystemUI/src/com/android/systemui/egg/LLandActivity.java
index 88fd952..b9f8106 100644
--- a/packages/SystemUI/src/com/android/systemui/egg/LLandActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/egg/LLandActivity.java
@@ -24,13 +24,21 @@
import com.android.systemui.R;
public class LLandActivity extends Activity {
+ LLand mLand;
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.lland);
- LLand world = (LLand) findViewById(R.id.world);
- world.setScoreField((TextView) findViewById(R.id.score));
- world.setSplash(findViewById(R.id.welcome));
- Log.v(LLand.TAG, "focus: " + world.requestFocus());
+ mLand = (LLand) findViewById(R.id.world);
+ mLand.setScoreField((TextView) findViewById(R.id.score));
+ mLand.setSplash(findViewById(R.id.welcome));
+ //Log.v(LLand.TAG, "focus: " + mLand.requestFocus());
+ }
+
+ @Override
+ public void onPause() {
+ mLand.stop();
+ super.onPause();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
index c524edc..6bad652 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
@@ -47,6 +47,10 @@
ViewGroupAdapterBridge.link(this, mAdapter);
}
+ public void refreshAdapter() {
+ mAdapter.refresh();
+ }
+
public static class Adapter extends UserSwitcherController.BaseUserAdapter
implements OnClickListener {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index 29f291d..4f0700e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -19,6 +19,7 @@
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityOptions;
+import android.app.ITaskStackListener;
import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ActivityNotFoundException;
@@ -56,6 +57,7 @@
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
+
/** A proxy implementation for the recents component */
public class AlternateRecentsComponent implements ActivityOptions.OnAnimationStartedListener {
@@ -79,6 +81,28 @@
final static String sRecentsPackage = "com.android.systemui";
final static String sRecentsActivity = "com.android.systemui.recents.RecentsActivity";
+ /**
+ * An implementation of ITaskStackListener, that allows us to listen for changes to the system
+ * task stacks and update recents accordingly.
+ */
+ class TaskStackListenerImpl extends ITaskStackListener.Stub {
+ @Override
+ public void onTaskStackChanged() {
+ RecentsConfiguration config = RecentsConfiguration.getInstance();
+ if (config.svelteLevel == RecentsConfiguration.SVELTE_NONE) {
+ // Load the next task only if we aren't svelte
+ RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+ RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
+ loader.preloadTasks(plan, true /* isTopTaskHome */);
+ RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
+ launchOpts.numVisibleTasks = 1;
+ launchOpts.numVisibleTaskThumbnails = 1;
+ launchOpts.onlyLoadForCache = true;
+ loader.loadTasks(mContext, plan, launchOpts);
+ }
+ }
+ }
+
static RecentsComponent.Callbacks sRecentsComponentCallbacks;
static RecentsTaskLoadPlan sInstanceLoadPlan;
@@ -86,6 +110,7 @@
LayoutInflater mInflater;
SystemServicesProxy mSystemServicesProxy;
Handler mHandler;
+ TaskStackListenerImpl mTaskStackListener;
boolean mBootCompleted;
boolean mStartAnimationTriggered;
boolean mCanReuseTaskStackViews = true;
@@ -116,6 +141,10 @@
mSystemServicesProxy = new SystemServicesProxy(context);
mHandler = new Handler();
mTaskStackBounds = new Rect();
+
+ // Register the task stack listener
+ mTaskStackListener = new TaskStackListenerImpl();
+ mSystemServicesProxy.registerTaskStackListener(mTaskStackListener);
}
public void onStart() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 6dc2edb..a37bc54 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -167,10 +167,6 @@
if (action.equals(Intent.ACTION_SCREEN_OFF)) {
// When the screen turns off, dismiss Recents to Home
dismissRecentsToHome(false);
- // Preload the metadata for all tasks in the background
- RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
- RecentsTaskLoadPlan plan = loader.createLoadPlan(context);
- loader.preloadTasks(plan, true /* isTopTaskHome */);
} else if (action.equals(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED)) {
// When the search activity changes, update the Search widget
refreshSearchWidget();
@@ -437,22 +433,6 @@
onEnterAnimationTriggered();
}
- // Start listening for widget package changes if there is one bound, post it since we don't
- // want it stalling the startup
- if (mConfig.searchBarAppWidgetId >= 0) {
- final WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks> callback =
- new WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks>(this);
- mRecentsView.post(new Runnable() {
- @Override
- public void run() {
- RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks cb = callback.get();
- if (cb != null) {
- mAppWidgetHost.startListening(cb);
- }
- }
- });
- }
-
mStatusBar = ((SystemUIApplication) getApplication())
.getComponent(PhoneStatusBar.class);
}
@@ -539,15 +519,29 @@
unregisterReceiver(mSystemBroadcastReceiver);
// Stop listening for widget package changes if there was one bound
- if (mAppWidgetHost.isListening()) {
- mAppWidgetHost.stopListening();
- }
+ mAppWidgetHost.stopListening();
}
public void onEnterAnimationTriggered() {
// Try and start the enter animation (or restart it on configuration changed)
ReferenceCountedTrigger t = new ReferenceCountedTrigger(this, null, null, null);
- mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(t));
+ ViewAnimation.TaskViewEnterContext ctx = new ViewAnimation.TaskViewEnterContext(t);
+ mRecentsView.startEnterRecentsAnimation(ctx);
+ if (mConfig.searchBarAppWidgetId >= 0) {
+ final WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks> cbRef =
+ new WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks>(
+ RecentsActivity.this);
+ ctx.postAnimationTrigger.addLastDecrementRunnable(new Runnable() {
+ @Override
+ public void run() {
+ // Start listening for widget package changes if there is one bound
+ RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks cb = cbRef.get();
+ if (cb != null) {
+ mAppWidgetHost.startListening(cb);
+ }
+ }
+ });
+ }
// Animate the SystemUI scrim views
mScrimViews.startEnterRecentsAnimation();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java
index a63e167..5bae37a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java
@@ -43,23 +43,23 @@
public void startListening(RecentsAppWidgetHostCallbacks cb) {
mCb = cb;
- mIsListening = true;
- super.startListening();
+ if (!mIsListening) {
+ mIsListening = true;
+ super.startListening();
+ }
}
@Override
public void stopListening() {
- super.stopListening();
+ if (mIsListening) {
+ super.stopListening();
+ }
// Ensure that we release any references to the callbacks
mCb = null;
mContext = null;
mIsListening = false;
}
- public boolean isListening() {
- return mIsListening;
- }
-
@Override
protected void onProviderChanged(int appWidgetId, AppWidgetProviderInfo appWidgetInfo) {
if (mCb == null) return;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 9a4bd08..3fbd5a6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -21,6 +21,7 @@
import android.app.ActivityOptions;
import android.app.AppGlobals;
import android.app.IActivityManager;
+import android.app.ITaskStackListener;
import android.app.SearchManager;
import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetManager;
@@ -536,4 +537,15 @@
e.printStackTrace();
}
}
+
+ /** Registers a task stack listener with the system. */
+ public void registerTaskStackListener(ITaskStackListener listener) {
+ if (mIam == null) return;
+
+ try {
+ mIam.registerTaskStackListener(listener);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 46a5d8d..746a7df 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -204,6 +204,10 @@
/** Requests all task stacks to start their enter-recents animation */
public void startEnterRecentsAnimation(ViewAnimation.TaskViewEnterContext ctx) {
+ // We have to increment/decrement the post animation trigger in case there are no children
+ // to ensure that it runs
+ ctx.postAnimationTrigger.increment();
+
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
@@ -212,6 +216,7 @@
stackView.startEnterRecentsAnimation(ctx);
}
}
+ ctx.postAnimationTrigger.decrement();
}
/** Requests all task stacks to start their exit-recents animation */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/ViewAnimation.java b/packages/SystemUI/src/com/android/systemui/recents/views/ViewAnimation.java
index 4586f12..e1d80fd 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/ViewAnimation.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/ViewAnimation.java
@@ -27,7 +27,7 @@
public static class TaskViewEnterContext {
// A trigger to run some logic when all the animations complete. This works around the fact
// that it is difficult to coordinate ViewPropertyAnimators
- ReferenceCountedTrigger postAnimationTrigger;
+ public ReferenceCountedTrigger postAnimationTrigger;
// An update listener to notify as the enter animation progresses (used for the home transition)
ValueAnimator.AnimatorUpdateListener updateListener;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index 3d4a1e0..6b167b4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -46,9 +46,12 @@
public void dump(PrintWriter pw) {
pw.println(" DozeParameters:");
pw.print(" getDisplayStateSupported(): "); pw.println(getDisplayStateSupported());
- pw.print(" getPulseDuration(): "); pw.println(getPulseDuration());
- pw.print(" getPulseInDuration(): "); pw.println(getPulseInDuration());
- pw.print(" getPulseInDelay(): "); pw.println(getPulseInDelay());
+ pw.print(" getPulseDuration(pickup=false): "); pw.println(getPulseDuration(false));
+ pw.print(" getPulseDuration(pickup=true): "); pw.println(getPulseDuration(true));
+ pw.print(" getPulseInDuration(pickup=false): "); pw.println(getPulseInDuration(false));
+ pw.print(" getPulseInDuration(pickup=true): "); pw.println(getPulseInDuration(true));
+ pw.print(" getPulseInDelay(pickup=false): "); pw.println(getPulseInDelay(false));
+ pw.print(" getPulseInDelay(pickup=true): "); pw.println(getPulseInDelay(true));
pw.print(" getPulseInVisibleDuration(): "); pw.println(getPulseVisibleDuration());
pw.print(" getPulseOutDuration(): "); pw.println(getPulseOutDuration());
pw.print(" getPulseOnSigMotion(): "); pw.println(getPulseOnSigMotion());
@@ -60,22 +63,27 @@
pw.print(" getPulseSchedule(): "); pw.println(getPulseSchedule());
pw.print(" getPulseScheduleResets(): "); pw.println(getPulseScheduleResets());
pw.print(" getPickupVibrationThreshold(): "); pw.println(getPickupVibrationThreshold());
+ pw.print(" getPickupPerformsProxCheck(): "); pw.println(getPickupPerformsProxCheck());
}
public boolean getDisplayStateSupported() {
return getBoolean("doze.display.supported", R.bool.doze_display_state_supported);
}
- public int getPulseDuration() {
- return getPulseInDuration() + getPulseVisibleDuration() + getPulseOutDuration();
+ public int getPulseDuration(boolean pickup) {
+ return getPulseInDuration(pickup) + getPulseVisibleDuration() + getPulseOutDuration();
}
- public int getPulseInDuration() {
- return getInt("doze.pulse.duration.in", R.integer.doze_pulse_duration_in);
+ public int getPulseInDuration(boolean pickup) {
+ return pickup
+ ? getInt("doze.pulse.duration.in.pickup", R.integer.doze_pulse_duration_in_pickup)
+ : getInt("doze.pulse.duration.in", R.integer.doze_pulse_duration_in);
}
- public int getPulseInDelay() {
- return getInt("doze.pulse.delay.in", R.integer.doze_pulse_delay_in);
+ public int getPulseInDelay(boolean pickup) {
+ return pickup
+ ? getInt("doze.pulse.delay.in.pickup", R.integer.doze_pulse_delay_in_pickup)
+ : getInt("doze.pulse.delay.in", R.integer.doze_pulse_delay_in);
}
public int getPulseVisibleDuration() {
@@ -106,6 +114,10 @@
return getBoolean("doze.pulse.proxcheck", R.bool.doze_proximity_check_before_pulse);
}
+ public boolean getPickupPerformsProxCheck() {
+ return getBoolean("doze.pickup.proxcheck", R.bool.doze_pickup_performs_proximity_check);
+ }
+
public boolean getPulseOnNotifications() {
return getBoolean("doze.pulse.notifications", R.bool.doze_pulse_on_notifications);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
index 022e64e..3394a8d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -21,10 +21,8 @@
import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.content.Context;
-import android.graphics.Color;
import android.os.Handler;
import android.util.Log;
-import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
@@ -219,11 +217,14 @@
private final Runnable mPulseIn = new Runnable() {
@Override
public void run() {
- if (DEBUG) Log.d(TAG, "Pulse in, mDozing=" + mDozing);
+ if (DEBUG) Log.d(TAG, "Pulse in, mDozing=" + mDozing + " mPulseReason="
+ + DozeLog.pulseReasonToString(mPulseReason));
if (!mDozing) return;
DozeLog.tracePulseStart(mPulseReason);
- startScrimAnimation(true /* inFront */, 0f, mDozeParameters.getPulseInDuration(),
- mPulseInInterpolator, mDozeParameters.getPulseInDelay(), mPulseInFinished);
+ final boolean pickup = mPulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP;
+ startScrimAnimation(true /* inFront */, 0f, mDozeParameters.getPulseInDuration(pickup),
+ mPulseInInterpolator, mDozeParameters.getPulseInDelay(pickup),
+ mPulseInFinished);
// Signal that the pulse is ready to turn the screen on and draw.
pulseStarted();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index 8ce608c..45a1386 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -122,7 +122,7 @@
tile.userSwitch(newUserId);
}
mSecurity.onUserSwitched(newUserId);
- mNetwork.getAccessPointController().onUserSwitched(newUserId);
+ mNetwork.onUserSwitched(newUserId);
mObserver.register();
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
index 7ee1fc5..1460e5f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
@@ -107,6 +107,7 @@
public void show(boolean animate) {
if (mUserSwitcher != null && mUserSwitcherContainer.getVisibility() != View.VISIBLE) {
cancelAnimations();
+ mAdapter.refresh();
mUserSwitcherContainer.setVisibility(View.VISIBLE);
mStatusBarView.setKeyguardUserSwitcherShowing(true, animate);
if (animate) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 58bf246..bcf08ff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -22,6 +22,7 @@
void addNetworkSignalChangedCallback(NetworkSignalChangedCallback cb);
void removeNetworkSignalChangedCallback(NetworkSignalChangedCallback cb);
void setWifiEnabled(boolean enabled);
+ void onUserSwitched(int newUserId);
AccessPointController getAccessPointController();
MobileDataController getMobileDataController();
@@ -49,7 +50,6 @@
void scanForAccessPoints();
boolean connect(AccessPoint ap);
boolean canConfigWifi();
- void onUserSwitched(int newUserId);
public interface AccessPointCallback {
void onAccessPointsChanged(AccessPoint[] accessPoints);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 5e71047..6431ab5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -16,12 +16,19 @@
package com.android.systemui.statusbar.policy;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
+import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.net.ConnectivityManager;
+import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
@@ -55,6 +62,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.BitSet;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@@ -98,16 +106,19 @@
private final AccessPointControllerImpl mAccessPoints;
private final MobileDataControllerImpl mMobileDataController;
- // bluetooth
+ // Network types that replace the carrier label if the device does not support mobile data.
private boolean mBluetoothTethered = false;
+ private boolean mEthernetConnected = false;
- // data connectivity (regardless of state, can we access the internet?)
- // state of inet connection - 0 not connected, 100 connected
+ // state of inet connection
private boolean mConnected = false;
- private int mConnectedNetworkType = ConnectivityManager.TYPE_NONE;
- private String mConnectedNetworkTypeName;
private boolean mInetCondition; // Used for Logging and demo.
+ // BitSets indicating which network transport types (e.g., TRANSPORT_WIFI, TRANSPORT_MOBILE) are
+ // connected and validated, respectively.
+ private final BitSet mConnectedTransports = new BitSet();
+ private final BitSet mValidatedTransports = new BitSet();
+
// States that don't belong to a subcontroller.
private boolean mAirplaneMode = false;
private boolean mHasNoSims;
@@ -125,6 +136,9 @@
new ArrayList<NetworkSignalChangedCallback>();
private boolean mListening;
+ // The current user ID.
+ private int mCurrentUserId;
+
/**
* Construct this controller object and register for updates.
*/
@@ -344,6 +358,14 @@
}
@Override
+ public void onUserSwitched(int newUserId) {
+ mCurrentUserId = newUserId;
+ mAccessPoints.onUserSwitched(newUserId);
+ updateConnectivity();
+ refreshCarrierLabel();
+ }
+
+ @Override
public void onReceive(Context context, Intent intent) {
if (CHATTY) {
Log.d(TAG, "onReceive: intent=" + intent);
@@ -351,7 +373,7 @@
final String action = intent.getAction();
if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE) ||
action.equals(ConnectivityManager.INET_CONDITION_ACTION)) {
- updateConnectivity(intent);
+ updateConnectivity();
refreshCarrierLabel();
} else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
refreshLocale();
@@ -406,8 +428,9 @@
updateNoSims();
}
- private void updateNoSims() {
- boolean hasNoSims = mPhone.getPhoneCount() != 0 && mMobileSignalControllers.size() == 0;
+ @VisibleForTesting
+ protected void updateNoSims() {
+ boolean hasNoSims = mHasMobileDataFeature && mMobileSignalControllers.size() == 0;
if (hasNoSims != mHasNoSims) {
mHasNoSims = hasNoSims;
notifyListeners();
@@ -498,14 +521,6 @@
}
/**
- * Turns inet condition into a boolean indexing for a specific network.
- * @return 0 for bad connectivity on this network, 1 for good connectivity
- */
- private int inetConditionForNetwork(int networkType, boolean inetCondition) {
- return (inetCondition && mConnectedNetworkType == networkType) ? 1 : 0;
- }
-
- /**
* Forces update of all callbacks on both SignalClusters and
* NetworkSignalChangedCallbacks.
*/
@@ -539,41 +554,37 @@
/**
* Update the Inet conditions and what network we are connected to.
*/
- private void updateConnectivity(Intent intent) {
- final NetworkInfo info = mConnectivityManager.getActiveNetworkInfo();
-
- // Are we connected at all, by any interface?
- mConnected = info != null && info.isConnected();
- if (mConnected) {
- mConnectedNetworkType = info.getType();
- mConnectedNetworkTypeName = info.getTypeName();
- } else {
- mConnectedNetworkType = ConnectivityManager.TYPE_NONE;
- mConnectedNetworkTypeName = null;
+ private void updateConnectivity() {
+ mConnectedTransports.clear();
+ mValidatedTransports.clear();
+ for (NetworkCapabilities nc :
+ mConnectivityManager.getDefaultNetworkCapabilitiesForUser(mCurrentUserId)) {
+ for (int transportType : nc.getTransportTypes()) {
+ mConnectedTransports.set(transportType);
+ if (nc.hasCapability(NET_CAPABILITY_VALIDATED)) {
+ mValidatedTransports.set(transportType);
+ }
+ }
}
- int connectionStatus = intent.getIntExtra(ConnectivityManager.EXTRA_INET_CONDITION, 0);
-
if (CHATTY) {
- Log.d(TAG, "updateConnectivity: networkInfo=" + info);
- Log.d(TAG, "updateConnectivity: connectionStatus=" + connectionStatus);
+ Log.d(TAG, "updateConnectivity: mConnectedTransports=" + mConnectedTransports);
+ Log.d(TAG, "updateConnectivity: mValidatedTransports=" + mValidatedTransports);
}
- mInetCondition = connectionStatus > INET_CONDITION_THRESHOLD;
-
- if (info != null && info.getType() == ConnectivityManager.TYPE_BLUETOOTH) {
- mBluetoothTethered = info.isConnected();
- } else {
- mBluetoothTethered = false;
- }
+ mConnected = !mConnectedTransports.isEmpty();
+ mInetCondition = !mValidatedTransports.isEmpty();
+ mBluetoothTethered = mConnectedTransports.get(TRANSPORT_BLUETOOTH);
+ mEthernetConnected = mConnectedTransports.get(TRANSPORT_ETHERNET);
// We want to update all the icons, all at once, for any condition change
for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
- mobileSignalController.setInetCondition(mInetCondition ? 1 : 0, inetConditionForNetwork(
- mobileSignalController.getNetworkType(), mInetCondition));
+ mobileSignalController.setInetCondition(
+ mInetCondition ? 1 : 0,
+ mValidatedTransports.get(mobileSignalController.getTransportType()) ? 1 : 0);
}
mWifiSignalController.setInetCondition(
- inetConditionForNetwork(mWifiSignalController.getNetworkType(), mInetCondition));
+ mValidatedTransports.get(mWifiSignalController.getTransportType()) ? 1 : 0);
}
/**
@@ -594,9 +605,7 @@
label = mContext.getString(R.string.bluetooth_tethered);
}
- final boolean ethernetConnected =
- (mConnectedNetworkType == ConnectivityManager.TYPE_ETHERNET);
- if (ethernetConnected && !mHasMobileDataFeature) {
+ if (mEthernetConnected && !mHasMobileDataFeature) {
label = context.getString(R.string.ethernet_label);
}
@@ -612,7 +621,7 @@
}
}
} else if (!isMobileDataConnected() && !wifiState.connected && !mBluetoothTethered &&
- !ethernetConnected && !mHasMobileDataFeature) {
+ !mEthernetConnected && !mHasMobileDataFeature) {
// Pretty much no connection.
label = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
}
@@ -633,9 +642,7 @@
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("NetworkController state:");
- pw.println(String.format(" %s network type %d (%s)",
- mConnected ? "CONNECTED" : "DISCONNECTED",
- mConnectedNetworkType, mConnectedNetworkTypeName));
+
pw.println(" - telephony ------");
pw.print(" hasVoiceCallingFeature()=");
pw.println(hasVoiceCallingFeature());
@@ -645,6 +652,10 @@
pw.println(mBluetoothTethered);
pw.println(" - connectivity ------");
+ pw.print(" mConnectedTransports=");
+ pw.println(mConnectedTransports);
+ pw.print(" mValidatedTransports=");
+ pw.println(mValidatedTransports);
pw.print(" mInetCondition=");
pw.println(mInetCondition);
pw.print(" mAirplaneMode=");
@@ -795,8 +806,8 @@
public WifiSignalController(Context context, boolean hasMobileData,
List<NetworkSignalChangedCallback> signalCallbacks,
List<SignalCluster> signalClusters, NetworkControllerImpl networkController) {
- super("WifiSignalController", context, ConnectivityManager.TYPE_WIFI, signalCallbacks,
- signalClusters, networkController);
+ super("WifiSignalController", context, NetworkCapabilities.TRANSPORT_WIFI,
+ signalCallbacks, signalClusters, networkController);
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
mHasMobileData = hasMobileData;
Handler handler = new WifiHandler();
@@ -989,7 +1000,7 @@
List<SignalCluster> signalClusters, NetworkControllerImpl networkController,
SubscriptionInfo info) {
super("MobileSignalController(" + info.getSubscriptionId() + ")", context,
- ConnectivityManager.TYPE_MOBILE, signalCallbacks, signalClusters,
+ NetworkCapabilities.TRANSPORT_CELLULAR, signalCallbacks, signalClusters,
networkController);
mConfig = config;
mPhone = phone;
@@ -1460,7 +1471,7 @@
protected final String mTag;
protected final T mCurrentState;
protected final T mLastState;
- protected final int mNetworkType;
+ protected final int mTransportType;
protected final Context mContext;
// The owner of the SignalController (i.e. NetworkController will maintain the following
// lists and call notifyListeners whenever the list has changed to ensure everyone
@@ -1479,7 +1490,7 @@
List<SignalCluster> signalClusters, NetworkControllerImpl networkController) {
mTag = TAG + "." + tag;
mNetworkController = networkController;
- mNetworkType = type;
+ mTransportType = type;
mContext = context;
mSignalsChangedCallbacks = signalCallbacks;
mSignalClusters = signalClusters;
@@ -1497,8 +1508,8 @@
return mCurrentState;
}
- public int getNetworkType() {
- return mNetworkType;
+ public int getTransportType() {
+ return mTransportType;
}
public void setInetCondition(int inetCondition) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index e5b357a..4ac41a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -417,18 +417,6 @@
}
}
- public int getSwitchableUsers() {
- int result = 0;
- ArrayList<UserRecord> users = mController.mUsers;
- int N = users.size();
- for (int i = 0; i < N; i++) {
- if (users.get(i).info != null) {
- result++;
- }
- }
- return result;
- }
-
public Drawable getDrawable(Context context, UserRecord item) {
if (item.isAddUser) {
return context.getDrawable(R.drawable.ic_add_circle_qs);
@@ -436,6 +424,10 @@
return UserIcons.getDefaultUserIcon(item.isGuest ? UserHandle.USER_NULL : item.info.id,
/* light= */ true);
}
+
+ public void refresh() {
+ mController.refreshUsers(UserHandle.USER_NULL);
+ }
}
public static final class UserRecord {
@@ -500,6 +492,7 @@
} else {
v = (UserDetailView) convertView;
}
+ v.refreshAdapter();
return v;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index eaf2f78..020bc00 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -195,6 +195,18 @@
mPhoneStateListener.onDataActivity(dataActivity);
}
+ protected void verifyHasNoSims(boolean hasNoSimsVisible) {
+ ArgumentCaptor<Boolean> hasNoSimsArg = ArgumentCaptor.forClass(Boolean.class);
+
+ Mockito.verify(mSignalCluster, Mockito.atLeastOnce()).setNoSims(hasNoSimsArg.capture());
+ assertEquals("No sims in status bar", hasNoSimsVisible, (boolean) hasNoSimsArg.getValue());
+
+ Mockito.verify(mNetworkSignalChangedCallback, Mockito.atLeastOnce())
+ .onNoSimVisibleChanged(hasNoSimsArg.capture());
+ assertEquals("No sims in quick settings", hasNoSimsVisible,
+ (boolean) hasNoSimsArg.getValue());
+ }
+
protected void verifyLastQsMobileDataIndicators(boolean visible, int icon, int typeIcon,
boolean dataIn, boolean dataOut) {
ArgumentCaptor<Integer> iconArg = ArgumentCaptor.forClass(Integer.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index b5d97d9..33eb4d6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -25,6 +25,30 @@
verifyLastMobileDataIndicators(false, 0, 0);
}
+ public void testNoSimsIconPresent() {
+ // No Subscriptions.
+ mNetworkController.mMobileSignalControllers.clear();
+ mNetworkController.updateNoSims();
+
+ verifyHasNoSims(true);
+ }
+
+ public void testNoSimlessIconWithoutMobile() {
+ // Turn off mobile network support.
+ Mockito.when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
+ // Create a new NetworkController as this is currently handled in constructor.
+ mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
+ mConfig, mock(AccessPointControllerImpl.class),
+ mock(MobileDataControllerImpl.class));
+ setupNetworkController();
+
+ // No Subscriptions.
+ mNetworkController.mMobileSignalControllers.clear();
+ mNetworkController.updateNoSims();
+
+ verifyHasNoSims(false);
+ }
+
public void testSignalStrength() {
for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 11c6edd0..c3500e2 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -4049,12 +4049,12 @@
mAppsToBeHidden.remove(appToken);
mAppsThatDismissKeyguard.remove(appToken);
if (mAppsToBeHidden.isEmpty()) {
- if (mKeyguardSecureIncludingHidden) {
+ if (dismissKeyguard && !mKeyguardSecure) {
+ mAppsThatDismissKeyguard.add(appToken);
+ } else {
mWinShowWhenLocked = win;
mHideLockScreen = true;
mForceStatusBarFromKeyguard = false;
- } else if (dismissKeyguard && !mKeyguardSecure) {
- mAppsThatDismissKeyguard.add(appToken);
}
}
} else if (dismissKeyguard) {
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index c3465d1..42a5195 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -29,6 +29,7 @@
import java.util.List;
import java.util.Map;
+import android.app.ActivityManager;
import android.app.ActivityThread;
import android.app.AppOpsManager;
import android.content.Context;
@@ -53,7 +54,6 @@
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
-import android.util.SparseIntArray;
import android.util.TimeUtils;
import android.util.Xml;
@@ -78,10 +78,12 @@
final Handler mHandler;
boolean mWriteScheduled;
+ boolean mFastWriteScheduled;
final Runnable mWriteRunner = new Runnable() {
public void run() {
synchronized (AppOpsService.this) {
mWriteScheduled = false;
+ mFastWriteScheduled = false;
AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
@Override protected Void doInBackground(Void... params) {
writeState();
@@ -237,7 +239,7 @@
}
}
if (changed) {
- scheduleWriteLocked();
+ scheduleFastWriteLocked();
}
}
}
@@ -250,7 +252,7 @@
if (pkgs.size() <= 0) {
mUidOps.remove(uid);
}
- scheduleWriteLocked();
+ scheduleFastWriteLocked();
}
}
}
@@ -260,7 +262,7 @@
synchronized (this) {
if (mUidOps.indexOfKey(uid) >= 0) {
mUidOps.remove(uid);
- scheduleWriteLocked();
+ scheduleFastWriteLocked();
}
}
}
@@ -400,7 +402,7 @@
// if there is nothing else interesting in it.
pruneOp(op, uid, packageName);
}
- scheduleWriteNowLocked();
+ scheduleFastWriteLocked();
}
}
}
@@ -436,16 +438,20 @@
}
@Override
- public void resetAllModes() {
- int callingUid = Binder.getCallingUid();
+ public void resetAllModes(int reqUserId, String reqPackageName) {
+ final int callingPid = Binder.getCallingPid();
+ final int callingUid = Binder.getCallingUid();
mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS,
- Binder.getCallingPid(), callingUid, null);
+ callingPid, callingUid, null);
+ reqUserId = ActivityManager.handleIncomingUser(callingPid, callingUid, reqUserId,
+ true, true, "resetAllModes", null);
HashMap<Callback, ArrayList<Pair<String, Integer>>> callbacks = null;
synchronized (this) {
boolean changed = false;
for (int i=mUidOps.size()-1; i>=0; i--) {
HashMap<String, Ops> packages = mUidOps.valueAt(i);
- if (UserHandle.getUserId(callingUid) != UserHandle.getUserId(mUidOps.keyAt(i))) {
+ if (reqUserId != UserHandle.USER_ALL
+ && reqUserId != UserHandle.getUserId(mUidOps.keyAt(i))) {
// Skip any ops for a different user
continue;
}
@@ -453,6 +459,10 @@
while (it.hasNext()) {
Map.Entry<String, Ops> ent = it.next();
String packageName = ent.getKey();
+ if (reqPackageName != null && !reqPackageName.equals(packageName)) {
+ // Skip any ops for a different package
+ continue;
+ }
Ops pkgOps = ent.getValue();
for (int j=pkgOps.size()-1; j>=0; j--) {
Op curOp = pkgOps.valueAt(j);
@@ -478,7 +488,7 @@
}
}
if (changed) {
- scheduleWriteNowLocked();
+ scheduleFastWriteLocked();
}
}
if (callbacks != null) {
@@ -837,12 +847,13 @@
}
}
- private void scheduleWriteNowLocked() {
- if (!mWriteScheduled) {
+ private void scheduleFastWriteLocked() {
+ if (!mFastWriteScheduled) {
mWriteScheduled = true;
+ mFastWriteScheduled = true;
+ mHandler.removeCallbacks(mWriteRunner);
+ mHandler.postDelayed(mWriteRunner, 10*1000);
}
- mHandler.removeCallbacks(mWriteRunner);
- mHandler.post(mWriteRunner);
}
private Op getOpLocked(int code, int uid, String packageName, boolean edit) {
@@ -1236,12 +1247,11 @@
pw.print(" ago");
}
if (op.duration == -1) {
- pw.println(" (running)");
- } else {
- pw.print("; duration=");
- TimeUtils.formatDuration(op.duration, pw);
- pw.println();
+ pw.print(" (running)");
+ } else if (op.duration != 0) {
+ pw.print("; duration="); TimeUtils.formatDuration(op.duration, pw);
}
+ pw.println();
}
}
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 5eec0b7..c5af085 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1065,6 +1065,72 @@
return result.toArray(new Network[result.size()]);
}
+ private NetworkCapabilities getNetworkCapabilitiesAndValidation(NetworkAgentInfo nai) {
+ if (nai != null) {
+ synchronized (nai) {
+ if (nai.created) {
+ NetworkCapabilities nc = new NetworkCapabilities(nai.networkCapabilities);
+ if (nai.validated) {
+ nc.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
+ } else {
+ nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
+ }
+ return nc;
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId) {
+ // The basic principle is: if an app's traffic could possibly go over a
+ // network, without the app doing anything multinetwork-specific,
+ // (hence, by "default"), then include that network's capabilities in
+ // the array.
+ //
+ // In the normal case, app traffic only goes over the system's default
+ // network connection, so that's the only network returned.
+ //
+ // With a VPN in force, some app traffic may go into the VPN, and thus
+ // over whatever underlying networks the VPN specifies, while other app
+ // traffic may go over the system default network (e.g.: a split-tunnel
+ // VPN, or an app disallowed by the VPN), so the set of networks
+ // returned includes the VPN's underlying networks and the system
+ // default.
+ enforceAccessPermission();
+
+ HashMap<Network, NetworkCapabilities> result = new HashMap<Network, NetworkCapabilities>();
+
+ NetworkAgentInfo nai = getDefaultNetwork();
+ NetworkCapabilities nc = getNetworkCapabilitiesAndValidation(getDefaultNetwork());
+ if (nc != null) {
+ result.put(nai.network, nc);
+ }
+
+ if (!mLockdownEnabled) {
+ synchronized (mVpns) {
+ Vpn vpn = mVpns.get(userId);
+ if (vpn != null) {
+ Network[] networks = vpn.getUnderlyingNetworks();
+ if (networks != null) {
+ for (Network network : networks) {
+ nai = getNetworkAgentInfoForNetwork(network);
+ nc = getNetworkCapabilitiesAndValidation(nai);
+ if (nc != null) {
+ result.put(nai.network, nc);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ NetworkCapabilities[] out = new NetworkCapabilities[result.size()];
+ out = result.values().toArray(out);
+ return out;
+ }
+
@Override
public boolean isNetworkSupported(int networkType) {
enforceAccessPermission();
@@ -3544,8 +3610,12 @@
// Note: if mDefaultRequest is changed, NetworkMonitor needs to be updated.
private final NetworkRequest mDefaultRequest;
+ private NetworkAgentInfo getDefaultNetwork() {
+ return mNetworkForRequestId.get(mDefaultRequest.requestId);
+ }
+
private boolean isDefaultNetwork(NetworkAgentInfo nai) {
- return mNetworkForRequestId.get(mDefaultRequest.requestId) == nai;
+ return nai == getDefaultNetwork();
}
public void registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 7e17043..6823119 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -37,6 +37,7 @@
import android.app.IActivityContainer;
import android.app.IActivityContainerCallback;
import android.app.IAppTask;
+import android.app.ITaskStackListener;
import android.app.ProfilerInfo;
import android.app.admin.DevicePolicyManager;
import android.app.usage.UsageEvents;
@@ -292,7 +293,7 @@
static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
// Maximum number recent bitmaps to keep in memory.
- static final int MAX_RECENT_BITMAPS = 5;
+ static final int MAX_RECENT_BITMAPS = 3;
// Amount of time after a call to stopAppSwitches() during which we will
// prevent further untrusted switches from happening.
@@ -370,6 +371,9 @@
static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
+ // Delay in notifying task stack change listeners (in millis)
+ static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
+
/** All system services */
SystemServiceManager mSystemServiceManager;
@@ -378,6 +382,10 @@
/** Run all ActivityStacks through this */
ActivityStackSupervisor mStackSupervisor;
+ /** Task stack change listeners. */
+ private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
+ new RemoteCallbackList<ITaskStackListener>();
+
public IntentFirewall mIntentFirewall;
// Whether we should show our dialogs (ANR, crash, etc) or just perform their
@@ -1219,6 +1227,7 @@
static final int START_USER_SWITCH_MSG = 46;
static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
static final int DISMISS_DIALOG_MSG = 48;
+ static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1738,6 +1747,22 @@
d.dismiss();
break;
}
+ case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
+ synchronized (ActivityManagerService.this) {
+ int i = mTaskStackListeners.beginBroadcast();
+ while (i > 0) {
+ i--;
+ try {
+ // Make a one-way callback to the listener
+ mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
+ } catch (RemoteException e){
+ // Handled by the RemoteCallbackList
+ }
+ }
+ mTaskStackListeners.finishBroadcast();
+ }
+ break;
+ }
}
}
};
@@ -2332,6 +2357,16 @@
}
}
+ /** Sets the task stack listener that gets callbacks when a task stack changes. */
+ @Override
+ public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
+ synchronized (ActivityManagerService.this) {
+ if (listener != null) {
+ mTaskStackListeners.register(listener);
+ }
+ }
+ }
+
@Override
public void notifyActivityDrawn(IBinder token) {
if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
@@ -3643,12 +3678,12 @@
if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
+ " when finishing user" + userId);
mRecentTasks.remove(i);
- tr.removedFromRecents(mTaskPersister);
+ tr.removedFromRecents();
}
}
// Remove tasks from persistent storage.
- mTaskPersister.wakeup(null, true);
+ notifyTaskPersisterLocked(null, true);
}
// Sort by taskId
@@ -3660,7 +3695,7 @@
};
// Extract the affiliates of the chain containing mRecentTasks[start].
- private int processNextAffiliateChain(int start) {
+ private int processNextAffiliateChainLocked(int start) {
final TaskRecord startTask = mRecentTasks.get(start);
final int affiliateId = startTask.mAffiliatedTaskId;
@@ -3695,7 +3730,7 @@
if (first.mNextAffiliate != null) {
Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
first.setNextAffiliate(null);
- mTaskPersister.wakeup(first, false);
+ notifyTaskPersisterLocked(first, false);
}
// Everything in the middle is doubly linked from next to prev.
final int tmpSize = mTmpRecents.size();
@@ -3706,13 +3741,13 @@
Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
" setting prev=" + prev);
next.setPrevAffiliate(prev);
- mTaskPersister.wakeup(next, false);
+ notifyTaskPersisterLocked(next, false);
}
if (prev.mNextAffiliate != next) {
Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
" setting next=" + next);
prev.setNextAffiliate(next);
- mTaskPersister.wakeup(prev, false);
+ notifyTaskPersisterLocked(prev, false);
}
prev.inRecents = true;
}
@@ -3721,7 +3756,7 @@
if (last.mPrevAffiliate != null) {
Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
last.setPrevAffiliate(null);
- mTaskPersister.wakeup(last, false);
+ notifyTaskPersisterLocked(last, false);
}
// Insert the group back into mRecentTasks at start.
@@ -3762,7 +3797,7 @@
if (task.autoRemoveRecents && task.getTopActivity() == null) {
// This situation is broken, and we should just get rid of it now.
mRecentTasks.remove(i);
- task.removedFromRecents(mTaskPersister);
+ task.removedFromRecents();
i--;
N--;
Slog.w(TAG, "Removing auto-remove without activity: " + task);
@@ -3807,7 +3842,7 @@
if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
// Doesn't exist any more! Good-bye.
mRecentTasks.remove(i);
- task.removedFromRecents(mTaskPersister);
+ task.removedFromRecents();
i--;
N--;
Slog.w(TAG, "Removing no longer valid recent: " + task);
@@ -3843,7 +3878,7 @@
}
// Verify the affiliate chain for each task.
- for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
+ for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
}
mTmpRecents.clear();
@@ -4009,12 +4044,12 @@
}
if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
- trimRecentsForTask(task, true);
+ trimRecentsForTaskLocked(task, true);
N = mRecentTasks.size();
while (N >= ActivityManager.getMaxRecentTasksStatic()) {
final TaskRecord tr = mRecentTasks.remove(N - 1);
- tr.removedFromRecents(mTaskPersister);
+ tr.removedFromRecents();
N--;
}
task.inRecents = true;
@@ -4079,7 +4114,7 @@
* If needed, remove oldest existing entries in recents that are for the same kind
* of task as the given one.
*/
- int trimRecentsForTask(TaskRecord task, boolean doTrim) {
+ int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
int N = mRecentTasks.size();
final Intent intent = task.intent;
final boolean document = intent != null && intent.isDocument();
@@ -4126,7 +4161,7 @@
tr.disposeThumbnail();
mRecentTasks.remove(i);
if (task != tr) {
- tr.removedFromRecents(mTaskPersister);
+ tr.removedFromRecents();
}
i--;
N--;
@@ -7989,10 +8024,6 @@
return list;
}
- TaskRecord getMostRecentTask() {
- return mRecentTasks.get(0);
- }
-
/**
* Creates a new RecentTaskInfo from a TaskRecord.
*/
@@ -8221,7 +8252,7 @@
TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
intent, description);
- int trimIdx = trimRecentsForTask(task, false);
+ int trimIdx = trimRecentsForTaskLocked(task, false);
if (trimIdx >= 0) {
// If this would have caused a trim, then we'll abort because that
// means it would be added at the end of the list but then just removed.
@@ -8231,7 +8262,7 @@
final int N = mRecentTasks.size();
if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
final TaskRecord tr = mRecentTasks.remove(N - 1);
- tr.removedFromRecents(mTaskPersister);
+ tr.removedFromRecents();
}
task.inRecents = true;
@@ -8291,7 +8322,7 @@
private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
mRecentTasks.remove(tr);
- tr.removedFromRecents(mTaskPersister);
+ tr.removedFromRecents();
ComponentName component = tr.getBaseIntent().getComponent();
if (component == null) {
Slog.w(TAG, "No component for base intent of task: " + tr);
@@ -9979,6 +10010,7 @@
}
}
+ /** Pokes the task persister. */
void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
if (task != null && task.stack != null && task.stack.isHomeStack()) {
// Never persist the home stack.
@@ -9987,6 +10019,13 @@
mTaskPersister.wakeup(task, flush);
}
+ /** Notifies all listeners when the task stack has changed. */
+ void notifyTaskStackChangedLocked() {
+ mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
+ Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
+ mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
+ }
+
@Override
public boolean shutdown(int timeout) {
if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
@@ -10010,12 +10049,12 @@
mBatteryStatsService.shutdown();
synchronized (this) {
mProcessStats.shutdownLocked();
+ notifyTaskPersisterLocked(null, true);
}
- notifyTaskPersisterLocked(null, true);
return timedout;
}
-
+
public final void activitySlept(IBinder token) {
if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index c12cadb..e37d5f3 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -69,7 +69,7 @@
final class ActivityRecord {
static final String TAG = ActivityManagerService.TAG;
static final boolean DEBUG_SAVED_STATE = ActivityStackSupervisor.DEBUG_SAVED_STATE;
- final public static String RECENTS_PACKAGE_NAME = "com.android.systemui.recent";
+ final public static String RECENTS_PACKAGE_NAME = "com.android.systemui.recents";
private static final String TAG_ACTIVITY = "activity";
private static final String ATTR_ID = "id";
@@ -792,7 +792,7 @@
}
}
- void updateThumbnail(Bitmap newThumbnail, CharSequence description) {
+ void updateThumbnailLocked(Bitmap newThumbnail, CharSequence description) {
if (newThumbnail != null) {
if (ActivityManagerService.DEBUG_THUMBNAILS) Slog.i(ActivityManagerService.TAG,
"Setting thumbnail of " + this + " to " + newThumbnail);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index ea694ada..ad86aea 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -65,7 +65,6 @@
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
-import android.content.res.Resources;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Binder;
@@ -838,7 +837,7 @@
clearLaunchTime(prev);
final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
if (mService.mHasRecents && (next == null || next.noDisplay || next.task != prev.task || uiSleeping)) {
- prev.updateThumbnail(screenshotActivities(prev), null);
+ prev.updateThumbnailLocked(screenshotActivities(prev), null);
}
stopFullyDrawnTraceIfNeeded();
@@ -950,7 +949,7 @@
r.icicle = icicle;
r.haveState = true;
r.launchCount = 0;
- r.updateThumbnail(null, description);
+ r.updateThumbnailLocked(null, description);
}
if (!r.stopped) {
if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r + " (stop complete)");
@@ -1060,6 +1059,9 @@
}
prev.cpuTimeAtResume = 0; // reset it
}
+
+ // Notfiy when the task stack has changed
+ mService.notifyTaskStackChangedLocked();
}
/**
@@ -4105,7 +4107,7 @@
// Task creator asked to remove this when done, or this task was a voice
// interaction, so it should not remain on the recent tasks list.
mService.mRecentTasks.remove(task);
- task.removedFromRecents(mService.mTaskPersister);
+ task.removedFromRecents();
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 38809cb..d9396d8 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2871,6 +2871,7 @@
final TaskRecord task = r.task;
task.setLastThumbnail(task.stack.screenshotActivities(r));
mService.addRecentTaskLocked(task);
+ mService.notifyTaskStackChangedLocked();
mWindowManager.setAppVisibility(r.appToken, false);
}
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index ee93233..d726685 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -383,12 +383,12 @@
setNextAffiliate(null);
}
- void removedFromRecents(TaskPersister persister) {
+ void removedFromRecents() {
disposeThumbnail();
closeRecentsChain();
if (inRecents) {
inRecents = false;
- persister.wakeup(this, false);
+ mService.notifyTaskPersisterLocked(this, false);
}
}
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index 225097f..39718ea 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -215,6 +215,8 @@
// Default to 5s reevaluation delay.
private static final int DEFAULT_REEVALUATE_DELAY_MS = 5000;
private static final int MAX_RETRIES = 10;
+ // Between groups of MAX_RETRIES evaluation attempts, pause 10 mins in hopes ISP outage passes.
+ private static final int REEVALUATE_PAUSE_MS = 10*60*1000;
private final int mReevaluateDelayMs;
private int mReevaluateToken = 0;
private static final int INVALID_UID = -1;
@@ -345,6 +347,7 @@
public void enter() {
mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED,
NETWORK_TEST_RESULT_INVALID, 0, mNetworkAgentInfo));
+ if (!mUserDoesNotWant) sendMessageDelayed(CMD_FORCE_REEVALUATION, REEVALUATE_PAUSE_MS);
}
@Override
@@ -360,6 +363,15 @@
return NOT_HANDLED;
}
}
+
+ @Override
+ public void exit() {
+ // NOTE: This removes the delayed message posted by enter() but will inadvertently
+ // remove any other CMD_FORCE_REEVALUATION in the message queue. At the moment this
+ // is harmless. If in the future this becomes problematic a different message could
+ // be used.
+ removeMessages(CMD_FORCE_REEVALUATION);
+ }
}
// Being in the ValidatedState State indicates a Network is:
diff --git a/services/core/java/com/android/server/hdmi/PowerStatusMonitorAction.java b/services/core/java/com/android/server/hdmi/PowerStatusMonitorAction.java
index 1e29fd6..fd7a7f9 100644
--- a/services/core/java/com/android/server/hdmi/PowerStatusMonitorAction.java
+++ b/services/core/java/com/android/server/hdmi/PowerStatusMonitorAction.java
@@ -64,10 +64,11 @@
@Override
boolean processCommand(HdmiCecMessage cmd) {
- if (mState != STATE_WAIT_FOR_REPORT_POWER_STATUS) {
- return false;
+ if (mState == STATE_WAIT_FOR_REPORT_POWER_STATUS
+ && cmd.getOpcode() == Constants.MESSAGE_REPORT_POWER_STATUS) {
+ return handleReportPowerStatus(cmd);
}
- return handleReportPowerStatus(cmd);
+ return false;
}
private boolean handleReportPowerStatus(HdmiCecMessage cmd) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 57a89679..6f1e851 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4539,26 +4539,35 @@
try {
IMountService ms = PackageHelper.getMountService();
if (ms != null) {
- final long interval = android.provider.Settings.Global.getLong(
- mContext.getContentResolver(),
- android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
- DEFAULT_MANDATORY_FSTRIM_INTERVAL);
- if (interval > 0) {
- final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance();
- if (timeSinceLast > interval) {
- Slog.w(TAG, "No disk maintenance in " + timeSinceLast
- + "; running immediately");
- if (!isFirstBoot()) {
- try {
- ActivityManagerNative.getDefault().showBootMessage(
- mContext.getResources().getString(
- R.string.android_upgrading_fstrim), true);
- } catch (RemoteException e) {
- }
+ final boolean isUpgrade = isUpgrade();
+ boolean doTrim = isUpgrade;
+ if (doTrim) {
+ Slog.w(TAG, "Running disk maintenance immediately due to system update");
+ } else {
+ final long interval = android.provider.Settings.Global.getLong(
+ mContext.getContentResolver(),
+ android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
+ DEFAULT_MANDATORY_FSTRIM_INTERVAL);
+ if (interval > 0) {
+ final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance();
+ if (timeSinceLast > interval) {
+ doTrim = true;
+ Slog.w(TAG, "No disk maintenance in " + timeSinceLast
+ + "; running immediately");
}
- ms.runMaintenance();
}
}
+ if (doTrim) {
+ if (!isFirstBoot()) {
+ try {
+ ActivityManagerNative.getDefault().showBootMessage(
+ mContext.getResources().getString(
+ R.string.android_upgrading_fstrim), true);
+ } catch (RemoteException e) {
+ }
+ }
+ ms.runMaintenance();
+ }
} else {
Slog.e(TAG, "Mount service unavailable!");
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index f144fb2..5f05d9a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -9764,7 +9764,7 @@
w.mContentChanged = false;
// Moved from updateWindowsAndWallpaperLocked().
- if (w.mHasSurface) {
+ if (w.mHasSurface && !w.isHiddenFromUserLocked()) {
// Take care of the window being ready to display.
final boolean committed =
winAnimator.commitFinishDrawingLocked(currentTime);
diff --git a/telecomm/java/android/telecom/AudioState.java b/telecomm/java/android/telecom/AudioState.java
index bd63e00..3271ebf 100644
--- a/telecomm/java/android/telecom/AudioState.java
+++ b/telecomm/java/android/telecom/AudioState.java
@@ -91,7 +91,7 @@
@Override
public String toString() {
return String.format(Locale.US,
- "[AudioState isMuted: %b, route; %s, supportedRouteMask: %s]",
+ "[AudioState isMuted: %b, route: %s, supportedRouteMask: %s]",
isMuted,
audioRouteToString(route),
audioRouteToString(supportedRouteMask));
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 04274c7..f3b0586 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -838,6 +838,11 @@
return mConnectionCapabilities;
}
+ /** @hide */
+ @SystemApi @Deprecated public final int getCallCapabilities() {
+ return getConnectionCapabilities();
+ }
+
/**
* Sets the value of the {@link #getAddress()} property.
*
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 8c2a4eb..559a58c 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -167,10 +167,40 @@
private int mVoiceRegState = STATE_OUT_OF_SERVICE;
private int mDataRegState = STATE_OUT_OF_SERVICE;
- private boolean mRoaming;
- private String mOperatorAlphaLong;
- private String mOperatorAlphaShort;
- private String mOperatorNumeric;
+
+ /**
+ * Roaming type
+ * HOME : in home network
+ * @hide
+ */
+ public static final int ROAMING_TYPE_NOT_ROAMING = 0;
+ /**
+ * Roaming type
+ * UNKNOWN : in a roaming network, but we can not tell if it's domestic or international
+ * @hide
+ */
+ public static final int ROAMING_TYPE_UNKNOWN = 1;
+ /**
+ * Roaming type
+ * DOMESTIC : in domestic roaming network
+ * @hide
+ */
+ public static final int ROAMING_TYPE_DOMESTIC = 2;
+ /**
+ * Roaming type
+ * INTERNATIONAL : in international roaming network
+ * @hide
+ */
+ public static final int ROAMING_TYPE_INTERNATIONAL = 3;
+
+ private int mVoiceRoamingType;
+ private int mDataRoamingType;
+ private String mVoiceOperatorAlphaLong;
+ private String mVoiceOperatorAlphaShort;
+ private String mVoiceOperatorNumeric;
+ private String mDataOperatorAlphaLong;
+ private String mDataOperatorAlphaShort;
+ private String mDataOperatorNumeric;
private boolean mIsManualNetworkSelection;
private boolean mIsEmergencyOnly;
@@ -187,6 +217,29 @@
private int mCdmaEriIconMode;
/**
+ * get String description of roaming type
+ * @hide
+ */
+ public static final String getRoamingLogString(int roamingType) {
+ switch (roamingType) {
+ case ROAMING_TYPE_NOT_ROAMING:
+ return "home";
+
+ case ROAMING_TYPE_UNKNOWN:
+ return "roaming";
+
+ case ROAMING_TYPE_DOMESTIC:
+ return "Domestic Roaming";
+
+ case ROAMING_TYPE_INTERNATIONAL:
+ return "International Roaming";
+
+ default:
+ return "UNKNOWN";
+ }
+ }
+
+ /**
* Create a new ServiceState from a intent notifier Bundle
*
* This method is used by PhoneStateIntentReceiver and maybe by
@@ -221,10 +274,14 @@
protected void copyFrom(ServiceState s) {
mVoiceRegState = s.mVoiceRegState;
mDataRegState = s.mDataRegState;
- mRoaming = s.mRoaming;
- mOperatorAlphaLong = s.mOperatorAlphaLong;
- mOperatorAlphaShort = s.mOperatorAlphaShort;
- mOperatorNumeric = s.mOperatorNumeric;
+ mVoiceRoamingType = s.mVoiceRoamingType;
+ mDataRoamingType = s.mDataRoamingType;
+ mVoiceOperatorAlphaLong = s.mVoiceOperatorAlphaLong;
+ mVoiceOperatorAlphaShort = s.mVoiceOperatorAlphaShort;
+ mVoiceOperatorNumeric = s.mVoiceOperatorNumeric;
+ mDataOperatorAlphaLong = s.mDataOperatorAlphaLong;
+ mDataOperatorAlphaShort = s.mDataOperatorAlphaShort;
+ mDataOperatorNumeric = s.mDataOperatorNumeric;
mIsManualNetworkSelection = s.mIsManualNetworkSelection;
mRilVoiceRadioTechnology = s.mRilVoiceRadioTechnology;
mRilDataRadioTechnology = s.mRilDataRadioTechnology;
@@ -244,10 +301,14 @@
public ServiceState(Parcel in) {
mVoiceRegState = in.readInt();
mDataRegState = in.readInt();
- mRoaming = in.readInt() != 0;
- mOperatorAlphaLong = in.readString();
- mOperatorAlphaShort = in.readString();
- mOperatorNumeric = in.readString();
+ mVoiceRoamingType = in.readInt();
+ mDataRoamingType = in.readInt();
+ mVoiceOperatorAlphaLong = in.readString();
+ mVoiceOperatorAlphaShort = in.readString();
+ mVoiceOperatorNumeric = in.readString();
+ mDataOperatorAlphaLong = in.readString();
+ mDataOperatorAlphaShort = in.readString();
+ mDataOperatorNumeric = in.readString();
mIsManualNetworkSelection = in.readInt() != 0;
mRilVoiceRadioTechnology = in.readInt();
mRilDataRadioTechnology = in.readInt();
@@ -264,10 +325,14 @@
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mVoiceRegState);
out.writeInt(mDataRegState);
- out.writeInt(mRoaming ? 1 : 0);
- out.writeString(mOperatorAlphaLong);
- out.writeString(mOperatorAlphaShort);
- out.writeString(mOperatorNumeric);
+ out.writeInt(mVoiceRoamingType);
+ out.writeInt(mDataRoamingType);
+ out.writeString(mVoiceOperatorAlphaLong);
+ out.writeString(mVoiceOperatorAlphaShort);
+ out.writeString(mVoiceOperatorNumeric);
+ out.writeString(mDataOperatorAlphaLong);
+ out.writeString(mDataOperatorAlphaShort);
+ out.writeString(mDataOperatorNumeric);
out.writeInt(mIsManualNetworkSelection ? 1 : 0);
out.writeInt(mRilVoiceRadioTechnology);
out.writeInt(mRilDataRadioTechnology);
@@ -337,10 +402,45 @@
*
* @return true if TS 27.007 7.2 roaming is true
* and ONS is different from SPN
- *
*/
public boolean getRoaming() {
- return mRoaming;
+ return getVoiceRoaming() || getDataRoaming();
+ }
+
+ /**
+ * Get current voice network roaming status
+ * @return roaming status
+ * @hide
+ */
+ public boolean getVoiceRoaming() {
+ return mVoiceRoamingType != ROAMING_TYPE_NOT_ROAMING;
+ }
+
+ /**
+ * Get current voice network roaming type
+ * @return roaming type
+ * @hide
+ */
+ public int getVoiceRoamingType() {
+ return mVoiceRoamingType;
+ }
+
+ /**
+ * Get current data network roaming type
+ * @return roaming type
+ * @hide
+ */
+ public boolean getDataRoaming() {
+ return mDataRoamingType != ROAMING_TYPE_NOT_ROAMING;
+ }
+
+ /**
+ * Get current data network roaming type
+ * @return roaming type
+ * @hide
+ */
+ public int getDataRoamingType() {
+ return mDataRoamingType;
}
/**
@@ -387,7 +487,25 @@
* @return long name of operator, null if unregistered or unknown
*/
public String getOperatorAlphaLong() {
- return mOperatorAlphaLong;
+ return mVoiceOperatorAlphaLong;
+ }
+
+ /**
+ * Get current registered voice network operator name in long alphanumeric format.
+ * @return long name of operator
+ * @hide
+ */
+ public String getVoiceOperatorAlphaLong() {
+ return mVoiceOperatorAlphaLong;
+ }
+
+ /**
+ * Get current registered data network operator name in long alphanumeric format.
+ * @return long name of voice operator
+ * @hide
+ */
+ public String getDataOperatorAlphaLong() {
+ return mDataOperatorAlphaLong;
}
/**
@@ -398,7 +516,25 @@
* @return short name of operator, null if unregistered or unknown
*/
public String getOperatorAlphaShort() {
- return mOperatorAlphaShort;
+ return mVoiceOperatorAlphaShort;
+ }
+
+ /**
+ * Get current registered voice network operator name in short alphanumeric format.
+ * @return short name of operator, null if unregistered or unknown
+ * @hide
+ */
+ public String getVoiceOperatorAlphaShort() {
+ return mVoiceOperatorAlphaShort;
+ }
+
+ /**
+ * Get current registered data network operator name in short alphanumeric format.
+ * @return short name of operator, null if unregistered or unknown
+ * @hide
+ */
+ public String getDataOperatorAlphaShort() {
+ return mDataOperatorAlphaShort;
}
/**
@@ -414,7 +550,25 @@
* {@link com.android.internal.telephony.MccTable#countryCodeForMcc(int)}.
*/
public String getOperatorNumeric() {
- return mOperatorNumeric;
+ return mVoiceOperatorNumeric;
+ }
+
+ /**
+ * Get current registered voice network operator numeric id.
+ * @return numeric format of operator, null if unregistered or unknown
+ * @hide
+ */
+ public String getVoiceOperatorNumeric() {
+ return mVoiceOperatorNumeric;
+ }
+
+ /**
+ * Get current registered data network operator numeric id.
+ * @return numeric format of operator, null if unregistered or unknown
+ * @hide
+ */
+ public String getDataOperatorNumeric() {
+ return mDataOperatorNumeric;
}
/**
@@ -430,11 +584,15 @@
public int hashCode() {
return ((mVoiceRegState * 31)
+ (mDataRegState * 37)
- + (mRoaming ? 1 : 0)
+ + mVoiceRoamingType
+ + mDataRoamingType
+ (mIsManualNetworkSelection ? 1 : 0)
- + ((null == mOperatorAlphaLong) ? 0 : mOperatorAlphaLong.hashCode())
- + ((null == mOperatorAlphaShort) ? 0 : mOperatorAlphaShort.hashCode())
- + ((null == mOperatorNumeric) ? 0 : mOperatorNumeric.hashCode())
+ + ((null == mVoiceOperatorAlphaLong) ? 0 : mVoiceOperatorAlphaLong.hashCode())
+ + ((null == mVoiceOperatorAlphaShort) ? 0 : mVoiceOperatorAlphaShort.hashCode())
+ + ((null == mVoiceOperatorNumeric) ? 0 : mVoiceOperatorNumeric.hashCode())
+ + ((null == mDataOperatorAlphaLong) ? 0 : mDataOperatorAlphaLong.hashCode())
+ + ((null == mDataOperatorAlphaShort) ? 0 : mDataOperatorAlphaShort.hashCode())
+ + ((null == mDataOperatorNumeric) ? 0 : mDataOperatorNumeric.hashCode())
+ mCdmaRoamingIndicator
+ mCdmaDefaultRoamingIndicator
+ (mIsEmergencyOnly ? 1 : 0));
@@ -456,11 +614,15 @@
return (mVoiceRegState == s.mVoiceRegState
&& mDataRegState == s.mDataRegState
- && mRoaming == s.mRoaming
&& mIsManualNetworkSelection == s.mIsManualNetworkSelection
- && equalsHandlesNulls(mOperatorAlphaLong, s.mOperatorAlphaLong)
- && equalsHandlesNulls(mOperatorAlphaShort, s.mOperatorAlphaShort)
- && equalsHandlesNulls(mOperatorNumeric, s.mOperatorNumeric)
+ && mVoiceRoamingType == s.mVoiceRoamingType
+ && mDataRoamingType == s.mDataRoamingType
+ && equalsHandlesNulls(mVoiceOperatorAlphaLong, s.mVoiceOperatorAlphaLong)
+ && equalsHandlesNulls(mVoiceOperatorAlphaShort, s.mVoiceOperatorAlphaShort)
+ && equalsHandlesNulls(mVoiceOperatorNumeric, s.mVoiceOperatorNumeric)
+ && equalsHandlesNulls(mDataOperatorAlphaLong, s.mDataOperatorAlphaLong)
+ && equalsHandlesNulls(mDataOperatorAlphaShort, s.mDataOperatorAlphaShort)
+ && equalsHandlesNulls(mDataOperatorNumeric, s.mDataOperatorNumeric)
&& equalsHandlesNulls(mRilVoiceRadioTechnology, s.mRilVoiceRadioTechnology)
&& equalsHandlesNulls(mRilDataRadioTechnology, s.mRilDataRadioTechnology)
&& equalsHandlesNulls(mCssIndicator, s.mCssIndicator)
@@ -548,10 +710,17 @@
String radioTechnology = rilRadioTechnologyToString(mRilVoiceRadioTechnology);
String dataRadioTechnology = rilRadioTechnologyToString(mRilDataRadioTechnology);
- return (mVoiceRegState + " " + mDataRegState + " " + (mRoaming ? "roaming" : "home")
- + " " + mOperatorAlphaLong
- + " " + mOperatorAlphaShort
- + " " + mOperatorNumeric
+ return (mVoiceRegState + " " + mDataRegState
+ + " "
+ + "voice " + getRoamingLogString(mVoiceRoamingType)
+ + " "
+ + "data " + getRoamingLogString(mDataRoamingType)
+ + " " + mVoiceOperatorAlphaLong
+ + " " + mVoiceOperatorAlphaShort
+ + " " + mVoiceOperatorNumeric
+ + " " + mDataOperatorAlphaLong
+ + " " + mDataOperatorAlphaShort
+ + " " + mDataOperatorNumeric
+ " " + (mIsManualNetworkSelection ? "(manual)" : "")
+ " " + radioTechnology
+ " " + dataRadioTechnology
@@ -567,10 +736,14 @@
if (DBG) Rlog.d(LOG_TAG, "[ServiceState] setNullState=" + state);
mVoiceRegState = state;
mDataRegState = state;
- mRoaming = false;
- mOperatorAlphaLong = null;
- mOperatorAlphaShort = null;
- mOperatorNumeric = null;
+ mVoiceRoamingType = ROAMING_TYPE_NOT_ROAMING;
+ mDataRoamingType = ROAMING_TYPE_NOT_ROAMING;
+ mVoiceOperatorAlphaLong = null;
+ mVoiceOperatorAlphaShort = null;
+ mVoiceOperatorNumeric = null;
+ mDataOperatorAlphaLong = null;
+ mDataOperatorAlphaShort = null;
+ mDataOperatorNumeric = null;
mIsManualNetworkSelection = false;
mRilVoiceRadioTechnology = 0;
mRilDataRadioTechnology = 0;
@@ -610,9 +783,29 @@
}
public void setRoaming(boolean roaming) {
- mRoaming = roaming;
+ mVoiceRoamingType = (roaming ? ROAMING_TYPE_UNKNOWN : ROAMING_TYPE_NOT_ROAMING);
+ mDataRoamingType = mVoiceRoamingType;
}
+ /** @hide */
+ public void setVoiceRoaming(boolean roaming) {
+ mVoiceRoamingType = (roaming ? ROAMING_TYPE_UNKNOWN : ROAMING_TYPE_NOT_ROAMING);
+ }
+
+ /** @hide */
+ public void setVoiceRoamingType(int type) {
+ mVoiceRoamingType = type;
+ }
+
+ /** @hide */
+ public void setDataRoaming(boolean dataRoaming) {
+ mDataRoamingType = (dataRoaming ? ROAMING_TYPE_UNKNOWN : ROAMING_TYPE_NOT_ROAMING);
+ }
+
+ /** @hide */
+ public void setDataRoamingType(int type) {
+ mDataRoamingType = type;
+ }
/**
* @hide
@@ -650,9 +843,26 @@
}
public void setOperatorName(String longName, String shortName, String numeric) {
- mOperatorAlphaLong = longName;
- mOperatorAlphaShort = shortName;
- mOperatorNumeric = numeric;
+ mVoiceOperatorAlphaLong = longName;
+ mVoiceOperatorAlphaShort = shortName;
+ mVoiceOperatorNumeric = numeric;
+ mDataOperatorAlphaLong = longName;
+ mDataOperatorAlphaShort = shortName;
+ mDataOperatorNumeric = numeric;
+ }
+
+ /** @hide */
+ public void setVoiceOperatorName(String longName, String shortName, String numeric) {
+ mVoiceOperatorAlphaLong = longName;
+ mVoiceOperatorAlphaShort = shortName;
+ mVoiceOperatorNumeric = numeric;
+ }
+
+ /** @hide */
+ public void setDataOperatorName(String longName, String shortName, String numeric) {
+ mDataOperatorAlphaLong = longName;
+ mDataOperatorAlphaShort = shortName;
+ mDataOperatorNumeric = numeric;
}
/**
@@ -662,7 +872,18 @@
* @hide
*/
public void setOperatorAlphaLong(String longName) {
- mOperatorAlphaLong = longName;
+ mVoiceOperatorAlphaLong = longName;
+ mDataOperatorAlphaLong = longName;
+ }
+
+ /** @hide */
+ public void setVoiceOperatorAlphaLong(String longName) {
+ mVoiceOperatorAlphaLong = longName;
+ }
+
+ /** @hide */
+ public void setDataOperatorAlphaLong(String longName) {
+ mDataOperatorAlphaLong = longName;
}
public void setIsManualSelection(boolean isManual) {
@@ -689,10 +910,14 @@
private void setFromNotifierBundle(Bundle m) {
mVoiceRegState = m.getInt("voiceRegState");
mDataRegState = m.getInt("dataRegState");
- mRoaming = m.getBoolean("roaming");
- mOperatorAlphaLong = m.getString("operator-alpha-long");
- mOperatorAlphaShort = m.getString("operator-alpha-short");
- mOperatorNumeric = m.getString("operator-numeric");
+ mVoiceRoamingType = m.getInt("voiceRoamingType");
+ mDataRoamingType = m.getInt("dataRoamingType");
+ mVoiceOperatorAlphaLong = m.getString("operator-alpha-long");
+ mVoiceOperatorAlphaShort = m.getString("operator-alpha-short");
+ mVoiceOperatorNumeric = m.getString("operator-numeric");
+ mDataOperatorAlphaLong = m.getString("data-operator-alpha-long");
+ mDataOperatorAlphaShort = m.getString("data-operator-alpha-short");
+ mDataOperatorNumeric = m.getString("data-operator-numeric");
mIsManualNetworkSelection = m.getBoolean("manual");
mRilVoiceRadioTechnology = m.getInt("radioTechnology");
mRilDataRadioTechnology = m.getInt("dataRadioTechnology");
@@ -713,10 +938,14 @@
public void fillInNotifierBundle(Bundle m) {
m.putInt("voiceRegState", mVoiceRegState);
m.putInt("dataRegState", mDataRegState);
- m.putBoolean("roaming", Boolean.valueOf(mRoaming));
- m.putString("operator-alpha-long", mOperatorAlphaLong);
- m.putString("operator-alpha-short", mOperatorAlphaShort);
- m.putString("operator-numeric", mOperatorNumeric);
+ m.putInt("voiceRoamingType", mVoiceRoamingType);
+ m.putInt("dataRoamingType", mDataRoamingType);
+ m.putString("operator-alpha-long", mVoiceOperatorAlphaLong);
+ m.putString("operator-alpha-short", mVoiceOperatorAlphaShort);
+ m.putString("operator-numeric", mVoiceOperatorNumeric);
+ m.putString("data-operator-alpha-long", mDataOperatorAlphaLong);
+ m.putString("data-operator-alpha-short", mDataOperatorAlphaShort);
+ m.putString("data-operator-numeric", mDataOperatorNumeric);
m.putBoolean("manual", Boolean.valueOf(mIsManualNetworkSelection));
m.putInt("radioTechnology", mRilVoiceRadioTechnology);
m.putInt("dataRadioTechnology", mRilDataRadioTechnology);
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index bfd0531..e3a0200 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -2985,23 +2985,26 @@
writeProguardForLayouts(ProguardKeepSet* keep, const sp<AaptAssets>& assets)
{
status_t err;
+ const char* kClass = "class";
+ const char* kFragment = "fragment";
const String8 kTransition("transition");
const String8 kTransitionPrefix("transition-");
// tag:attribute pairs that should be checked in layout files.
KeyedVector<String8, Vector<NamespaceAttributePair> > kLayoutTagAttrPairs;
- addTagAttrPair(&kLayoutTagAttrPairs, "view", NULL, "class");
- addTagAttrPair(&kLayoutTagAttrPairs, "fragment", NULL, "class");
- addTagAttrPair(&kLayoutTagAttrPairs, "fragment", RESOURCES_ANDROID_NAMESPACE, "name");
+ addTagAttrPair(&kLayoutTagAttrPairs, "view", NULL, kClass);
+ addTagAttrPair(&kLayoutTagAttrPairs, kFragment, NULL, kClass);
+ addTagAttrPair(&kLayoutTagAttrPairs, kFragment, RESOURCES_ANDROID_NAMESPACE, "name");
// tag:attribute pairs that should be checked in xml files.
KeyedVector<String8, Vector<NamespaceAttributePair> > kXmlTagAttrPairs;
- addTagAttrPair(&kXmlTagAttrPairs, "PreferenceScreen", RESOURCES_ANDROID_NAMESPACE, "fragment");
- addTagAttrPair(&kXmlTagAttrPairs, "header", RESOURCES_ANDROID_NAMESPACE, "fragment");
+ addTagAttrPair(&kXmlTagAttrPairs, "PreferenceScreen", RESOURCES_ANDROID_NAMESPACE, kFragment);
+ addTagAttrPair(&kXmlTagAttrPairs, "header", RESOURCES_ANDROID_NAMESPACE, kFragment);
// tag:attribute pairs that should be checked in transition files.
KeyedVector<String8, Vector<NamespaceAttributePair> > kTransitionTagAttrPairs;
- addTagAttrPair(&kTransitionTagAttrPairs, kTransition.string(), NULL, "class");
+ addTagAttrPair(&kTransitionTagAttrPairs, kTransition.string(), NULL, kClass);
+ addTagAttrPair(&kTransitionTagAttrPairs, "pathMotion", NULL, kClass);
const Vector<sp<AaptDir> >& dirs = assets->resDirs();
const size_t K = dirs.size();