summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt4
-rw-r--r--api/system-current.txt4
-rw-r--r--cmds/app_process/app_main.cpp3
-rw-r--r--core/java/android/app/ActivityThread.java3
-rw-r--r--core/java/android/app/AssistContent.java26
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java18
-rw-r--r--core/java/android/content/pm/PackageParser.java21
-rw-r--r--core/java/android/hardware/camera2/CameraCharacteristics.java25
-rw-r--r--core/java/android/hardware/camera2/CaptureResult.java18
-rw-r--r--core/java/android/net/ConnectivityManager.java52
-rw-r--r--core/java/android/net/IConnectivityManager.aidl6
-rw-r--r--core/java/android/net/Network.java3
-rw-r--r--core/java/android/net/NetworkInfo.java23
-rw-r--r--core/java/android/net/TrafficStats.java2
-rw-r--r--core/java/android/os/UserManager.java12
-rw-r--r--core/java/android/provider/Settings.java7
-rw-r--r--core/java/android/text/format/Formatter.java64
-rw-r--r--core/java/android/transition/Visibility.java2
-rw-r--r--core/java/android/view/ViewGroup.java6
-rw-r--r--core/java/android/widget/Editor.java14
-rw-r--r--core/java/android/widget/Toolbar.java74
-rw-r--r--core/java/com/android/internal/app/ToolbarActionBar.java4
-rw-r--r--core/java/com/android/internal/os/RuntimeInit.java6
-rw-r--r--core/java/com/android/internal/os/Zygote.java12
-rw-r--r--core/java/com/android/internal/os/ZygoteConnection.java4
-rw-r--r--core/java/com/android/internal/view/FloatingActionMode.java95
-rw-r--r--core/java/com/android/internal/widget/FloatingToolbar.java99
-rw-r--r--core/java/com/android/server/backup/AccountSyncSettingsBackupHelper.java104
-rw-r--r--core/jni/android_hardware_camera2_DngCreator.cpp85
-rw-r--r--core/jni/android_media_AudioSystem.cpp66
-rw-r--r--core/jni/android_util_Log.cpp26
-rw-r--r--core/res/res/values-sw600dp/dimens.xml2
-rwxr-xr-xcore/res/res/values/config.xml8
-rw-r--r--core/res/res/values/strings.xml6
-rwxr-xr-xcore/res/res/values/symbols.xml5
-rw-r--r--core/tests/coretests/src/android/net/NetworkTest.java50
-rw-r--r--docs/html/index.jd4
-rw-r--r--docs/html/jd_collections.js3
-rw-r--r--docs/html/preview/index.jd6
-rw-r--r--docs/html/training/tv/discovery/searchable.jd3
-rw-r--r--graphics/java/android/graphics/drawable/BitmapDrawable.java6
-rw-r--r--graphics/java/android/graphics/drawable/Drawable.java9
-rw-r--r--graphics/java/android/graphics/drawable/NinePatchDrawable.java6
-rw-r--r--keystore/java/android/security/keystore/KeyGenParameterSpec.java78
-rw-r--r--keystore/java/android/security/keystore/KeyInfo.java14
-rw-r--r--keystore/java/android/security/keystore/KeyProtection.java29
-rw-r--r--keystore/java/android/security/keystore/Utils.java32
-rw-r--r--libs/hwui/RenderNode.cpp8
-rw-r--r--media/java/android/media/AudioDeviceInfo.java3
-rw-r--r--media/java/android/media/AudioDevicePort.java4
-rw-r--r--media/java/android/media/AudioMixPort.java5
-rw-r--r--media/java/android/media/AudioPort.java13
-rw-r--r--packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java21
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java3
-rw-r--r--packages/Shell/src/com/android/shell/BugreportReceiver.java122
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java12
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java81
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java43
-rw-r--r--services/core/java/com/android/server/content/SyncManager.java7
-rw-r--r--services/core/java/com/android/server/content/SyncStorageEngine.java76
-rw-r--r--services/core/java/com/android/server/fingerprint/FingerprintService.java22
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java10
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java34
-rw-r--r--services/core/java/com/android/server/notification/ValidateNotificationPeople.java20
-rw-r--r--services/core/java/com/android/server/pm/KeySetManagerService.java118
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java33
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java2
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java1
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java80
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java109
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java24
-rw-r--r--telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl42
-rw-r--r--wifi/java/android/net/wifi/WifiConfiguration.java20
74 files changed, 1272 insertions, 797 deletions
diff --git a/api/current.txt b/api/current.txt
index e6bbdbe..2094c7c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4019,10 +4019,12 @@ package android.app {
ctor public AssistContent();
method public android.content.ClipData getClipData();
method public android.os.Bundle getExtras();
+ method public java.lang.String getStructuredData();
method public android.net.Uri getWebUri();
method public boolean isAppProvidedIntent();
method public void setClipData(android.content.ClipData);
method public void setIntent(android.content.Intent);
+ method public void setStructuredData(java.lang.String);
method public void setWebUri(android.net.Uri);
}
@@ -23674,6 +23676,7 @@ package android.os {
field public static final java.lang.String DISALLOW_CROSS_PROFILE_COPY_PASTE = "no_cross_profile_copy_paste";
field public static final java.lang.String DISALLOW_DEBUGGING_FEATURES = "no_debugging_features";
field public static final java.lang.String DISALLOW_FACTORY_RESET = "no_factory_reset";
+ field public static final java.lang.String DISALLOW_FUN = "no_fun";
field public static final java.lang.String DISALLOW_INSTALL_APPS = "no_install_apps";
field public static final java.lang.String DISALLOW_INSTALL_UNKNOWN_SOURCES = "no_install_unknown_sources";
field public static final java.lang.String DISALLOW_MODIFY_ACCOUNTS = "no_modify_accounts";
@@ -26561,7 +26564,6 @@ package android.provider {
field public static final java.lang.String DEBUG_APP = "debug_app";
field public static final java.lang.String DEVELOPMENT_SETTINGS_ENABLED = "development_settings_enabled";
field public static final java.lang.String DEVICE_PROVISIONED = "device_provisioned";
- field public static final java.lang.String HIDE_CARRIER_NETWORK_SETTINGS = "hide_carrier_network_settings";
field public static final java.lang.String HTTP_PROXY = "http_proxy";
field public static final deprecated java.lang.String INSTALL_NON_MARKET_APPS = "install_non_market_apps";
field public static final java.lang.String MODE_RINGER = "mode_ringer";
diff --git a/api/system-current.txt b/api/system-current.txt
index fb3c874..9386c50 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4114,10 +4114,12 @@ package android.app {
ctor public AssistContent();
method public android.content.ClipData getClipData();
method public android.os.Bundle getExtras();
+ method public java.lang.String getStructuredData();
method public android.net.Uri getWebUri();
method public boolean isAppProvidedIntent();
method public void setClipData(android.content.ClipData);
method public void setIntent(android.content.Intent);
+ method public void setStructuredData(java.lang.String);
method public void setWebUri(android.net.Uri);
}
@@ -25608,6 +25610,7 @@ package android.os {
field public static final java.lang.String DISALLOW_CROSS_PROFILE_COPY_PASTE = "no_cross_profile_copy_paste";
field public static final java.lang.String DISALLOW_DEBUGGING_FEATURES = "no_debugging_features";
field public static final java.lang.String DISALLOW_FACTORY_RESET = "no_factory_reset";
+ field public static final java.lang.String DISALLOW_FUN = "no_fun";
field public static final java.lang.String DISALLOW_INSTALL_APPS = "no_install_apps";
field public static final java.lang.String DISALLOW_INSTALL_UNKNOWN_SOURCES = "no_install_unknown_sources";
field public static final java.lang.String DISALLOW_MODIFY_ACCOUNTS = "no_modify_accounts";
@@ -28597,7 +28600,6 @@ package android.provider {
field public static final java.lang.String DEBUG_APP = "debug_app";
field public static final java.lang.String DEVELOPMENT_SETTINGS_ENABLED = "development_settings_enabled";
field public static final java.lang.String DEVICE_PROVISIONED = "device_provisioned";
- field public static final java.lang.String HIDE_CARRIER_NETWORK_SETTINGS = "hide_carrier_network_settings";
field public static final java.lang.String HTTP_PROXY = "http_proxy";
field public static final deprecated java.lang.String INSTALL_NON_MARKET_APPS = "install_non_market_apps";
field public static final java.lang.String MODE_RINGER = "mode_ringer";
diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp
index c5af992..449a4ab 100644
--- a/cmds/app_process/app_main.cpp
+++ b/cmds/app_process/app_main.cpp
@@ -90,9 +90,6 @@ public:
virtual void onZygoteInit()
{
- // Re-enable tracing now that we're no longer in Zygote.
- atrace_set_tracing_enabled(true);
-
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index e21c04a..828dc0a 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -5375,6 +5375,7 @@ public final class ActivityThread {
}
public static void main(String[] args) {
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
SamplingProfilerIntegration.start();
// CloseGuard defaults to true and can be quite spammy. We
@@ -5409,6 +5410,8 @@ public final class ActivityThread {
LogPrinter(Log.DEBUG, "ActivityThread"));
}
+ // End of event ActivityThreadMain.
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
diff --git a/core/java/android/app/AssistContent.java b/core/java/android/app/AssistContent.java
index 0df9ce5..ad2ba39 100644
--- a/core/java/android/app/AssistContent.java
+++ b/core/java/android/app/AssistContent.java
@@ -33,6 +33,7 @@ import android.os.Parcelable;
public class AssistContent {
private boolean mIsAppProvidedIntent = false;
private Intent mIntent;
+ private String mStructuredData;
private ClipData mClipData;
private Uri mUri;
private final Bundle mExtras;
@@ -125,6 +126,22 @@ public class AssistContent {
}
/**
+ * Sets optional structured data regarding the content being viewed. The provided data
+ * must be a string represented with <a href="http://json-ld.org/">JSON-LD</a> using the
+ * <a href="http://schema.org/">schema.org</a> vocabulary.
+ */
+ public void setStructuredData(String structuredData) {
+ mStructuredData = structuredData;
+ }
+
+ /**
+ * Returns the current {@link #setStructuredData}.
+ */
+ public String getStructuredData() {
+ return mStructuredData;
+ }
+
+ /**
* Set a web URI associated with the current data being shown to the user.
* This URI could be opened in a web browser, or in the app as an
* {@link Intent#ACTION_VIEW} Intent, to show the same data that is currently
@@ -163,6 +180,9 @@ public class AssistContent {
if (in.readInt() != 0) {
mUri = Uri.CREATOR.createFromParcel(in);
}
+ if (in.readInt() != 0) {
+ mStructuredData = in.readString();
+ }
mIsAppProvidedIntent = in.readInt() == 1;
mExtras = in.readBundle();
}
@@ -187,6 +207,12 @@ public class AssistContent {
} else {
dest.writeInt(0);
}
+ if (mStructuredData != null) {
+ dest.writeInt(1);
+ dest.writeString(mStructuredData);
+ } else {
+ dest.writeInt(0);
+ }
dest.writeInt(mIsAppProvidedIntent ? 1 : 0);
dest.writeBundle(mExtras);
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 9f49154..ed20086 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -403,8 +403,9 @@ public class DevicePolicyManager {
= "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER";
/**
- * A String extra holding the URL-safe base64 encoded SHA-1 checksum of the file at download
- * location specified in {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION}.
+ * A String extra holding the URL-safe base64 encoded SHA-256 or SHA-1 hash (see notes below) of
+ * the file at download location specified in
+ * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION}.
*
* <p>Either this extra or {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM} should be
* present. The provided checksum should match the checksum of the file at the download
@@ -413,12 +414,17 @@ public class DevicePolicyManager {
*
* <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
* provisioning via an NFC bump.
+ *
+ * <p><strong>Note:</strong> for devices running {@link android.os.Build.VERSION_CODES#LOLLIPOP}
+ * and {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} only SHA-1 hash is supported.
+ * Starting from {@link android.os.Build.VERSION_CODES#MNC}, this parameter accepts SHA-256 in
+ * addition to SHA-1. Support for SHA-1 is likely to be removed in future OS releases.
*/
public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM
= "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM";
/**
- * A String extra holding the URL-safe base64 encoded SHA-1 checksum of any signature of the
+ * A String extra holding the URL-safe base64 encoded SHA-256 checksum of any signature of the
* android package archive at the download location specified in {@link
* #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION}.
*
@@ -510,7 +516,7 @@ public class DevicePolicyManager {
= "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER";
/**
- * A String extra holding the URL-safe base64 encoded SHA-1 checksum of the file at download
+ * A String extra holding the URL-safe base64 encoded SHA-256 checksum of the file at download
* location specified in
* {@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION}.
*
@@ -526,7 +532,7 @@ public class DevicePolicyManager {
= "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM";
/**
- * A String extra holding the URL-safe base64 encoded SHA-1 checksum of any signature of the
+ * A String extra holding the URL-safe base64 encoded SHA-256 checksum of any signature of the
* android package archive at the download location specified in {@link
* #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION}.
*
@@ -924,7 +930,7 @@ public class DevicePolicyManager {
/**
* Constant for {@link #setPasswordQuality}: the policy requires some kind
- * of password, but doesn't care what it is. Note that quality constants
+ * of password or pattern, but doesn't care what it is. Note that quality constants
* are ordered so that higher values are more restrictive.
*/
public static final int PASSWORD_QUALITY_SOMETHING = 0x10000;
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index c92c256..287e0c5 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -4024,7 +4024,7 @@ public class PackageParser {
public static final PublicKey parsePublicKey(final String encodedPublicKey) {
if (encodedPublicKey == null) {
- Slog.i(TAG, "Could not parse null public key");
+ Slog.w(TAG, "Could not parse null public key");
return null;
}
@@ -4033,7 +4033,7 @@ public class PackageParser {
final byte[] encoded = Base64.decode(encodedPublicKey, Base64.DEFAULT);
keySpec = new X509EncodedKeySpec(encoded);
} catch (IllegalArgumentException e) {
- Slog.i(TAG, "Could not parse verifier public key; invalid Base64");
+ Slog.w(TAG, "Could not parse verifier public key; invalid Base64");
return null;
}
@@ -4042,23 +4042,32 @@ public class PackageParser {
final KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(keySpec);
} catch (NoSuchAlgorithmException e) {
- Log.wtf(TAG, "Could not parse public key because RSA isn't included in build");
- return null;
+ Slog.wtf(TAG, "Could not parse public key: RSA KeyFactory not included in build");
} catch (InvalidKeySpecException e) {
// Not a RSA public key.
}
+ /* Now try it as a ECDSA key. */
+ try {
+ final KeyFactory keyFactory = KeyFactory.getInstance("EC");
+ return keyFactory.generatePublic(keySpec);
+ } catch (NoSuchAlgorithmException e) {
+ Slog.wtf(TAG, "Could not parse public key: EC KeyFactory not included in build");
+ } catch (InvalidKeySpecException e) {
+ // Not a ECDSA public key.
+ }
+
/* Now try it as a DSA key. */
try {
final KeyFactory keyFactory = KeyFactory.getInstance("DSA");
return keyFactory.generatePublic(keySpec);
} catch (NoSuchAlgorithmException e) {
- Log.wtf(TAG, "Could not parse public key because DSA isn't included in build");
- return null;
+ Slog.wtf(TAG, "Could not parse public key: DSA KeyFactory not included in build");
} catch (InvalidKeySpecException e) {
// Not a DSA public key.
}
+ /* Not a supported key type */
return null;
}
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 152bc22..27d14b3 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -1093,14 +1093,28 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* <p>so <code>[x_s, y_s]</code> is the pixel coordinates of the world
* point, <code>z_s = 1</code>, and <code>w_s</code> is a measurement of disparity
* (depth) in pixel coordinates.</p>
+ * <p>Note that the coordinate system for this transform is the
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} system,
+ * where <code>(0,0)</code> is the top-left of the
+ * preCorrectionActiveArraySize rectangle. Once the pose and
+ * intrinsic calibration transforms have been applied to a
+ * world point, then the android.lens.radialDistortion
+ * transform needs to be applied, and the result adjusted to
+ * be in the {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} coordinate
+ * system (where <code>(0, 0)</code> is the top-left of the
+ * activeArraySize rectangle), to determine the final pixel
+ * coordinate of the world point for processed (non-RAW)
+ * output buffers.</p>
* <p><b>Units</b>:
- * Pixels in the {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} coordinate
- * system.</p>
+ * Pixels in the
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}
+ * coordinate system.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*
* @see CameraCharacteristics#LENS_POSE_ROTATION
* @see CameraCharacteristics#LENS_POSE_TRANSLATION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
*/
@PublicKey
public static final Key<float[]> LENS_INTRINSIC_CALIBRATION =
@@ -2006,19 +2020,19 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}:</p>
* <ol>
* <li>Choose a pixel (x', y') within the active array region of the raw buffer given in
- * android.sensor.info.preCorrectedActiveArraySize, otherwise this pixel is considered
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}, otherwise this pixel is considered
* to be outside of the FOV, and will not be shown in the processed output image.</li>
* <li>Apply geometric distortion correction to get the post-distortion pixel coordinate,
* (x_i, y_i). When applying geometric correction metadata, note that metadata for raw
* buffers is defined relative to the top, left of the
- * android.sensor.info.preCorrectedActiveArraySize rectangle.</li>
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} rectangle.</li>
* <li>If the resulting corrected pixel coordinate is within the region given in
* {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, then the position of this pixel in the
* processed output image buffer is <code>(x_i - activeArray.left, y_i - activeArray.top)</code>,
* when the top, left coordinate of that buffer is treated as (0, 0).</li>
* </ol>
* <p>Thus, for pixel x',y' = (25, 25) on a sensor where {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}
- * is (100,100), android.sensor.info.preCorrectedActiveArraySize is (10, 10, 100, 100),
+ * is (100,100), {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} is (10, 10, 100, 100),
* {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} is (20, 20, 80, 80), and the geometric distortion
* correction doesn't change the pixel coordinate, the resulting pixel selected in
* pixel coordinates would be x,y = (25, 25) relative to the top,left of the raw buffer
@@ -2042,6 +2056,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
*
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
* @see CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
*/
@PublicKey
public static final Key<android.graphics.Rect> SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE =
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 479583c..da216aa 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -2655,14 +2655,28 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* <p>so <code>[x_s, y_s]</code> is the pixel coordinates of the world
* point, <code>z_s = 1</code>, and <code>w_s</code> is a measurement of disparity
* (depth) in pixel coordinates.</p>
+ * <p>Note that the coordinate system for this transform is the
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} system,
+ * where <code>(0,0)</code> is the top-left of the
+ * preCorrectionActiveArraySize rectangle. Once the pose and
+ * intrinsic calibration transforms have been applied to a
+ * world point, then the android.lens.radialDistortion
+ * transform needs to be applied, and the result adjusted to
+ * be in the {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} coordinate
+ * system (where <code>(0, 0)</code> is the top-left of the
+ * activeArraySize rectangle), to determine the final pixel
+ * coordinate of the world point for processed (non-RAW)
+ * output buffers.</p>
* <p><b>Units</b>:
- * Pixels in the {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} coordinate
- * system.</p>
+ * Pixels in the
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}
+ * coordinate system.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*
* @see CameraCharacteristics#LENS_POSE_ROTATION
* @see CameraCharacteristics#LENS_POSE_TRANSLATION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
*/
@PublicKey
public static final Key<float[]> LENS_INTRINSIC_CALIBRATION =
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 3a3c47d..a2ca41c 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -801,28 +801,6 @@ public class ConnectivityManager {
}
/**
- * 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
- * network traffic. This may return {@code null} when there is no default
- * network.
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- *
- * @return a {@link NetworkInfo} object for the current default network
- * or {@code null} if no default network is currently active
- *
- * {@hide}
- */
- public NetworkInfo getProvisioningOrActiveNetworkInfo() {
- try {
- return mService.getProvisioningOrActiveNetworkInfo();
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /**
* Returns the IP information for the current default network.
* <p>This method requires the caller to hold the permission
* {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
@@ -2007,24 +1985,6 @@ public class ConnectivityManager {
}
/**
- * Signal that the captive portal check on the indicated network
- * is complete and whether its a captive portal or not.
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
- *
- * @param info the {@link NetworkInfo} object for the networkType
- * in question.
- * @param isCaptivePortal true/false.
- * {@hide}
- */
- public void captivePortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) {
- try {
- mService.captivePortalCheckCompleted(info, isCaptivePortal);
- } catch (RemoteException e) {
- }
- }
-
- /**
* Check mobile provisioning.
*
* @param suggestedTimeOutMs, timeout in milliseconds
@@ -2056,18 +2016,6 @@ public class ConnectivityManager {
}
/**
- * Get the mobile redirected provisioning url.
- * {@hide}
- */
- public String getMobileRedirectedProvisioningUrl() {
- try {
- return mService.getMobileRedirectedProvisioningUrl();
- } catch (RemoteException e) {
- }
- return null;
- }
-
- /**
* Set sign in error notification to visible or in visible
*
* @param visible
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 89d23a2..29557bb 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -53,8 +53,6 @@ interface IConnectivityManager
Network[] getAllNetworks();
NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId);
- NetworkInfo getProvisioningOrActiveNetworkInfo();
-
boolean isNetworkSupported(int networkType);
LinkProperties getActiveLinkProperties();
@@ -122,14 +120,10 @@ interface IConnectivityManager
boolean updateLockdownVpn();
- void captivePortalCheckCompleted(in NetworkInfo info, boolean isCaptivePortal);
-
int checkMobileProvisioning(int suggestedTimeOutMs);
String getMobileProvisioningUrl();
- String getMobileRedirectedProvisioningUrl();
-
void setProvisioningNotificationVisible(boolean visible, int networkType, in String action);
void setAirplaneMode(boolean enable);
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index 9628bae..fe69320 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -378,6 +378,9 @@ public class Network implements Parcelable {
//
// The HANDLE_MAGIC value MUST be kept in sync with the corresponding
// value in the native/android/net.c NDK implementation.
+ if (netId == 0) {
+ return 0L; // make this zero condition obvious for debugging
+ }
final long HANDLE_MAGIC = 0xfacade;
return (((long) netId) << 32) | HANDLE_MAGIC;
}
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index 393637e..af7a465 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -120,7 +120,6 @@ public class NetworkInfo implements Parcelable {
private String mExtraInfo;
private boolean mIsFailover;
private boolean mIsRoaming;
- private boolean mIsConnectedToProvisioningNetwork;
/**
* Indicates whether network connectivity is possible:
@@ -142,7 +141,6 @@ public class NetworkInfo implements Parcelable {
mState = State.UNKNOWN;
mIsAvailable = false; // until we're told otherwise, assume unavailable
mIsRoaming = false;
- mIsConnectedToProvisioningNetwork = false;
}
/** {@hide} */
@@ -160,7 +158,6 @@ public class NetworkInfo implements Parcelable {
mIsFailover = source.mIsFailover;
mIsRoaming = source.mIsRoaming;
mIsAvailable = source.mIsAvailable;
- mIsConnectedToProvisioningNetwork = source.mIsConnectedToProvisioningNetwork;
}
}
}
@@ -332,22 +329,6 @@ public class NetworkInfo implements Parcelable {
}
}
- /** {@hide} */
- @VisibleForTesting
- public boolean isConnectedToProvisioningNetwork() {
- synchronized (this) {
- return mIsConnectedToProvisioningNetwork;
- }
- }
-
- /** {@hide} */
- @VisibleForTesting
- public void setIsConnectedToProvisioningNetwork(boolean val) {
- synchronized (this) {
- mIsConnectedToProvisioningNetwork = val;
- }
- }
-
/**
* Reports the current coarse-grained state of the network.
* @return the coarse-grained state
@@ -431,8 +412,6 @@ public class NetworkInfo implements Parcelable {
append(", roaming: ").append(mIsRoaming).
append(", failover: ").append(mIsFailover).
append(", isAvailable: ").append(mIsAvailable).
- append(", isConnectedToProvisioningNetwork: ").
- append(mIsConnectedToProvisioningNetwork).
append("]");
return builder.toString();
}
@@ -461,7 +440,6 @@ public class NetworkInfo implements Parcelable {
dest.writeInt(mIsFailover ? 1 : 0);
dest.writeInt(mIsAvailable ? 1 : 0);
dest.writeInt(mIsRoaming ? 1 : 0);
- dest.writeInt(mIsConnectedToProvisioningNetwork ? 1 : 0);
dest.writeString(mReason);
dest.writeString(mExtraInfo);
}
@@ -484,7 +462,6 @@ public class NetworkInfo implements Parcelable {
netInfo.mIsFailover = in.readInt() != 0;
netInfo.mIsAvailable = in.readInt() != 0;
netInfo.mIsRoaming = in.readInt() != 0;
- netInfo.mIsConnectedToProvisioningNetwork = in.readInt() != 0;
netInfo.mReason = in.readString();
netInfo.mExtraInfo = in.readString();
return netInfo;
diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java
index ff3de2b..bb08be2 100644
--- a/core/java/android/net/TrafficStats.java
+++ b/core/java/android/net/TrafficStats.java
@@ -53,6 +53,8 @@ public class TrafficStats {
public static final long GB_IN_BYTES = MB_IN_BYTES * 1024;
/** @hide */
public static final long TB_IN_BYTES = GB_IN_BYTES * 1024;
+ /** @hide */
+ public static final long PB_IN_BYTES = TB_IN_BYTES * 1024;
/**
* Special UID value used when collecting {@link NetworkStatsHistory} for
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index ef7e747..00350ec 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -362,6 +362,18 @@ public class UserManager {
public static final String DISALLOW_SMS = "no_sms";
/**
+ * Specifies if the user is not allowed to have fun. In some cases, the
+ * device owner may wish to prevent the user from experiencing amusement or
+ * joy while using the device. The default value is <code>false</code>.
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
+ * @see #setUserRestrictions(Bundle)
+ * @see #getUserRestrictions()
+ */
+ public static final String DISALLOW_FUN = "no_fun";
+
+ /**
* Specifies that windows besides app windows should not be
* created. This will block the creation of the following types of windows.
* <li>{@link LayoutParams#TYPE_TOAST}</li>
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index dfd72c2..3e9c9de 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7232,13 +7232,6 @@ public final class Settings {
"preferred_network_mode";
/**
- * Setting to 1 will hide carrier network settings.
- * Default is 0.
- */
- public static final String HIDE_CARRIER_NETWORK_SETTINGS =
- "hide_carrier_network_settings";
-
- /**
* Name of an application package to be debugged.
*/
public static final String DEBUG_APP = "debug_app";
diff --git a/core/java/android/text/format/Formatter.java b/core/java/android/text/format/Formatter.java
index b467f5a..13a959e 100644
--- a/core/java/android/text/format/Formatter.java
+++ b/core/java/android/text/format/Formatter.java
@@ -17,7 +17,9 @@
package android.text.format;
import android.content.Context;
+import android.content.res.Resources;
import android.net.NetworkUtils;
+import android.net.TrafficStats;
/**
* Utility class to aid in formatting common values that are not covered
@@ -25,63 +27,88 @@ import android.net.NetworkUtils;
*/
public final class Formatter {
+ /** {@hide} */
+ public static final int FLAG_SHORTER = 1 << 0;
+ /** {@hide} */
+ public static final int FLAG_CALCULATE_ROUNDED = 1 << 1;
+
+ /** {@hide} */
+ public static class BytesResult {
+ public final String value;
+ public final String units;
+ public final long roundedBytes;
+
+ public BytesResult(String value, String units, long roundedBytes) {
+ this.value = value;
+ this.units = units;
+ this.roundedBytes = roundedBytes;
+ }
+ }
+
/**
* Formats a content size to be in the form of bytes, kilobytes, megabytes, etc
*
* @param context Context to use to load the localized units
- * @param number size value to be formatted
+ * @param sizeBytes size value to be formatted, in bytes
* @return formatted string with the number
*/
- public static String formatFileSize(Context context, long number) {
- return formatFileSize(context, number, false);
+ public static String formatFileSize(Context context, long sizeBytes) {
+ final BytesResult res = formatBytes(context.getResources(), sizeBytes, 0);
+ return context.getString(com.android.internal.R.string.fileSizeSuffix,
+ res.value, res.units);
}
/**
* Like {@link #formatFileSize}, but trying to generate shorter numbers
* (showing fewer digits of precision).
*/
- public static String formatShortFileSize(Context context, long number) {
- return formatFileSize(context, number, true);
+ public static String formatShortFileSize(Context context, long sizeBytes) {
+ final BytesResult res = formatBytes(context.getResources(), sizeBytes, FLAG_SHORTER);
+ return context.getString(com.android.internal.R.string.fileSizeSuffix,
+ res.value, res.units);
}
- private static String formatFileSize(Context context, long number, boolean shorter) {
- if (context == null) {
- return "";
- }
-
- float result = number;
+ /** {@hide} */
+ public static BytesResult formatBytes(Resources res, long sizeBytes, int flags) {
+ float result = sizeBytes;
int suffix = com.android.internal.R.string.byteShort;
+ long mult = 1;
if (result > 900) {
suffix = com.android.internal.R.string.kilobyteShort;
+ mult = TrafficStats.KB_IN_BYTES;
result = result / 1024;
}
if (result > 900) {
suffix = com.android.internal.R.string.megabyteShort;
+ mult = TrafficStats.MB_IN_BYTES;
result = result / 1024;
}
if (result > 900) {
suffix = com.android.internal.R.string.gigabyteShort;
+ mult = TrafficStats.GB_IN_BYTES;
result = result / 1024;
}
if (result > 900) {
suffix = com.android.internal.R.string.terabyteShort;
+ mult = TrafficStats.TB_IN_BYTES;
result = result / 1024;
}
if (result > 900) {
suffix = com.android.internal.R.string.petabyteShort;
+ mult = TrafficStats.PB_IN_BYTES;
result = result / 1024;
}
String value;
if (result < 1) {
value = String.format("%.2f", result);
} else if (result < 10) {
- if (shorter) {
+ if ((flags & FLAG_SHORTER) != 0) {
value = String.format("%.1f", result);
} else {
value = String.format("%.2f", result);
}
} else if (result < 100) {
- if (shorter) {
+ if ((flags & FLAG_SHORTER) != 0) {
value = String.format("%.0f", result);
} else {
value = String.format("%.2f", result);
@@ -89,9 +116,14 @@ public final class Formatter {
} else {
value = String.format("%.0f", result);
}
- return context.getResources().
- getString(com.android.internal.R.string.fileSizeSuffix,
- value, context.getString(suffix));
+ final String units = res.getString(suffix);
+ final long roundedBytes;
+ if ((flags & FLAG_CALCULATE_ROUNDED) != 0) {
+ roundedBytes = (long) (Double.parseDouble(value) * mult);
+ } else {
+ roundedBytes = 0;
+ }
+ return new BytesResult(value, units, roundedBytes);
}
/**
diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java
index bac668a..8b74a1e 100644
--- a/core/java/android/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -557,7 +557,7 @@ public abstract class Visibility extends Transition {
if (mIsForcedVisibility) {
mView.setTransitionAlpha(0);
} else {
- mView.setTransitionVisibility(mFinalVisibility);
+ mView.setVisibility(mFinalVisibility);
}
}
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 89743e5..73cfd8c 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2939,11 +2939,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
}
- /** @hide */
@Override
- public void onInitializeAccessibilityEventInternal(AccessibilityEvent event) {
- super.onInitializeAccessibilityEventInternal(event);
- event.setClassName(ViewGroup.class.getName());
+ public CharSequence getAccessibilityClassName() {
+ return ViewGroup.class.getName();
}
@Override
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index cf6a018..f89ee91 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -244,15 +244,6 @@ public class Editor {
final CursorAnchorInfoNotifier mCursorAnchorInfoNotifier = new CursorAnchorInfoNotifier();
- private final Runnable mHideFloatingToolbar = new Runnable() {
- @Override
- public void run() {
- if (mTextActionMode != null) {
- mTextActionMode.hide(ActionMode.DEFAULT_HIDE_DURATION);
- }
- }
- };
-
private final Runnable mShowFloatingToolbar = new Runnable() {
@Override
public void run() {
@@ -389,7 +380,6 @@ public class Editor {
mTextView.removeCallbacks(mInsertionActionModeRunnable);
}
- mTextView.removeCallbacks(mHideFloatingToolbar);
mTextView.removeCallbacks(mShowFloatingToolbar);
destroyDisplayListsData();
@@ -1248,14 +1238,12 @@ public class Editor {
private void hideFloatingToolbar() {
if (mTextActionMode != null) {
mTextView.removeCallbacks(mShowFloatingToolbar);
- // Delay the "hide" a little bit just in case a "show" will happen almost immediately.
- mTextView.postDelayed(mHideFloatingToolbar, 100);
+ mTextActionMode.hide(ActionMode.DEFAULT_HIDE_DURATION);
}
}
private void showFloatingToolbar() {
if (mTextActionMode != null) {
- mTextView.removeCallbacks(mHideFloatingToolbar);
// Delay "show" so it doesn't interfere with click confirmations
// or double-clicks that could "dismiss" the floating toolbar.
int delay = ViewConfiguration.getDoubleTapTimeout();
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index 8ace0f3..2ea2667 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -26,7 +26,6 @@ import android.annotation.StyleRes;
import android.app.ActionBar;
import android.content.Context;
import android.content.res.TypedArray;
-import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
@@ -148,6 +147,9 @@ public class Toolbar extends ViewGroup {
// Clear me after use.
private final ArrayList<View> mTempViews = new ArrayList<View>();
+ // Used to hold views that will be removed while we have an expanded action view.
+ private final ArrayList<View> mHiddenViews = new ArrayList<>();
+
private final int[] mTempMargins = new int[2];
private OnMenuItemClickListener mOnMenuItemClickListener;
@@ -435,12 +437,12 @@ public class Toolbar extends ViewGroup {
public void setLogo(Drawable drawable) {
if (drawable != null) {
ensureLogoView();
- if (mLogoView.getParent() == null) {
- addSystemView(mLogoView);
- updateChildVisibilityForExpandedActionView(mLogoView);
+ if (!isChildOrHidden(mLogoView)) {
+ addSystemView(mLogoView, true);
}
- } else if (mLogoView != null && mLogoView.getParent() != null) {
+ } else if (mLogoView != null && isChildOrHidden(mLogoView)) {
removeView(mLogoView);
+ mHiddenViews.remove(mLogoView);
}
if (mLogoView != null) {
mLogoView.setImageDrawable(drawable);
@@ -577,12 +579,12 @@ public class Toolbar extends ViewGroup {
mTitleTextView.setTextColor(mTitleTextColor);
}
}
- if (mTitleTextView.getParent() == null) {
- addSystemView(mTitleTextView);
- updateChildVisibilityForExpandedActionView(mTitleTextView);
+ if (!isChildOrHidden(mTitleTextView)) {
+ addSystemView(mTitleTextView, true);
}
- } else if (mTitleTextView != null && mTitleTextView.getParent() != null) {
+ } else if (mTitleTextView != null && isChildOrHidden(mTitleTextView)) {
removeView(mTitleTextView);
+ mHiddenViews.remove(mTitleTextView);
}
if (mTitleTextView != null) {
mTitleTextView.setText(title);
@@ -631,12 +633,12 @@ public class Toolbar extends ViewGroup {
mSubtitleTextView.setTextColor(mSubtitleTextColor);
}
}
- if (mSubtitleTextView.getParent() == null) {
- addSystemView(mSubtitleTextView);
- updateChildVisibilityForExpandedActionView(mSubtitleTextView);
+ if (!isChildOrHidden(mSubtitleTextView)) {
+ addSystemView(mSubtitleTextView, true);
}
- } else if (mSubtitleTextView != null && mSubtitleTextView.getParent() != null) {
+ } else if (mSubtitleTextView != null && isChildOrHidden(mSubtitleTextView)) {
removeView(mSubtitleTextView);
+ mHiddenViews.remove(mSubtitleTextView);
}
if (mSubtitleTextView != null) {
mSubtitleTextView.setText(subtitle);
@@ -772,12 +774,12 @@ public class Toolbar extends ViewGroup {
public void setNavigationIcon(@Nullable Drawable icon) {
if (icon != null) {
ensureNavButtonView();
- if (mNavButtonView.getParent() == null) {
- addSystemView(mNavButtonView);
- updateChildVisibilityForExpandedActionView(mNavButtonView);
+ if (!isChildOrHidden(mNavButtonView)) {
+ addSystemView(mNavButtonView, true);
}
- } else if (mNavButtonView != null && mNavButtonView.getParent() != null) {
+ } else if (mNavButtonView != null && isChildOrHidden(mNavButtonView)) {
removeView(mNavButtonView);
+ mHiddenViews.remove(mNavButtonView);
}
if (mNavButtonView != null) {
mNavButtonView.setImageDrawable(icon);
@@ -866,7 +868,7 @@ public class Toolbar extends ViewGroup {
final LayoutParams lp = generateDefaultLayoutParams();
lp.gravity = Gravity.END | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
mMenuView.setLayoutParams(lp);
- addSystemView(mMenuView);
+ addSystemView(mMenuView, false);
}
}
@@ -1041,7 +1043,7 @@ public class Toolbar extends ViewGroup {
}
}
- private void addSystemView(View v) {
+ private void addSystemView(View v, boolean allowHide) {
final ViewGroup.LayoutParams vlp = v.getLayoutParams();
final LayoutParams lp;
if (vlp == null) {
@@ -1052,7 +1054,13 @@ public class Toolbar extends ViewGroup {
lp = (LayoutParams) vlp;
}
lp.mViewType = LayoutParams.SYSTEM;
- addView(v, lp);
+
+ if (allowHide && mExpandedActionView != null) {
+ v.setLayoutParams(lp);
+ mHiddenViews.add(v);
+ } else {
+ addView(v, lp);
+ }
}
@Override
@@ -1741,22 +1749,30 @@ public class Toolbar extends ViewGroup {
return mWrapper;
}
- private void setChildVisibilityForExpandedActionView(boolean expand) {
+ void removeChildrenForExpandedActionView() {
final int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
+ // Go backwards since we're removing from the list
+ for (int i = childCount - 1; i >= 0; i--) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (lp.mViewType != LayoutParams.EXPANDED && child != mMenuView) {
- child.setVisibility(expand ? GONE : VISIBLE);
+ removeViewAt(i);
+ mHiddenViews.add(child);
}
}
}
- private void updateChildVisibilityForExpandedActionView(View child) {
- final LayoutParams lp = (LayoutParams) child.getLayoutParams();
- if (lp.mViewType != LayoutParams.EXPANDED && child != mMenuView) {
- child.setVisibility(mExpandedActionView != null ? GONE : VISIBLE);
+ void addChildrenForExpandedActionView() {
+ final int count = mHiddenViews.size();
+ // Re-add in reverse order since we removed in reverse order
+ for (int i = count - 1; i >= 0; i--) {
+ addView(mHiddenViews.get(i));
}
+ mHiddenViews.clear();
+ }
+
+ private boolean isChildOrHidden(View child) {
+ return child.getParent() == this || mHiddenViews.contains(child);
}
/**
@@ -1971,7 +1987,7 @@ public class Toolbar extends ViewGroup {
addView(mExpandedActionView);
}
- setChildVisibilityForExpandedActionView(true);
+ removeChildrenForExpandedActionView();
requestLayout();
item.setActionViewExpanded(true);
@@ -1994,7 +2010,7 @@ public class Toolbar extends ViewGroup {
removeView(mCollapseButtonView);
mExpandedActionView = null;
- setChildVisibilityForExpandedActionView(false);
+ addChildrenForExpandedActionView();
mCurrentExpandedItem = null;
requestLayout();
item.setActionViewExpanded(false);
diff --git a/core/java/com/android/internal/app/ToolbarActionBar.java b/core/java/com/android/internal/app/ToolbarActionBar.java
index 34b9dcb..2b162af 100644
--- a/core/java/com/android/internal/app/ToolbarActionBar.java
+++ b/core/java/com/android/internal/app/ToolbarActionBar.java
@@ -83,7 +83,9 @@ public class ToolbarActionBar extends ActionBar {
@Override
public void setCustomView(View view, LayoutParams layoutParams) {
- view.setLayoutParams(layoutParams);
+ if (view != null) {
+ view.setLayoutParams(layoutParams);
+ }
mDecorToolbar.setCustomView(view);
}
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index 2539a35..f81658e 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -24,6 +24,7 @@ import android.os.Debug;
import android.os.IBinder;
import android.os.Process;
import android.os.SystemProperties;
+import android.os.Trace;
import android.util.Log;
import android.util.Slog;
import com.android.internal.logging.AndroidConfig;
@@ -269,11 +270,11 @@ public class RuntimeInit {
throws ZygoteInit.MethodAndArgsCaller {
if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
redirectLogStreams();
commonInit();
nativeZygoteInit();
-
applicationInit(targetSdkVersion, argv, classLoader);
}
@@ -318,6 +319,9 @@ public class RuntimeInit {
return;
}
+ // The end of of the RuntimeInit event (see #zygoteInit).
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+
// Remaining arguments are passed to the start class's static main
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 1e7ee5a..4f6d781 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -17,6 +17,7 @@
package com.android.internal.os;
+import android.os.Trace;
import dalvik.system.ZygoteHooks;
import android.system.ErrnoException;
import android.system.Os;
@@ -88,6 +89,13 @@ public final class Zygote {
int pid = nativeForkAndSpecialize(
uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
instructionSet, appDataDir);
+ // Enable tracing as soon as possible for the child process.
+ if (pid == 0) {
+ Trace.setTracingEnabled(true);
+
+ // Note that this event ends at the end of handleChildProc,
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
+ }
VM_HOOKS.postForkCommon();
return pid;
}
@@ -124,6 +132,10 @@ public final class Zygote {
VM_HOOKS.preFork();
int pid = nativeForkSystemServer(
uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
+ // Enable tracing as soon as we enter the system_server.
+ if (pid == 0) {
+ Trace.setTracingEnabled(true);
+ }
VM_HOOKS.postForkCommon();
return pid;
}
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 969d236..1a0345b 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -27,6 +27,7 @@ import android.net.LocalSocket;
import android.os.Process;
import android.os.SELinux;
import android.os.SystemProperties;
+import android.os.Trace;
import android.system.ErrnoException;
import android.system.Os;
import android.util.Log;
@@ -711,7 +712,6 @@ class ZygoteConnection {
private void handleChildProc(Arguments parsedArgs,
FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
throws ZygoteInit.MethodAndArgsCaller {
-
/**
* By the time we get here, the native code has closed the two actual Zygote
* socket connections, and substituted /dev/null in their place. The LocalSocket
@@ -740,6 +740,8 @@ class ZygoteConnection {
Process.setArgV0(parsedArgs.niceName);
}
+ // End of the postFork event.
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
if (parsedArgs.invokeWith != null) {
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java
index 661dce1..99c1277 100644
--- a/core/java/com/android/internal/view/FloatingActionMode.java
+++ b/core/java/com/android/internal/view/FloatingActionMode.java
@@ -48,12 +48,14 @@ public class FloatingActionMode extends ActionMode {
private final Runnable mMovingOff = new Runnable() {
public void run() {
mFloatingToolbarVisibilityHelper.setMoving(false);
+ mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
}
};
private final Runnable mHideOff = new Runnable() {
public void run() {
mFloatingToolbarVisibilityHelper.setHideRequested(false);
+ mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
}
};
@@ -87,6 +89,7 @@ public class FloatingActionMode extends ActionMode {
}
});
mFloatingToolbarVisibilityHelper = new FloatingToolbarVisibilityHelper(mFloatingToolbar);
+ mFloatingToolbarVisibilityHelper.activate();
}
@Override
@@ -108,8 +111,7 @@ public class FloatingActionMode extends ActionMode {
public void invalidate() {
checkToolbarInitialized();
mCallback.onPrepareActionMode(this, mMenu);
- mFloatingToolbar.updateLayout();
- invalidateContentRect();
+ invalidateContentRect(); // Will re-layout and show the toolbar if necessary.
}
@Override
@@ -131,44 +133,43 @@ public class FloatingActionMode extends ActionMode {
mContentRectOnWindow.set(mContentRect);
mContentRectOnWindow.offset(mViewPosition[0], mViewPosition[1]);
- // Make sure that content rect is not out of the view's visible bounds.
- mContentRectOnWindow.set(
- Math.max(mContentRectOnWindow.left, mViewRect.left),
- Math.max(mContentRectOnWindow.top, mViewRect.top),
- Math.min(mContentRectOnWindow.right, mViewRect.right),
- Math.min(mContentRectOnWindow.bottom, mViewRect.bottom));
-
- if (!mContentRectOnWindow.equals(mPreviousContentRectOnWindow)) {
- if (!mPreviousContentRectOnWindow.isEmpty()) {
- notifyContentRectMoving();
- }
- mFloatingToolbar.setContentRect(mContentRectOnWindow);
- mFloatingToolbar.updateLayout();
- }
- mPreviousContentRectOnWindow.set(mContentRectOnWindow);
if (isContentRectWithinBounds()) {
mFloatingToolbarVisibilityHelper.setOutOfBounds(false);
+ // Make sure that content rect is not out of the view's visible bounds.
+ mContentRectOnWindow.set(
+ Math.max(mContentRectOnWindow.left, mViewRect.left),
+ Math.max(mContentRectOnWindow.top, mViewRect.top),
+ Math.min(mContentRectOnWindow.right, mViewRect.right),
+ Math.min(mContentRectOnWindow.bottom, mViewRect.bottom));
+
+ if (!mContentRectOnWindow.equals(mPreviousContentRectOnWindow)) {
+ // Content rect is moving.
+ mOriginatingView.removeCallbacks(mMovingOff);
+ mFloatingToolbarVisibilityHelper.setMoving(true);
+ mOriginatingView.postDelayed(mMovingOff, MOVING_HIDE_DELAY);
+
+ mFloatingToolbar.setContentRect(mContentRectOnWindow);
+ mFloatingToolbar.updateLayout();
+ }
} else {
mFloatingToolbarVisibilityHelper.setOutOfBounds(true);
+ mContentRectOnWindow.setEmpty();
}
- }
+ mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
- private boolean isContentRectWithinBounds() {
- mScreenRect.set(
- 0,
- 0,
- mContext.getResources().getDisplayMetrics().widthPixels,
- mContext.getResources().getDisplayMetrics().heightPixels);
-
- return Rect.intersects(mContentRectOnWindow, mScreenRect)
- && Rect.intersects(mContentRectOnWindow, mViewRect);
+ mPreviousContentRectOnWindow.set(mContentRectOnWindow);
}
- private void notifyContentRectMoving() {
- mOriginatingView.removeCallbacks(mMovingOff);
- mFloatingToolbarVisibilityHelper.setMoving(true);
- mOriginatingView.postDelayed(mMovingOff, MOVING_HIDE_DELAY);
+ private boolean isContentRectWithinBounds() {
+ mScreenRect.set(
+ 0,
+ 0,
+ mContext.getResources().getDisplayMetrics().widthPixels,
+ mContext.getResources().getDisplayMetrics().heightPixels);
+
+ return Rect.intersects(mContentRectOnWindow, mScreenRect)
+ && Rect.intersects(mContentRectOnWindow, mViewRect);
}
@Override
@@ -184,6 +185,7 @@ public class FloatingActionMode extends ActionMode {
mHideOff.run();
} else {
mFloatingToolbarVisibilityHelper.setHideRequested(true);
+ mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
mOriginatingView.postDelayed(mHideOff, duration);
}
}
@@ -221,7 +223,7 @@ public class FloatingActionMode extends ActionMode {
}
/**
- * @throws IlllegalStateException
+ * @throws IllegalStateException
*/
private void checkToolbarInitialized() {
Preconditions.checkState(mFloatingToolbar != null);
@@ -229,13 +231,14 @@ public class FloatingActionMode extends ActionMode {
}
private void reset() {
+ mFloatingToolbarVisibilityHelper.deactivate();
mOriginatingView.removeCallbacks(mMovingOff);
mOriginatingView.removeCallbacks(mHideOff);
}
/**
- * A helper that shows/hides the floating toolbar depending on certain states.
+ * A helper for showing/hiding the floating toolbar depending on certain states.
*/
private static final class FloatingToolbarVisibilityHelper {
@@ -245,29 +248,45 @@ public class FloatingActionMode extends ActionMode {
private boolean mMoving;
private boolean mOutOfBounds;
+ private boolean mActive;
+
public FloatingToolbarVisibilityHelper(FloatingToolbar toolbar) {
mToolbar = Preconditions.checkNotNull(toolbar);
}
+ public void activate() {
+ mHideRequested = false;
+ mMoving = false;
+ mOutOfBounds = false;
+
+ mActive = true;
+ }
+
+ public void deactivate() {
+ mActive = false;
+ mToolbar.dismiss();
+ }
+
public void setHideRequested(boolean hide) {
mHideRequested = hide;
- updateToolbarVisibility();
}
public void setMoving(boolean moving) {
mMoving = moving;
- updateToolbarVisibility();
}
public void setOutOfBounds(boolean outOfBounds) {
mOutOfBounds = outOfBounds;
- updateToolbarVisibility();
}
- private void updateToolbarVisibility() {
+ public void updateToolbarVisibility() {
+ if (!mActive) {
+ return;
+ }
+
if (mHideRequested || mMoving || mOutOfBounds) {
mToolbar.hide();
- } else if (mToolbar.isHidden()) {
+ } else {
mToolbar.show();
}
}
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index 2d0989f..53ebc23 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -37,7 +37,6 @@ import android.view.View.MeasureSpec;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
-import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
@@ -436,8 +435,6 @@ public final class FloatingToolbar {
// The "show" animation will make this visible.
mContentContainer.setAlpha(0);
}
- refreshViewPort();
- updateOverflowHeight(contentRect.top - (mMarginVertical * 2) - mViewPort.top);
refreshCoordinatesAndOverflowDirection(contentRect);
preparePopupContent();
mPopupWindow.showAtLocation(mParent, Gravity.NO_GRAVITY, mCoords.x, mCoords.y);
@@ -501,7 +498,6 @@ public final class FloatingToolbar {
}
cancelOverflowAnimations();
- refreshViewPort();
refreshCoordinatesAndOverflowDirection(contentRect);
preparePopupContent();
mPopupWindow.update(mCoords.x, mCoords.y, getWidth(), getHeight());
@@ -529,28 +525,65 @@ public final class FloatingToolbar {
}
private void refreshCoordinatesAndOverflowDirection(Rect contentRect) {
- // NOTE: Ensure that mViewPort has been refreshed before this.
+ refreshViewPort();
- int x = contentRect.centerX() - getWidth() / 2;
- int y;
- if (contentRect.top - getHeight() > mViewPort.top) {
- y = contentRect.top - getHeight();
- mOverflowDirection = FloatingToolbarPopup.OVERFLOW_DIRECTION_UP;
- } else if (contentRect.top - getToolbarHeightWithVerticalMargin() > mViewPort.top) {
- y = contentRect.top - getToolbarHeightWithVerticalMargin();
- mOverflowDirection = FloatingToolbarPopup.OVERFLOW_DIRECTION_DOWN;
- } else {
- y = contentRect.bottom;
- mOverflowDirection = FloatingToolbarPopup.OVERFLOW_DIRECTION_DOWN;
- }
+ int availableHeightAboveContent =
+ contentRect.top - mViewPort.top - 2 * mMarginVertical;
+ int availableHeightBelowContent =
+ mViewPort.bottom - contentRect.bottom - 2 * mMarginVertical;
+ int availableHeightThroughContent =
+ mViewPort.bottom - contentRect.top + getToolbarHeightWithVerticalMargin();
+ int x = contentRect.centerX() - getWidth() / 2;
// Update x so that the toolbar isn't rendered behind the nav bar in landscape.
x = Math.max(0, Math.min(x, mViewPort.right - getWidth()));
- mCoords.set(x, y);
- if (mOverflowPanel != null) {
+ int y;
+ if (mOverflowPanel == null) { // There is no overflow.
+ if (availableHeightAboveContent > getToolbarHeightWithVerticalMargin()) {
+ // There is enough space at the top of the content.
+ y = contentRect.top - getToolbarHeightWithVerticalMargin();
+ } else if (availableHeightBelowContent > getToolbarHeightWithVerticalMargin()) {
+ // There is enough space at the bottom of the content.
+ y = contentRect.bottom;
+ } else {
+ // Not enough space. Prefer to position as high as possible.
+ y = Math.max(
+ mViewPort.top,
+ contentRect.top - getToolbarHeightWithVerticalMargin());
+ }
+ } else { // There is an overflow.
+ if (availableHeightAboveContent > mOverflowPanel.getMinimumHeight()) {
+ // There is enough space at the top of the content rect for the overflow.
+ // Position above and open upwards.
+ updateOverflowHeight(availableHeightAboveContent);
+ y = contentRect.top - getHeight();
+ mOverflowDirection = OVERFLOW_DIRECTION_UP;
+ } else if (availableHeightAboveContent > getToolbarHeightWithVerticalMargin()
+ && availableHeightThroughContent > mOverflowPanel.getMinimumHeight()) {
+ // There is enough space at the top of the content rect for the main panel
+ // but not the overflow.
+ // Position above but open downwards.
+ updateOverflowHeight(availableHeightThroughContent);
+ y = contentRect.top - getToolbarHeightWithVerticalMargin();
+ mOverflowDirection = OVERFLOW_DIRECTION_DOWN;
+ } else if (availableHeightBelowContent > mOverflowPanel.getMinimumHeight()) {
+ // There is enough space at the bottom of the content rect for the overflow.
+ // Position below and open downwards.
+ updateOverflowHeight(availableHeightBelowContent);
+ y = contentRect.bottom;
+ mOverflowDirection = OVERFLOW_DIRECTION_DOWN;
+ } else {
+ // Not enough space.
+ // Position at the bottom of the view port and open upwards.
+ updateOverflowHeight(mViewPort.height());
+ y = mViewPort.bottom - getHeight();
+ mOverflowDirection = OVERFLOW_DIRECTION_UP;
+ }
mOverflowPanel.setOverflowDirection(mOverflowDirection);
}
+
+ mCoords.set(x, y);
}
private int getToolbarHeightWithVerticalMargin() {
@@ -837,13 +870,7 @@ public final class FloatingToolbar {
private void refreshViewPort() {
- mParent.getGlobalVisibleRect(mViewPort);
- WindowInsets windowInsets = mParent.getRootWindowInsets();
- mViewPort.set(
- mViewPort.left + windowInsets.getStableInsetLeft(),
- mViewPort.top + windowInsets.getStableInsetTop(),
- mViewPort.right - windowInsets.getStableInsetRight(),
- mViewPort.bottom - windowInsets.getStableInsetBottom());
+ mParent.getWindowVisibleDisplayFrame(mViewPort);
}
private int getToolbarWidth(int suggestedWidth) {
@@ -1139,6 +1166,12 @@ public final class FloatingToolbar {
setListViewHeight();
}
+ public int getMinimumHeight() {
+ return mContentView.getContext().getResources().
+ getDimensionPixelSize(R.dimen.floating_toolbar_minimum_overflow_height)
+ + getEstimatedToolbarHeight(mContentView.getContext());
+ }
+
/**
* Returns the content view of the overflow.
*/
@@ -1173,13 +1206,18 @@ public final class FloatingToolbar {
getDimensionPixelSize(R.dimen.floating_toolbar_maximum_overflow_height);
int minHeight = mContentView.getContext().getResources().
getDimensionPixelSize(R.dimen.floating_toolbar_minimum_overflow_height);
- int availableHeight = mSuggestedHeight - (mSuggestedHeight % itemHeight)
+ int suggestedListViewHeight = mSuggestedHeight - (mSuggestedHeight % itemHeight)
- itemHeight; // reserve space for the back button.
ViewGroup.LayoutParams params = mListView.getLayoutParams();
- if (availableHeight >= minHeight) {
- params.height = Math.min(Math.min(availableHeight, maxHeight), height);
- } else {
+ if (suggestedListViewHeight <= 0) {
+ // Invalid height. Use the maximum height available.
params.height = Math.min(maxHeight, height);
+ } else if (suggestedListViewHeight < minHeight) {
+ // Height is smaller than minimum allowed. Use minimum height.
+ params.height = minHeight;
+ } else {
+ // Use the suggested height. Cap it at the maximum available height.
+ params.height = Math.min(Math.min(suggestedListViewHeight, maxHeight), height);
}
mListView.setLayoutParams(params);
}
@@ -1360,6 +1398,7 @@ public final class FloatingToolbar {
PopupWindow popupWindow = new PopupWindow(popupContentHolder);
popupWindow.setWindowLayoutType(
WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL);
+ popupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
popupWindow.setAnimationStyle(0);
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
content.setLayoutParams(new ViewGroup.LayoutParams(
diff --git a/core/java/com/android/server/backup/AccountSyncSettingsBackupHelper.java b/core/java/com/android/server/backup/AccountSyncSettingsBackupHelper.java
index 3f4b980..c0215a8 100644
--- a/core/java/com/android/server/backup/AccountSyncSettingsBackupHelper.java
+++ b/core/java/com/android/server/backup/AccountSyncSettingsBackupHelper.java
@@ -28,8 +28,6 @@ import android.app.backup.BackupHelper;
import android.content.ContentResolver;
import android.content.Context;
import android.content.SyncAdapterType;
-import android.content.SyncStatusObserver;
-import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.util.Log;
@@ -47,8 +45,6 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
/**
* Helper for backing up account sync settings (whether or not a service should be synced). The
@@ -270,6 +266,10 @@ public class AccountSyncSettingsBackupHelper implements BackupHelper {
// yet won't be restored.
if (currentAccounts.contains(account)) {
restoreExistingAccountSyncSettingsFromJSON(accountJSON);
+ } else {
+ // TODO:
+ // Stash the data to a file that the SyncManager can read from to restore
+ // settings at a later date.
}
}
} finally {
@@ -300,6 +300,31 @@ public class AccountSyncSettingsBackupHelper implements BackupHelper {
/**
* Restore account sync settings using the given JSON. This function won't work if the account
* doesn't exist yet.
+ * This function will only be called during Setup Wizard, where we are guaranteed that there
+ * are no active syncs.
+ * There are 2 pieces of data to restore -
+ * isSyncable (corresponds to {@link ContentResolver#getIsSyncable(Account, String)}
+ * syncEnabled (corresponds to {@link ContentResolver#getSyncAutomatically(Account, String)}
+ * <strong>The restore favours adapters that were enabled on the old device, and doesn't care
+ * about adapters that were disabled.</strong>
+ *
+ * syncEnabled=true in restore data.
+ * syncEnabled will be true on this device. isSyncable will be left as the default in order to
+ * give the enabled adapter the chance to run an initialization sync.
+ *
+ * syncEnabled=false in restore data.
+ * syncEnabled will be false on this device. isSyncable will be set to 2, unless it was 0 on the
+ * old device in which case it will be set to 0 on this device. This is because isSyncable=0 is
+ * a rare state and was probably set to 0 for good reason (historically isSyncable is a way by
+ * which adapters control their own sync state independently of sync settings which is
+ * toggleable by the user).
+ * isSyncable=2 is a new isSyncable state we introduced specifically to allow adapters that are
+ * disabled after a restore to run initialization logic when the adapter is later enabled.
+ * See com.android.server.content.SyncStorageEngine#setSyncAutomatically
+ *
+ * The end result is that an adapter that the user had on will be turned on and get an
+ * initialization sync, while an adapter that the user had off will be off until the user
+ * enables it on this device at which point it will get an initialization sync.
*/
private void restoreExistingAccountSyncSettingsFromJSON(JSONObject accountJSON)
throws JSONException {
@@ -307,72 +332,27 @@ public class AccountSyncSettingsBackupHelper implements BackupHelper {
JSONArray authorities = accountJSON.getJSONArray(KEY_ACCOUNT_AUTHORITIES);
String accountName = accountJSON.getString(KEY_ACCOUNT_NAME);
String accountType = accountJSON.getString(KEY_ACCOUNT_TYPE);
+
final Account account = new Account(accountName, accountType);
for (int i = 0; i < authorities.length(); i++) {
JSONObject authority = (JSONObject) authorities.get(i);
final String authorityName = authority.getString(KEY_AUTHORITY_NAME);
- boolean syncEnabled = authority.getBoolean(KEY_AUTHORITY_SYNC_ENABLED);
-
- // Cancel any active syncs.
- if (ContentResolver.isSyncActive(account, authorityName)) {
- ContentResolver.cancelSync(account, authorityName);
- }
-
- boolean overwriteSync = true;
- Bundle initializationExtras = createSyncInitializationBundle();
- int currentSyncState = ContentResolver.getIsSyncable(account, authorityName);
- if (currentSyncState < 0) {
- // Requesting a sync is an asynchronous operation, so we setup a countdown latch to
- // wait for it to finish. Initialization syncs are generally very brief and
- // shouldn't take too much time to finish.
- final CountDownLatch latch = new CountDownLatch(1);
- Object syncStatusObserverHandle = ContentResolver.addStatusChangeListener(
- ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE, new SyncStatusObserver() {
- @Override
- public void onStatusChanged(int which) {
- if (!ContentResolver.isSyncActive(account, authorityName)) {
- latch.countDown();
- }
- }
- });
-
- // If we set sync settings for a sync that hasn't been initialized yet, we run the
- // risk of having our changes overwritten later on when the sync gets initialized.
- // To prevent this from happening we will manually initiate the sync adapter. We
- // also explicitly pass in a Bundle with SYNC_EXTRAS_INITIALIZE to prevent a data
- // sync from running after the initialization sync. Two syncs will be scheduled, but
- // the second one (data sync) will override the first one (initialization sync) and
- // still behave as an initialization sync because of the Bundle.
- ContentResolver.requestSync(account, authorityName, initializationExtras);
-
- boolean done = false;
- try {
- done = latch.await(SYNC_REQUEST_LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS);
- } catch (InterruptedException e) {
- Log.e(TAG, "CountDownLatch interrupted\n" + e);
- done = false;
- }
- if (!done) {
- overwriteSync = false;
- Log.i(TAG, "CountDownLatch timed out, skipping '" + authorityName
- + "' authority.");
- }
- ContentResolver.removeStatusChangeListener(syncStatusObserverHandle);
- }
-
- if (overwriteSync) {
- ContentResolver.setSyncAutomatically(account, authorityName, syncEnabled);
- Log.i(TAG, "Set sync automatically for '" + authorityName + "': " + syncEnabled);
+ boolean wasSyncEnabled = authority.getBoolean(KEY_AUTHORITY_SYNC_ENABLED);
+ int wasSyncable = authority.getInt(KEY_AUTHORITY_SYNC_STATE);
+
+ ContentResolver.setSyncAutomaticallyAsUser(
+ account, authorityName, wasSyncEnabled, 0 /* user Id */);
+
+ if (!wasSyncEnabled) {
+ ContentResolver.setIsSyncable(
+ account,
+ authorityName,
+ wasSyncable == 0 ?
+ 0 /* not syncable */ : 2 /* syncable but needs initialization */);
}
}
}
- private Bundle createSyncInitializationBundle() {
- Bundle extras = new Bundle();
- extras.putBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, true);
- return extras;
- }
-
@Override
public void writeNewStateDescription(ParcelFileDescriptor newState) {
diff --git a/core/jni/android_hardware_camera2_DngCreator.cpp b/core/jni/android_hardware_camera2_DngCreator.cpp
index 2229071..304de8c 100644
--- a/core/jni/android_hardware_camera2_DngCreator.cpp
+++ b/core/jni/android_hardware_camera2_DngCreator.cpp
@@ -371,8 +371,8 @@ ssize_t JniInputByteBuffer::read(uint8_t* buf, size_t offset, size_t count) {
realCount = count;
}
- jobject chainingBuf = mEnv->CallObjectMethod(mInBuf, gInputByteBufferClassInfo.mGetMethod, mByteArray, 0,
- realCount);
+ jobject chainingBuf = mEnv->CallObjectMethod(mInBuf, gInputByteBufferClassInfo.mGetMethod,
+ mByteArray, 0, realCount);
mEnv->DeleteLocalRef(chainingBuf);
if (mEnv->ExceptionCheck()) {
@@ -630,8 +630,10 @@ static bool validateDngHeader(JNIEnv* env, TiffWriter* writer, jint width, jint
bool hasThumbnail = writer->hasIfd(TIFF_IFD_SUB1);
// TODO: handle lens shading map, etc. conversions for other raw buffer sizes.
- uint32_t metadataWidth = *(writer->getEntry(TAG_IMAGEWIDTH, (hasThumbnail) ? TIFF_IFD_SUB1 : TIFF_IFD_0)->getData<uint32_t>());
- uint32_t metadataHeight = *(writer->getEntry(TAG_IMAGELENGTH, (hasThumbnail) ? TIFF_IFD_SUB1 : TIFF_IFD_0)->getData<uint32_t>());
+ uint32_t metadataWidth = *(writer->getEntry(TAG_IMAGEWIDTH, (hasThumbnail) ? TIFF_IFD_SUB1 :
+ TIFF_IFD_0)->getData<uint32_t>());
+ uint32_t metadataHeight = *(writer->getEntry(TAG_IMAGELENGTH, (hasThumbnail) ? TIFF_IFD_SUB1 :
+ TIFF_IFD_0)->getData<uint32_t>());
if (width < 0 || metadataWidth != static_cast<uint32_t>(width)) {
jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", \
@@ -641,7 +643,8 @@ static bool validateDngHeader(JNIEnv* env, TiffWriter* writer, jint width, jint
if (height < 0 || metadataHeight != static_cast<uint32_t>(height)) {
jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", \
- "Metadata height %d doesn't match image height %d", metadataHeight, height);
+ "Metadata height %d doesn't match image height %d",
+ metadataHeight, height);
return false;
}
@@ -1428,7 +1431,11 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt
}
{
- // Setup opcode List 2
+ // Set up opcode List 2
+ OpcodeListBuilder builder;
+ status_t err = OK;
+
+ // Set up lens shading map
camera_metadata_entry entry1 =
characteristics.find(ANDROID_LENS_INFO_SHADING_MAP_SIZE);
@@ -1444,34 +1451,52 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt
results.find(ANDROID_STATISTICS_LENS_SHADING_MAP);
if (entry2.count > 0 && entry2.count == lsmWidth * lsmHeight * 4) {
-
- OpcodeListBuilder builder;
- status_t err = builder.addGainMapsForMetadata(lsmWidth,
- lsmHeight,
- 0,
- 0,
- imageHeight,
- imageWidth,
- opcodeCfaLayout,
- entry2.data.f);
- if (err == OK) {
- size_t listSize = builder.getSize();
- uint8_t opcodeListBuf[listSize];
- err = builder.buildOpList(opcodeListBuf);
- if (err == OK) {
- BAIL_IF_INVALID(writer->addEntry(TAG_OPCODELIST2, listSize, opcodeListBuf,
- TIFF_IFD_0), env, TAG_OPCODELIST2, writer);
- } else {
- ALOGE("%s: Could not build Lens shading map opcode.", __FUNCTION__);
- jniThrowRuntimeException(env, "failed to construct lens shading map opcode.");
- }
- } else {
+ err = builder.addGainMapsForMetadata(lsmWidth,
+ lsmHeight,
+ 0,
+ 0,
+ imageHeight,
+ imageWidth,
+ opcodeCfaLayout,
+ entry2.data.f);
+ if (err != OK) {
ALOGE("%s: Could not add Lens shading map.", __FUNCTION__);
jniThrowRuntimeException(env, "failed to add lens shading map.");
+ return;
+ }
+ }
+
+ // Set up rectilinear distortion correction
+ camera_metadata_entry entry3 =
+ results.find(ANDROID_LENS_RADIAL_DISTORTION);
+ camera_metadata_entry entry4 =
+ results.find(ANDROID_LENS_INTRINSIC_CALIBRATION);
+
+ if (entry3.count == 6 && entry4.count == 5) {
+ float cx = entry4.data.f[/*c_x*/2];
+ float cy = entry4.data.f[/*c_y*/3];
+ err = builder.addWarpRectilinearForMetadata(entry3.data.f, imageWidth, imageHeight, cx,
+ cy);
+ if (err != OK) {
+ ALOGE("%s: Could not add distortion correction.", __FUNCTION__);
+ jniThrowRuntimeException(env, "failed to add distortion correction.");
+ return;
}
+ }
+
+
+ size_t listSize = builder.getSize();
+ uint8_t opcodeListBuf[listSize];
+ err = builder.buildOpList(opcodeListBuf);
+ if (err == OK) {
+ BAIL_IF_INVALID(writer->addEntry(TAG_OPCODELIST2, listSize, opcodeListBuf,
+ TIFF_IFD_0), env, TAG_OPCODELIST2, writer);
} else {
- ALOGW("%s: No lens shading map found in result metadata. Image quality may be reduced.",
- __FUNCTION__);
+ ALOGE("%s: Could not build list of opcodes for distortion correction and lens shading"
+ "map.", __FUNCTION__);
+ jniThrowRuntimeException(env, "failed to construct opcode list for distortion"
+ " correction and lens shading map");
+ return;
}
}
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 1cd07d1..ac00532 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -677,13 +677,14 @@ static jint convertAudioPortConfigFromNative(JNIEnv *env,
// constructed by java code with correct class type (device, mix etc...)
// and reference to AudioPort instance in this client
jAudioPort = env->NewObject(gAudioPortClass, gAudioPortCstor,
- jHandle,
- 0,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL);
+ jHandle, // handle
+ 0, // role
+ NULL, // name
+ NULL, // samplingRates
+ NULL, // channelMasks
+ NULL, // channelIndexMasks
+ NULL, // formats
+ NULL); // gains
env->DeleteLocalRef(jHandle);
if (jAudioPort == NULL) {
return (jint)AUDIO_JAVA_ERROR;
@@ -837,11 +838,14 @@ static jint convertAudioPortFromNative(JNIEnv *env,
jint jStatus = (jint)AUDIO_JAVA_SUCCESS;
jintArray jSamplingRates = NULL;
jintArray jChannelMasks = NULL;
+ jintArray jChannelIndexMasks = NULL;
jintArray jFormats = NULL;
jobjectArray jGains = NULL;
jobject jHandle = NULL;
jstring jDeviceName = NULL;
bool useInMask;
+ size_t numPositionMasks = 0;
+ size_t numIndexMasks = 0;
ALOGV("convertAudioPortFromNative id %d role %d type %d name %s",
nAudioPort->id, nAudioPort->role, nAudioPort->type, nAudioPort->name);
@@ -856,23 +860,43 @@ static jint convertAudioPortFromNative(JNIEnv *env,
(jint *)nAudioPort->sample_rates);
}
- jChannelMasks = env->NewIntArray(nAudioPort->num_channel_masks);
+ // count up how many masks are positional and indexed
+ for(size_t index = 0; index < nAudioPort->num_channel_masks; index++) {
+ const audio_channel_mask_t mask = nAudioPort->channel_masks[index];
+ if (audio_channel_mask_get_representation(mask) == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
+ numIndexMasks++;
+ } else {
+ numPositionMasks++;
+ }
+ }
+
+ jChannelMasks = env->NewIntArray(numPositionMasks);
if (jChannelMasks == NULL) {
jStatus = (jint)AUDIO_JAVA_ERROR;
goto exit;
}
+ jChannelIndexMasks = env->NewIntArray(numIndexMasks);
+ if (jChannelIndexMasks == NULL) {
+ jStatus = (jint)AUDIO_JAVA_ERROR;
+ goto exit;
+ }
useInMask = useInChannelMask(nAudioPort->type, nAudioPort->role);
- jint jMask;
- for (size_t j = 0; j < nAudioPort->num_channel_masks; j++) {
- if (useInMask) {
- jMask = inChannelMaskFromNative(nAudioPort->channel_masks[j]);
+ // put the masks in the output arrays
+ for (size_t maskIndex = 0, posMaskIndex = 0, indexedMaskIndex = 0;
+ maskIndex < nAudioPort->num_channel_masks; maskIndex++) {
+ const audio_channel_mask_t mask = nAudioPort->channel_masks[maskIndex];
+ if (audio_channel_mask_get_representation(mask) == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
+ jint jMask = audio_channel_mask_get_bits(mask);
+ env->SetIntArrayRegion(jChannelIndexMasks, indexedMaskIndex++, 1, &jMask);
} else {
- jMask = outChannelMaskFromNative(nAudioPort->channel_masks[j]);
+ jint jMask = useInMask ? inChannelMaskFromNative(mask)
+ : outChannelMaskFromNative(mask);
+ env->SetIntArrayRegion(jChannelMasks, posMaskIndex++, 1, &jMask);
}
- env->SetIntArrayRegion(jChannelMasks, j, 1, &jMask);
}
+ // formats
jFormats = env->NewIntArray(nAudioPort->num_formats);
if (jFormats == NULL) {
jStatus = (jint)AUDIO_JAVA_ERROR;
@@ -883,14 +907,17 @@ static jint convertAudioPortFromNative(JNIEnv *env,
env->SetIntArrayRegion(jFormats, j, 1, &jFormat);
}
+ // gains
jGains = env->NewObjectArray(nAudioPort->num_gains,
gAudioGainClass, NULL);
if (jGains == NULL) {
jStatus = (jint)AUDIO_JAVA_ERROR;
goto exit;
}
+
for (size_t j = 0; j < nAudioPort->num_gains; j++) {
audio_channel_mask_t nMask = nAudioPort->gains[j].channel_mask;
+ jint jMask;
if (useInMask) {
jMask = inChannelMaskFromNative(nMask);
ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask);
@@ -931,7 +958,8 @@ static jint convertAudioPortFromNative(JNIEnv *env,
jstring jAddress = env->NewStringUTF(nAudioPort->ext.device.address);
*jAudioPort = env->NewObject(gAudioDevicePortClass, gAudioDevicePortCstor,
jHandle, jDeviceName,
- jSamplingRates, jChannelMasks, jFormats, jGains,
+ jSamplingRates, jChannelMasks, jChannelIndexMasks,
+ jFormats, jGains,
nAudioPort->ext.device.type, jAddress);
env->DeleteLocalRef(jAddress);
} else if (nAudioPort->type == AUDIO_PORT_TYPE_MIX) {
@@ -939,7 +967,7 @@ static jint convertAudioPortFromNative(JNIEnv *env,
*jAudioPort = env->NewObject(gAudioMixPortClass, gAudioMixPortCstor,
jHandle, nAudioPort->ext.mix.handle,
nAudioPort->role, jDeviceName,
- jSamplingRates, jChannelMasks,
+ jSamplingRates, jChannelMasks, jChannelIndexMasks,
jFormats, jGains);
} else {
ALOGE("convertAudioPortFromNative unknown nAudioPort type %d", nAudioPort->type);
@@ -1634,7 +1662,7 @@ int register_android_media_AudioSystem(JNIEnv *env)
jclass audioPortClass = FindClassOrDie(env, "android/media/AudioPort");
gAudioPortClass = MakeGlobalRefOrDie(env, audioPortClass);
gAudioPortCstor = GetMethodIDOrDie(env, audioPortClass, "<init>",
- "(Landroid/media/AudioHandle;ILjava/lang/String;[I[I[I[Landroid/media/AudioGain;)V");
+ "(Landroid/media/AudioHandle;ILjava/lang/String;[I[I[I[I[Landroid/media/AudioGain;)V");
gAudioPortFields.mHandle = GetFieldIDOrDie(env, audioPortClass, "mHandle",
"Landroid/media/AudioHandle;");
gAudioPortFields.mRole = GetFieldIDOrDie(env, audioPortClass, "mRole", "I");
@@ -1672,12 +1700,12 @@ int register_android_media_AudioSystem(JNIEnv *env)
jclass audioDevicePortClass = FindClassOrDie(env, "android/media/AudioDevicePort");
gAudioDevicePortClass = MakeGlobalRefOrDie(env, audioDevicePortClass);
gAudioDevicePortCstor = GetMethodIDOrDie(env, audioDevicePortClass, "<init>",
- "(Landroid/media/AudioHandle;Ljava/lang/String;[I[I[I[Landroid/media/AudioGain;ILjava/lang/String;)V");
+ "(Landroid/media/AudioHandle;Ljava/lang/String;[I[I[I[I[Landroid/media/AudioGain;ILjava/lang/String;)V");
jclass audioMixPortClass = FindClassOrDie(env, "android/media/AudioMixPort");
gAudioMixPortClass = MakeGlobalRefOrDie(env, audioMixPortClass);
gAudioMixPortCstor = GetMethodIDOrDie(env, audioMixPortClass, "<init>",
- "(Landroid/media/AudioHandle;IILjava/lang/String;[I[I[I[Landroid/media/AudioGain;)V");
+ "(Landroid/media/AudioHandle;IILjava/lang/String;[I[I[I[I[Landroid/media/AudioGain;)V");
jclass audioGainClass = FindClassOrDie(env, "android/media/AudioGain");
gAudioGainClass = MakeGlobalRefOrDie(env, audioGainClass);
diff --git a/core/jni/android_util_Log.cpp b/core/jni/android_util_Log.cpp
index 9a80f1d..2b1067b 100644
--- a/core/jni/android_util_Log.cpp
+++ b/core/jni/android_util_Log.cpp
@@ -41,32 +41,8 @@ struct levels_t {
};
static levels_t levels;
-static int toLevel(const char* value)
-{
- switch (value[0]) {
- case 'V': return levels.verbose;
- case 'D': return levels.debug;
- case 'I': return levels.info;
- case 'W': return levels.warn;
- case 'E': return levels.error;
- case 'A': return levels.assert;
- case 'S': return -1; // SUPPRESS
- }
- return levels.info;
-}
-
static jboolean isLoggable(const char* tag, jint level) {
- String8 key;
- key.append(LOG_NAMESPACE);
- key.append(tag);
-
- char buf[PROPERTY_VALUE_MAX];
- if (property_get(key.string(), buf, "") <= 0) {
- buf[0] = '\0';
- }
-
- int logLevel = toLevel(buf);
- return logLevel >= 0 && level >= logLevel;
+ return __android_log_is_loggable(level, tag, ANDROID_LOG_INFO);
}
static jboolean android_util_Log_isLoggable(JNIEnv* env, jobject clazz, jstring tag, jint level)
diff --git a/core/res/res/values-sw600dp/dimens.xml b/core/res/res/values-sw600dp/dimens.xml
index c0d9995..94e9c4e 100644
--- a/core/res/res/values-sw600dp/dimens.xml
+++ b/core/res/res/values-sw600dp/dimens.xml
@@ -115,4 +115,6 @@
<!-- width of ImmersiveModeConfirmation (-1 for match_parent) -->
<dimen name="immersive_mode_cling_width">380dp</dimen>
+
+ <dimen name="floating_toolbar_preferred_width">544dp</dimen>
</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index e7811df..7272ae3 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1271,11 +1271,6 @@
an mcc/mnc specific config.xml -->
<string name="mobile_provisioning_url" translatable="false"></string>
- <!-- This url is used as the default url when redirection is detected. Any
- should work as all url's get redirected. But maybe overridden by
- if needed. -->
- <string name="mobile_redirected_provisioning_url" translatable="false">http://google.com</string>
-
<!-- The default character set for GsmAlphabet -->
<!-- Empty string means MBCS is not considered -->
<string name="gsm_alphabet_default_charset" translatable="false"></string>
@@ -2196,6 +2191,9 @@
<!-- Keyguard component -->
<string name="config_keyguardComponent" translatable="false">com.android.systemui/com.android.systemui.keyguard.KeyguardService</string>
+ <!-- For performance and storage reasons, limit the number of fingerprints per user -->
+ <integer name="config_fingerprintMaxTemplatesPerUser">5</integer>
+
<!-- This config is used to force VoiceInteractionService to start on certain low ram devices.
It declares the package name of VoiceInteractionService that should be started. -->
<string translatable="false" name="config_forceVoiceInteractionServicePackage"></string>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 2908cc5..510f6a5 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -34,7 +34,7 @@
to display a size in kilobytes, megabytes, or other size units.
Some languages (like French) will want to add a space between
the placeholders. -->
- <string name="fileSizeSuffix"><xliff:g id="number" example="123">%1$s</xliff:g><xliff:g id="unit" example="KB">%2$s</xliff:g></string>
+ <string name="fileSizeSuffix"><xliff:g id="number" example="123">%1$s</xliff:g> <xliff:g id="unit" example="KB">%2$s</xliff:g></string>
<!-- [CHAR_LIMIT=10] Suffix added to signify duration in days -->
<string name="durationDays"><xliff:g id="days">%1$d</xliff:g> days</string>
@@ -1969,9 +1969,9 @@
<string name="lockscreen_access_pattern_start">Pattern started</string>
<!-- Accessibility description sent when the pattern times out and is cleared. [CHAR LIMIT=NONE] -->
<string name="lockscreen_access_pattern_cleared">Pattern cleared</string>
- <!-- Accessibility description sent when user adds a cell to the pattern. [CHAR LIMIT=NONE] -->
+ <!-- Accessibility description sent when user adds a dot to the pattern. [CHAR LIMIT=NONE] -->
<string name="lockscreen_access_pattern_cell_added">Cell added</string>
- <!-- Accessibility description sent when user adds a cell to the pattern. Announces the
+ <!-- Accessibility description sent when user adds a dot to the pattern. Announces the
actual cell when headphones are connected [CHAR LIMIT=NONE] -->
<string name="lockscreen_access_pattern_cell_added_verbose">
Cell <xliff:g id="cell_index" example="3">%1$s</xliff:g> added</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 45e5d17..5ba57c4 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -818,7 +818,6 @@
<java-symbol type="string" name="progress_unmounting" />
<java-symbol type="string" name="mobile_provisioning_apn" />
<java-symbol type="string" name="mobile_provisioning_url" />
- <java-symbol type="string" name="mobile_redirected_provisioning_url" />
<java-symbol type="string" name="quick_contacts_not_available" />
<java-symbol type="string" name="reboot_to_update_package" />
<java-symbol type="string" name="reboot_to_update_prepare" />
@@ -2125,6 +2124,9 @@
<java-symbol type="string" name="fingerprint_error_lockout" />
<java-symbol type="string" name="fingerprint_name_template" />
+ <!-- Fingerprint config -->
+ <java-symbol type="integer" name="config_fingerprintMaxTemplatesPerUser"/>
+
<!-- From various Material changes -->
<java-symbol type="attr" name="titleTextAppearance" />
<java-symbol type="attr" name="subtitleTextAppearance" />
@@ -2309,5 +2311,6 @@
<java-symbol type="string" name="ext_media_unsupported_notification_message" />
<java-symbol type="string" name="ext_media_unsupported_notification_title" />
<java-symbol type="plurals" name="selected_count" />
+ <java-symbol type="drawable" name="ic_dialog_alert_material" />
</resources>
diff --git a/core/tests/coretests/src/android/net/NetworkTest.java b/core/tests/coretests/src/android/net/NetworkTest.java
index b0ecb04..74b6d98 100644
--- a/core/tests/coretests/src/android/net/NetworkTest.java
+++ b/core/tests/coretests/src/android/net/NetworkTest.java
@@ -16,11 +16,14 @@
package android.net;
+import static android.test.MoreAsserts.assertNotEqual;
+
import android.net.LocalServerSocket;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.net.Network;
import android.test.suitebuilder.annotation.SmallTest;
+
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
@@ -29,6 +32,7 @@ import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Inet6Address;
import java.net.SocketException;
+
import junit.framework.TestCase;
public class NetworkTest extends TestCase {
@@ -93,4 +97,50 @@ public class NetworkTest extends TestCase {
fail("SocketException not thrown");
} catch (SocketException expected) {}
}
+
+ @SmallTest
+ public void testZeroIsObviousForDebugging() {
+ Network zero = new Network(0);
+ assertEquals(0, zero.hashCode());
+ assertEquals(0, zero.getNetworkHandle());
+ assertEquals("0", zero.toString());
+ }
+
+ @SmallTest
+ public void testGetNetworkHandle() {
+ Network one = new Network(1);
+ Network two = new Network(2);
+ Network three = new Network(3);
+
+ // None of the hashcodes are zero.
+ assertNotEqual(0, one.hashCode());
+ assertNotEqual(0, two.hashCode());
+ assertNotEqual(0, three.hashCode());
+
+ // All the hashcodes are distinct.
+ assertNotEqual(one.hashCode(), two.hashCode());
+ assertNotEqual(one.hashCode(), three.hashCode());
+ assertNotEqual(two.hashCode(), three.hashCode());
+
+ // None of the handles are zero.
+ assertNotEqual(0, one.getNetworkHandle());
+ assertNotEqual(0, two.getNetworkHandle());
+ assertNotEqual(0, three.getNetworkHandle());
+
+ // All the handles are distinct.
+ assertNotEqual(one.getNetworkHandle(), two.getNetworkHandle());
+ assertNotEqual(one.getNetworkHandle(), three.getNetworkHandle());
+ assertNotEqual(two.getNetworkHandle(), three.getNetworkHandle());
+
+ // The handles are not equal to the hashcodes.
+ assertNotEqual(one.hashCode(), one.getNetworkHandle());
+ assertNotEqual(two.hashCode(), two.getNetworkHandle());
+ assertNotEqual(three.hashCode(), three.getNetworkHandle());
+
+ // Adjust as necessary to test an implementation's specific constants.
+ // When running with runtest, "adb logcat -s TestRunner" can be useful.
+ assertEquals(4311403230L, one.getNetworkHandle());
+ assertEquals(8606370526L, two.getNetworkHandle());
+ assertEquals(12901337822L, three.getNetworkHandle());
+ }
}
diff --git a/docs/html/index.jd b/docs/html/index.jd
index 3989b92..cd129d4 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -26,9 +26,9 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3
<p class="dac-hero-description">Get your apps ready for the next version
of Android. Test on Nexus 5, 6, 9, and Player. </p>
- <a class="dac-hero-cta" href="{@docRoot}preview/index.html">
+ <a class="dac-hero-cta" href="{@docRoot}preview/overview.html">
<span class="dac-sprite dac-auto-chevron"></span>
- Learn more
+ Get started
</a>
</div>
</div>
diff --git a/docs/html/jd_collections.js b/docs/html/jd_collections.js
index 82836e2..86089e6 100644
--- a/docs/html/jd_collections.js
+++ b/docs/html/jd_collections.js
@@ -1594,7 +1594,8 @@ var RESOURCE_COLLECTIONS = {
"training/enterprise/app-restrictions.html",
"https://www.youtube.com/watch?v=39NkpWkaH8M&index=2&list=PLOU2XLYxmsIKAK2Bhv19H2THwF-22O5WX",
"samples/AppRestrictionSchema/index.html",
- "samples/AppRestrictionEnforcer/index.html"
+ "samples/AppRestrictionEnforcer/index.html",
+ "https://www.youtube.com/watch?v=dH41OutAMNM"
]
},
"training/work/admin": {
diff --git a/docs/html/preview/index.jd b/docs/html/preview/index.jd
index eb18aa6..68186bd 100644
--- a/docs/html/preview/index.jd
+++ b/docs/html/preview/index.jd
@@ -26,7 +26,7 @@ footer.hide=1
<a class="dac-hero-cta" href="{@docRoot}preview/overview.html">
<span class="dac-sprite dac-auto-chevron"></span>
- Get Started!
+ Get started
</a><br>
</div>
</div>
@@ -44,7 +44,7 @@ footer.hide=1
<div class="dac-section-subtitle">
Essential information to help you get your apps ready for Android M.
</div>
-
+
<div class="resource-widget resource-flow-layout col-16"
data-query="collection:preview/landing/more"
data-cardSizes="6x6"
@@ -56,7 +56,7 @@ footer.hide=1
<span class="dac-sprite dac-auto-chevron"></span>
Report Issues
</a>
- </li>
+ </li>
<li class="dac-section-link"><a href="http://g.co/dev/AndroidMDevPreview">
<span class="dac-sprite dac-auto-chevron"></span>
Join G+ Community
diff --git a/docs/html/training/tv/discovery/searchable.jd b/docs/html/training/tv/discovery/searchable.jd
index 27a1c33..4ca7abb 100644
--- a/docs/html/training/tv/discovery/searchable.jd
+++ b/docs/html/training/tv/discovery/searchable.jd
@@ -90,7 +90,7 @@ more important columns are described below.</p>
<td>The production year of your content <strong>(required)</strong></td>
</tr><tr>
<td>{@code SUGGEST_COLUMN_DURATION}</td>
- <td>The duration in milliseconds of your media</td>
+ <td>The duration in milliseconds of your media <strong>(required)</strong></td>
</tr>
</table>
@@ -99,6 +99,7 @@ more important columns are described below.</p>
<li>{@link android.app.SearchManager#SUGGEST_COLUMN_TEXT_1}</li>
<li>{@link android.app.SearchManager#SUGGEST_COLUMN_CONTENT_TYPE}</li>
<li>{@link android.app.SearchManager#SUGGEST_COLUMN_PRODUCTION_YEAR}</li>
+ <li>{@link android.app.SearchManager#SUGGEST_COLUMN_DURATION}</li>
</ul>
<p>When the values of these columns for your content match the values for the same content from other
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 82a592a..a0c407f 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -815,6 +815,9 @@ public class BitmapDrawable extends Drawable {
if (tileModeY != TILE_MODE_UNDEFINED) {
setTileModeY(parseTileMode(tileModeY));
}
+
+ final int densityDpi = r.getDisplayMetrics().densityDpi;
+ state.mTargetDensity = densityDpi == 0 ? DisplayMetrics.DENSITY_DEFAULT : densityDpi;
}
@Override
@@ -977,7 +980,8 @@ public class BitmapDrawable extends Drawable {
*/
private void updateLocalState(Resources res) {
if (res != null) {
- mTargetDensity = res.getDisplayMetrics().densityDpi;
+ final int densityDpi = res.getDisplayMetrics().densityDpi;
+ mTargetDensity = densityDpi == 0 ? DisplayMetrics.DENSITY_DEFAULT : densityDpi;
} else {
mTargetDensity = mBitmapState.mTargetDensity;
}
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 532c888..415af0d 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -1147,6 +1147,7 @@ public abstract class Drawable {
* document, tries to create a Drawable from that tag. Returns {@code null}
* if the tag is not a valid drawable.
*/
+ @SuppressWarnings("deprecation")
public static Drawable createFromXmlInner(Resources r, XmlPullParser parser, AttributeSet attrs,
Theme theme) throws XmlPullParserException, IOException {
final Drawable drawable;
@@ -1202,16 +1203,10 @@ public abstract class Drawable {
drawable = new InsetDrawable();
break;
case "bitmap":
- drawable = new BitmapDrawable(r);
- if (r != null) {
- ((BitmapDrawable) drawable).setTargetDensity(r.getDisplayMetrics());
- }
+ drawable = new BitmapDrawable();
break;
case "nine-patch":
drawable = new NinePatchDrawable();
- if (r != null) {
- ((NinePatchDrawable) drawable).setTargetDensity(r.getDisplayMetrics());
- }
break;
default:
throw new XmlPullParserException(parser.getPositionDescription() +
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index 91bbff7..0b7869b 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -482,6 +482,9 @@ public class NinePatchDrawable extends Drawable {
if (tint != null) {
state.mTint = tint;
}
+
+ final int densityDpi = r.getDisplayMetrics().densityDpi;
+ state.mTargetDensity = densityDpi == 0 ? DisplayMetrics.DENSITY_DEFAULT : densityDpi;
}
@Override
@@ -713,7 +716,8 @@ public class NinePatchDrawable extends Drawable {
final NinePatchState state = mNinePatchState;
if (res != null) {
- mTargetDensity = res.getDisplayMetrics().densityDpi;
+ final int densityDpi = res.getDisplayMetrics().densityDpi;
+ mTargetDensity = densityDpi == 0 ? DisplayMetrics.DENSITY_DEFAULT : densityDpi;
} else {
mTargetDensity = state.mTargetDensity;
}
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index 4c0631f..8d4bfcd 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -70,6 +70,8 @@ import javax.security.auth.x500.X500Principal;
* <p>NOTE: The key material of the generated symmetric and private keys is not accessible. The key
* material of the public keys is accessible.
*
+ * <p>Instances of this class are immutable.
+ *
* <p><h3>Example: Asymmetric key pair</h3>
* The following example illustrates how to generate an EC key pair in the Android KeyStore system
* under alias {@code key1} authorized to be used only for signing using SHA-256, SHA-384,
@@ -79,11 +81,12 @@ import javax.security.auth.x500.X500Principal;
* KeyProperties.KEY_ALGORITHM_EC,
* "AndroidKeyStore");
* keyPairGenerator.initialize(
- * new KeyGenParameterSpec.Builder("key1",
+ * new KeyGenParameterSpec.Builder(
+ * "key1",
* KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
- * .setDigests(KeyProperties.DIGEST_SHA256
- * | KeyProperties.DIGEST_SHA384
- * | KeyProperties.DIGEST_SHA512)
+ * .setDigests(KeyProperties.DIGEST_SHA256,
+ * KeyProperties.DIGEST_SHA384,
+ * KeyProperties.DIGEST_SHA512)
* // Only permit this key to be used if the user authenticated
* // within the last five minutes.
* .setUserAuthenticationRequired(true)
@@ -100,16 +103,17 @@ import javax.security.auth.x500.X500Principal;
*
* <p><h3>Example: Symmetric key</h3>
* The following example illustrates how to generate an AES key in the Android KeyStore system under
- * alias {@code key2} authorized to be used only for encryption/decryption in CTR mode.
+ * alias {@code key2} authorized to be used only for encryption/decryption in CBC mode with PKCS#7
+ * padding.
* <pre> {@code
* KeyGenerator keyGenerator = KeyGenerator.getInstance(
- * KeyProperties.KEY_ALGORITHM_HMAC_SHA256,
+ * KeyProperties.KEY_ALGORITHM_AES,
* "AndroidKeyStore");
* keyGenerator.initialize(
* new KeyGenParameterSpec.Builder("key2",
* KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
- * .setBlockModes(KeyProperties.BLOCK_MODE_CTR)
- * .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+ * .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
+ * .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
* .build());
* SecretKey key = keyGenerator.generateKey();
*
@@ -169,10 +173,6 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
int userAuthenticationValidityDurationSeconds) {
if (TextUtils.isEmpty(keyStoreAlias)) {
throw new IllegalArgumentException("keyStoreAlias must not be empty");
- } else if ((userAuthenticationValidityDurationSeconds < 0)
- && (userAuthenticationValidityDurationSeconds != -1)) {
- throw new IllegalArgumentException(
- "userAuthenticationValidityDurationSeconds must not be negative");
}
if (certificateSubject == null) {
@@ -197,11 +197,11 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
mSpec = spec;
mCertificateSubject = certificateSubject;
mCertificateSerialNumber = certificateSerialNumber;
- mCertificateNotBefore = certificateNotBefore;
- mCertificateNotAfter = certificateNotAfter;
- mKeyValidityStart = keyValidityStart;
- mKeyValidityForOriginationEnd = keyValidityForOriginationEnd;
- mKeyValidityForConsumptionEnd = keyValidityForConsumptionEnd;
+ mCertificateNotBefore = Utils.cloneIfNotNull(certificateNotBefore);
+ mCertificateNotAfter = Utils.cloneIfNotNull(certificateNotAfter);
+ mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart);
+ mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd);
+ mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd);
mPurposes = purposes;
mDigests = ArrayUtils.cloneIfNotEmpty(digests);
mEncryptionPaddings =
@@ -217,6 +217,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
* Returns the alias that will be used in the {@code java.security.KeyStore}
* in conjunction with the {@code AndroidKeyStore}.
*/
+ @NonNull
public String getKeystoreAlias() {
return mKeystoreAlias;
}
@@ -231,10 +232,10 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
}
/**
- * Returns the {@link AlgorithmParameterSpec} that will be used for creation
- * of the key pair.
+ * Returns the key algorithm-specific {@link AlgorithmParameterSpec} that will be used for
+ * creation of the key or {@code null} if algorithm-specific defaults should be used.
*/
- @NonNull
+ @Nullable
public AlgorithmParameterSpec getAlgorithmParameterSpec() {
return mSpec;
}
@@ -263,7 +264,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
*/
@NonNull
public Date getCertificateNotBefore() {
- return mCertificateNotBefore;
+ return Utils.cloneIfNotNull(mCertificateNotBefore);
}
/**
@@ -272,7 +273,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
*/
@NonNull
public Date getCertificateNotAfter() {
- return mCertificateNotAfter;
+ return Utils.cloneIfNotNull(mCertificateNotAfter);
}
/**
@@ -281,7 +282,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
*/
@Nullable
public Date getKeyValidityStart() {
- return mKeyValidityStart;
+ return Utils.cloneIfNotNull(mKeyValidityStart);
}
/**
@@ -290,7 +291,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
*/
@Nullable
public Date getKeyValidityForConsumptionEnd() {
- return mKeyValidityForConsumptionEnd;
+ return Utils.cloneIfNotNull(mKeyValidityForConsumptionEnd);
}
/**
@@ -299,7 +300,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
*/
@Nullable
public Date getKeyValidityForOriginationEnd() {
- return mKeyValidityForOriginationEnd;
+ return Utils.cloneIfNotNull(mKeyValidityForOriginationEnd);
}
/**
@@ -411,7 +412,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
* restricted.
*
* @return duration in seconds or {@code -1} if authentication is required for every use of the
- * key.
+ * key.
*
* @see #isUserAuthenticationRequired()
*/
@@ -447,7 +448,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
* Creates a new instance of the {@code Builder}.
*
* @param keystoreAlias alias of the entry in which the generated key will appear in
- * Android KeyStore.
+ * Android KeyStore. Must not be empty.
* @param purposes set of purposes (e.g., encrypt, decrypt, sign) for which the key can be
* used. Attempts to use the key for any other purpose will be rejected.
*
@@ -462,6 +463,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
public Builder(@NonNull String keystoreAlias, @KeyProperties.PurposeEnum int purposes) {
if (keystoreAlias == null) {
throw new NullPointerException("keystoreAlias == null");
+ } else if (keystoreAlias.isEmpty()) {
+ throw new IllegalArgumentException("keystoreAlias must not be empty");
}
mKeystoreAlias = keystoreAlias;
mPurposes = purposes;
@@ -488,7 +491,11 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
/**
* Sets the algorithm-specific key generation parameters. For example, for RSA keys this may
- * be an instance of {@link java.security.spec.RSAKeyGenParameterSpec}.
+ * be an instance of {@link java.security.spec.RSAKeyGenParameterSpec} whereas for EC keys
+ * this may be an instance of {@link java.security.spec.ECGenParameterSpec}.
+ *
+ * <p>These key generation parameters must match other explicitly set parameters (if any),
+ * such as key size.
*/
public Builder setAlgorithmParameterSpec(@NonNull AlgorithmParameterSpec spec) {
if (spec == null) {
@@ -537,7 +544,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
if (date == null) {
throw new NullPointerException("date == null");
}
- mCertificateNotBefore = date;
+ mCertificateNotBefore = Utils.cloneIfNotNull(date);
return this;
}
@@ -552,7 +559,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
if (date == null) {
throw new NullPointerException("date == null");
}
- mCertificateNotAfter = date;
+ mCertificateNotAfter = Utils.cloneIfNotNull(date);
return this;
}
@@ -565,7 +572,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
*/
@NonNull
public Builder setKeyValidityStart(Date startDate) {
- mKeyValidityStart = startDate;
+ mKeyValidityStart = Utils.cloneIfNotNull(startDate);
return this;
}
@@ -594,7 +601,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
*/
@NonNull
public Builder setKeyValidityForOriginationEnd(Date endDate) {
- mKeyValidityForOriginationEnd = endDate;
+ mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(endDate);
return this;
}
@@ -608,7 +615,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
*/
@NonNull
public Builder setKeyValidityForConsumptionEnd(Date endDate) {
- mKeyValidityForConsumptionEnd = endDate;
+ mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(endDate);
return this;
}
@@ -768,14 +775,15 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
@NonNull
public Builder setUserAuthenticationValidityDurationSeconds(
@IntRange(from = -1) int seconds) {
+ if (seconds < -1) {
+ throw new IllegalArgumentException("seconds must be -1 or larger");
+ }
mUserAuthenticationValidityDurationSeconds = seconds;
return this;
}
/**
* Builds an instance of {@code KeyGenParameterSpec}.
- *
- * @throws IllegalArgumentException if a required field is missing
*/
@NonNull
public KeyGenParameterSpec build() {
diff --git a/keystore/java/android/security/keystore/KeyInfo.java b/keystore/java/android/security/keystore/KeyInfo.java
index e4f921e..03b4100 100644
--- a/keystore/java/android/security/keystore/KeyInfo.java
+++ b/keystore/java/android/security/keystore/KeyInfo.java
@@ -33,6 +33,8 @@ import javax.crypto.SecretKey;
* is authorized for (e.g., only in {@code CBC} mode, or signing only), whether the key should be
* encrypted at rest, the key's and validity start and end dates.
*
+ * <p>Instances of this class are immutable.
+ *
* <p><h3>Example: Symmetric Key</h3>
* The following example illustrates how to obtain a {@code KeyInfo} describing the provided Android
* Keystore {@link SecretKey}.
@@ -102,9 +104,9 @@ public class KeyInfo implements KeySpec {
mInsideSecureHardware = insideSecureHardware;
mOrigin = origin;
mKeySize = keySize;
- mKeyValidityStart = keyValidityStart;
- mKeyValidityForOriginationEnd = keyValidityForOriginationEnd;
- mKeyValidityForConsumptionEnd = keyValidityForConsumptionEnd;
+ mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart);
+ mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd);
+ mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd);
mPurposes = purposes;
mEncryptionPaddings =
ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings));
@@ -155,7 +157,7 @@ public class KeyInfo implements KeySpec {
*/
@Nullable
public Date getKeyValidityStart() {
- return mKeyValidityStart;
+ return Utils.cloneIfNotNull(mKeyValidityStart);
}
/**
@@ -165,7 +167,7 @@ public class KeyInfo implements KeySpec {
*/
@Nullable
public Date getKeyValidityForConsumptionEnd() {
- return mKeyValidityForConsumptionEnd;
+ return Utils.cloneIfNotNull(mKeyValidityForConsumptionEnd);
}
/**
@@ -175,7 +177,7 @@ public class KeyInfo implements KeySpec {
*/
@Nullable
public Date getKeyValidityForOriginationEnd() {
- return mKeyValidityForOriginationEnd;
+ return Utils.cloneIfNotNull(mKeyValidityForOriginationEnd);
}
/**
diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java
index 432fc12..1e0611c 100644
--- a/keystore/java/android/security/keystore/KeyProtection.java
+++ b/keystore/java/android/security/keystore/KeyProtection.java
@@ -47,6 +47,8 @@ import javax.crypto.Cipher;
*
* <p>NOTE: The key material of keys stored in the Android KeyStore is not accessible.
*
+ * <p>Instances of this class are immutable.
+ *
* <p><h3>Example: Symmetric Key</h3>
* The following example illustrates how to import an AES key into the Android KeyStore under alias
* {@code key1} authorized to be used only for encryption/decryption in CBC mode with PKCS#7
@@ -122,15 +124,9 @@ public final class KeyProtection implements ProtectionParameter {
boolean randomizedEncryptionRequired,
boolean userAuthenticationRequired,
int userAuthenticationValidityDurationSeconds) {
- if ((userAuthenticationValidityDurationSeconds < 0)
- && (userAuthenticationValidityDurationSeconds != -1)) {
- throw new IllegalArgumentException(
- "userAuthenticationValidityDurationSeconds must not be negative");
- }
-
- mKeyValidityStart = keyValidityStart;
- mKeyValidityForOriginationEnd = keyValidityForOriginationEnd;
- mKeyValidityForConsumptionEnd = keyValidityForConsumptionEnd;
+ mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart);
+ mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd);
+ mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd);
mPurposes = purposes;
mEncryptionPaddings =
ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings));
@@ -150,7 +146,7 @@ public final class KeyProtection implements ProtectionParameter {
*/
@Nullable
public Date getKeyValidityStart() {
- return mKeyValidityStart;
+ return Utils.cloneIfNotNull(mKeyValidityStart);
}
/**
@@ -160,7 +156,7 @@ public final class KeyProtection implements ProtectionParameter {
*/
@Nullable
public Date getKeyValidityForConsumptionEnd() {
- return mKeyValidityForConsumptionEnd;
+ return Utils.cloneIfNotNull(mKeyValidityForConsumptionEnd);
}
/**
@@ -170,7 +166,7 @@ public final class KeyProtection implements ProtectionParameter {
*/
@Nullable
public Date getKeyValidityForOriginationEnd() {
- return mKeyValidityForOriginationEnd;
+ return Utils.cloneIfNotNull(mKeyValidityForOriginationEnd);
}
/**
@@ -320,7 +316,7 @@ public final class KeyProtection implements ProtectionParameter {
*/
@NonNull
public Builder setKeyValidityStart(Date startDate) {
- mKeyValidityStart = startDate;
+ mKeyValidityStart = Utils.cloneIfNotNull(startDate);
return this;
}
@@ -349,7 +345,7 @@ public final class KeyProtection implements ProtectionParameter {
*/
@NonNull
public Builder setKeyValidityForOriginationEnd(Date endDate) {
- mKeyValidityForOriginationEnd = endDate;
+ mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(endDate);
return this;
}
@@ -363,7 +359,7 @@ public final class KeyProtection implements ProtectionParameter {
*/
@NonNull
public Builder setKeyValidityForConsumptionEnd(Date endDate) {
- mKeyValidityForConsumptionEnd = endDate;
+ mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(endDate);
return this;
}
@@ -517,6 +513,9 @@ public final class KeyProtection implements ProtectionParameter {
@NonNull
public Builder setUserAuthenticationValidityDurationSeconds(
@IntRange(from = -1) int seconds) {
+ if (seconds < -1) {
+ throw new IllegalArgumentException("seconds must be -1 or larger");
+ }
mUserAuthenticationValidityDurationSeconds = seconds;
return this;
}
diff --git a/keystore/java/android/security/keystore/Utils.java b/keystore/java/android/security/keystore/Utils.java
new file mode 100644
index 0000000..9bec682
--- /dev/null
+++ b/keystore/java/android/security/keystore/Utils.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2015 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.security.keystore;
+
+import java.util.Date;
+
+/**
+ * Assorted utility methods.
+ *
+ * @hide
+ */
+abstract class Utils {
+ private Utils() {}
+
+ static Date cloneIfNotNull(Date value) {
+ return (value != null) ? (Date) value.clone() : null;
+ }
+}
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index b4cbc36..fc18491 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -241,8 +241,12 @@ void RenderNode::prepareTreeImpl(TreeInfo& info, bool functorsNeedLayer) {
animatorDirtyMask = mAnimatorManager.animate(info);
}
- bool willHaveFunctor = info.mode == TreeInfo::MODE_FULL && mStagingDisplayListData
- ? !mStagingDisplayListData->functors.isEmpty() : !mDisplayListData->functors.isEmpty();
+ bool willHaveFunctor = false;
+ if (info.mode == TreeInfo::MODE_FULL && mStagingDisplayListData) {
+ willHaveFunctor = !mStagingDisplayListData->functors.isEmpty();
+ } else if (mDisplayListData) {
+ willHaveFunctor = !mDisplayListData->functors.isEmpty();
+ }
bool childFunctorsNeedLayer = mProperties.prepareForFunctorPresence(
willHaveFunctor, functorsNeedLayer);
diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java
index 431d37e..173d349 100644
--- a/media/java/android/media/AudioDeviceInfo.java
+++ b/media/java/android/media/AudioDeviceInfo.java
@@ -173,8 +173,7 @@ public final class AudioDeviceInfo {
* @see AudioFormat
*/
public @NonNull int[] getChannelIndexMasks() {
- // TODO: implement
- return new int[0];
+ return mPort.channelIndexMasks();
}
/**
diff --git a/media/java/android/media/AudioDevicePort.java b/media/java/android/media/AudioDevicePort.java
index c078260..aea39a3 100644
--- a/media/java/android/media/AudioDevicePort.java
+++ b/media/java/android/media/AudioDevicePort.java
@@ -37,12 +37,12 @@ public class AudioDevicePort extends AudioPort {
private final String mAddress;
AudioDevicePort(AudioHandle handle, String deviceName,
- int[] samplingRates, int[] channelMasks,
+ int[] samplingRates, int[] channelMasks, int[] channelIndexMasks,
int[] formats, AudioGain[] gains, int type, String address) {
super(handle,
(AudioManager.isInputDevice(type) == true) ?
AudioPort.ROLE_SOURCE : AudioPort.ROLE_SINK,
- deviceName, samplingRates, channelMasks, formats, gains);
+ deviceName, samplingRates, channelMasks, channelIndexMasks, formats, gains);
mType = type;
mAddress = address;
}
diff --git a/media/java/android/media/AudioMixPort.java b/media/java/android/media/AudioMixPort.java
index ab55c8d..ba144bf 100644
--- a/media/java/android/media/AudioMixPort.java
+++ b/media/java/android/media/AudioMixPort.java
@@ -31,9 +31,10 @@ public class AudioMixPort extends AudioPort {
private final int mIoHandle;
AudioMixPort(AudioHandle handle, int ioHandle, int role, String deviceName,
- int[] samplingRates, int[] channelMasks,
+ int[] samplingRates, int[] channelMasks, int[] channelIndexMasks,
int[] formats, AudioGain[] gains) {
- super(handle, role, deviceName, samplingRates, channelMasks, formats, gains);
+ super(handle, role, deviceName, samplingRates, channelMasks, channelIndexMasks,
+ formats, gains);
mIoHandle = ioHandle;
}
diff --git a/media/java/android/media/AudioPort.java b/media/java/android/media/AudioPort.java
index 7328d7a..19bf51d 100644
--- a/media/java/android/media/AudioPort.java
+++ b/media/java/android/media/AudioPort.java
@@ -71,12 +71,13 @@ public class AudioPort {
private final String mName;
private final int[] mSamplingRates;
private final int[] mChannelMasks;
+ private final int[] mChannelIndexMasks;
private final int[] mFormats;
private final AudioGain[] mGains;
private AudioPortConfig mActiveConfig;
AudioPort(AudioHandle handle, int role, String name,
- int[] samplingRates, int[] channelMasks,
+ int[] samplingRates, int[] channelMasks, int[] channelIndexMasks,
int[] formats, AudioGain[] gains) {
mHandle = handle;
@@ -84,6 +85,7 @@ public class AudioPort {
mName = name;
mSamplingRates = samplingRates;
mChannelMasks = channelMasks;
+ mChannelIndexMasks = channelIndexMasks;
mFormats = formats;
mGains = gains;
}
@@ -133,6 +135,15 @@ public class AudioPort {
}
/**
+ * Get the list of supported channel index mask configurations
+ * (e.g 0x0003 means 2 channel, 0x000F means 4 channel....)
+ * Empty array if channel index mask is not relevant for this audio port
+ */
+ public int[] channelIndexMasks() {
+ return mChannelIndexMasks;
+ }
+
+ /**
* Get the list of supported audio format configurations
* (e.g AudioFormat.ENCODING_PCM_16BIT)
* Empty array if format is not relevant for this audio port
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index 73a723d..4143e15 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -120,13 +120,20 @@ public class ExternalStorageProvider extends DocumentsProvider {
if (!volume.isMountedReadable()) continue;
final String rootId;
- if (VolumeInfo.ID_EMULATED_INTERNAL.equals(volume.getId())) {
+ final String title;
+ if (volume.getType() == VolumeInfo.TYPE_EMULATED) {
+ // We currently only support a single emulated volume mounted at
+ // a time, and it's always considered the primary
rootId = ROOT_ID_PRIMARY_EMULATED;
- } else if (volume.getType() == VolumeInfo.TYPE_EMULATED) {
- final VolumeInfo privateVol = mStorageManager.findPrivateForEmulated(volume);
- rootId = privateVol.getFsUuid();
+ if (VolumeInfo.ID_EMULATED_INTERNAL.equals(volume.getId())) {
+ title = getContext().getString(R.string.root_internal_storage);
+ } else {
+ final VolumeInfo privateVol = mStorageManager.findPrivateForEmulated(volume);
+ title = mStorageManager.getBestVolumeDescription(privateVol);
+ }
} else if (volume.getType() == VolumeInfo.TYPE_PUBLIC) {
rootId = volume.getFsUuid();
+ title = mStorageManager.getBestVolumeDescription(volume);
} else {
// Unsupported volume; ignore
continue;
@@ -148,11 +155,7 @@ public class ExternalStorageProvider extends DocumentsProvider {
root.rootId = rootId;
root.flags = Root.FLAG_SUPPORTS_CREATE | Root.FLAG_LOCAL_ONLY | Root.FLAG_ADVANCED
| Root.FLAG_SUPPORTS_SEARCH | Root.FLAG_SUPPORTS_IS_CHILD;
- if (ROOT_ID_PRIMARY_EMULATED.equals(rootId)) {
- root.title = getContext().getString(R.string.root_internal_storage);
- } else {
- root.title = mStorageManager.getBestVolumeDescription(volume);
- }
+ root.title = title;
if (volume.getType() == VolumeInfo.TYPE_PUBLIC) {
root.flags |= Root.FLAG_HAS_SETTINGS;
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 7bf2223..5a14967 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -2682,9 +2682,6 @@ class DatabaseHelper extends SQLiteOpenHelper {
// Set default cdma call auto retry
loadSetting(stmt, Settings.Global.CALL_AUTO_RETRY, 0);
- // Set default simplified carrier network settings to 0
- loadSetting(stmt, Settings.Global.HIDE_CARRIER_NETWORK_SETTINGS, 0);
-
// Set the preferred network mode to target desired value or Default
// value defined in RILConstants
int type;
diff --git a/packages/Shell/src/com/android/shell/BugreportReceiver.java b/packages/Shell/src/com/android/shell/BugreportReceiver.java
index e1bfc43..13747ed 100644
--- a/packages/Shell/src/com/android/shell/BugreportReceiver.java
+++ b/packages/Shell/src/com/android/shell/BugreportReceiver.java
@@ -33,11 +33,23 @@ import android.os.FileUtils;
import android.os.SystemProperties;
import android.support.v4.content.FileProvider;
import android.text.format.DateUtils;
+import android.util.Log;
import android.util.Patterns;
import com.google.android.collect.Lists;
+import libcore.io.Streams;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
import java.util.ArrayList;
/**
@@ -73,30 +85,14 @@ public class BugreportReceiver extends BroadcastReceiver {
final Uri bugreportUri = FileProvider.getUriForFile(context, AUTHORITY, bugreportFile);
final Uri screenshotUri = FileProvider.getUriForFile(context, AUTHORITY, screenshotFile);
- Intent sendIntent = buildSendIntent(context, bugreportUri, screenshotUri);
- Intent notifIntent;
-
- // Send through warning dialog by default
- if (getWarningState(context, STATE_SHOW) == STATE_SHOW) {
- notifIntent = buildWarningIntent(context, sendIntent);
+ boolean isPlainText = bugreportFile.getName().toLowerCase().endsWith(".txt");
+ if (!isPlainText) {
+ // Already zipped, send it right away.
+ sendBugreportNotification(context, bugreportFile, screenshotFile);
} else {
- notifIntent = sendIntent;
+ // Asynchronously zip the file first, then send it.
+ sendZippedBugreportNotification(context, bugreportFile, screenshotFile);
}
- notifIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
- final Notification.Builder builder = new Notification.Builder(context)
- .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
- .setContentTitle(context.getString(R.string.bugreport_finished_title))
- .setTicker(context.getString(R.string.bugreport_finished_title))
- .setContentText(context.getString(R.string.bugreport_finished_text))
- .setContentIntent(PendingIntent.getActivity(
- context, 0, notifIntent, PendingIntent.FLAG_CANCEL_CURRENT))
- .setAutoCancel(true)
- .setLocalOnly(true)
- .setColor(context.getColor(
- com.android.internal.R.color.system_notification_accent_color));
-
- NotificationManager.from(context).notify(TAG, 0, builder.build());
// Clean up older bugreports in background
final PendingResult result = goAsync();
@@ -141,6 +137,88 @@ public class BugreportReceiver extends BroadcastReceiver {
}
/**
+ * Sends a bugreport notitication.
+ */
+ private static void sendBugreportNotification(Context context, File bugreportFile,
+ File screenshotFile) {
+ // Files are kept on private storage, so turn into Uris that we can
+ // grant temporary permissions for.
+ final Uri bugreportUri = FileProvider.getUriForFile(context, AUTHORITY, bugreportFile);
+ final Uri screenshotUri = FileProvider.getUriForFile(context, AUTHORITY, screenshotFile);
+
+ Intent sendIntent = buildSendIntent(context, bugreportUri, screenshotUri);
+ Intent notifIntent;
+
+ // Send through warning dialog by default
+ if (getWarningState(context, STATE_SHOW) == STATE_SHOW) {
+ notifIntent = buildWarningIntent(context, sendIntent);
+ } else {
+ notifIntent = sendIntent;
+ }
+ notifIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ final Notification.Builder builder = new Notification.Builder(context)
+ .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
+ .setContentTitle(context.getString(R.string.bugreport_finished_title))
+ .setTicker(context.getString(R.string.bugreport_finished_title))
+ .setContentText(context.getString(R.string.bugreport_finished_text))
+ .setContentIntent(PendingIntent.getActivity(
+ context, 0, notifIntent, PendingIntent.FLAG_CANCEL_CURRENT))
+ .setAutoCancel(true)
+ .setLocalOnly(true)
+ .setColor(context.getColor(
+ com.android.internal.R.color.system_notification_accent_color));
+
+ NotificationManager.from(context).notify(TAG, 0, builder.build());
+ }
+
+ /**
+ * Sends a zipped bugreport notification.
+ */
+ private static void sendZippedBugreportNotification(final Context context,
+ final File bugreportFile, final File screenshotFile) {
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ File zippedFile = zipBugreport(bugreportFile);
+ sendBugreportNotification(context, zippedFile, screenshotFile);
+ return null;
+ }
+ }.execute();
+ }
+
+ /**
+ * Zips a bugreport file, returning the path to the new file (or to the
+ * original in case of failure).
+ */
+ private static File zipBugreport(File bugreportFile) {
+ String bugreportPath = bugreportFile.getAbsolutePath();
+ String zippedPath = bugreportPath.replace(".txt", ".zip");
+ Log.v(TAG, "zipping " + bugreportPath + " as " + zippedPath);
+ File bugreportZippedFile = new File(zippedPath);
+ try (InputStream is = new FileInputStream(bugreportFile);
+ ZipOutputStream zos = new ZipOutputStream(
+ new BufferedOutputStream(new FileOutputStream(bugreportZippedFile)))) {
+ ZipEntry entry = new ZipEntry("bugreport.txt");
+ zos.putNextEntry(entry);
+ int totalBytes = Streams.copy(is, zos);
+ Log.v(TAG, "size of original bugreport: " + totalBytes + " bytes");
+ zos.closeEntry();
+ // Delete old file;
+ boolean deleted = bugreportFile.delete();
+ if (deleted) {
+ Log.v(TAG, "deleted original bugreport (" + bugreportPath + ")");
+ } else {
+ Log.e(TAG, "could not delete original bugreport (" + bugreportPath + ")");
+ }
+ return bugreportZippedFile;
+ } catch (IOException e) {
+ Log.e(TAG, "exception zipping file " + zippedPath, e);
+ return bugreportFile; // Return original.
+ }
+ }
+
+ /**
* Find the best matching {@link Account} based on build properties.
*/
private static Account findSendToAccount(Context context) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index e3b1b9f..5ac436a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1180,7 +1180,9 @@ public class NotificationPanelView extends PanelView implements
} else if (statusBarState == StatusBarState.KEYGUARD
|| statusBarState == StatusBarState.SHADE_LOCKED) {
mKeyguardBottomArea.animate().cancel();
- mKeyguardBottomArea.setVisibility(View.VISIBLE);
+ if (!mDozing) {
+ mKeyguardBottomArea.setVisibility(View.VISIBLE);
+ }
mKeyguardBottomArea.setAlpha(1f);
} else {
mKeyguardBottomArea.animate().cancel();
@@ -1717,7 +1719,8 @@ public class NotificationPanelView extends PanelView implements
float alphaQsExpansion = 1 - Math.min(1, getQsExpansionFraction() * 2);
mKeyguardStatusBar.setAlpha(Math.min(getKeyguardContentsAlpha(), alphaQsExpansion)
* mKeyguardStatusBarAnimateAlpha);
- mKeyguardStatusBar.setVisibility(mKeyguardStatusBar.getAlpha() != 0f ? VISIBLE : INVISIBLE);
+ mKeyguardStatusBar.setVisibility(mKeyguardStatusBar.getAlpha() != 0f
+ && !mDozing ? VISIBLE : INVISIBLE);
setQsTranslation(mQsExpansionHeight);
}
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index 05ee9c2..d360875 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -53,6 +53,7 @@ public class StorageNotification extends SystemUI {
private static final int MOVE_ID = 0x534d4f56; // SMOV
private static final String ACTION_SNOOZE_VOLUME = "com.android.systemui.action.SNOOZE_VOLUME";
+ private static final String ACTION_FINISH_WIZARD = "com.android.systemui.action.FINISH_WIZARD";
// TODO: delay some notifications to avoid bumpy fast operations
@@ -107,6 +108,15 @@ public class StorageNotification extends SystemUI {
}
};
+ private final BroadcastReceiver mFinishReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // When finishing the adoption wizard, clean up any notifications
+ // for moving primary storage
+ mNotificationManager.cancelAsUser(null, MOVE_ID, UserHandle.ALL);
+ }
+ };
+
private final MoveCallback mMoveCallback = new MoveCallback() {
@Override
public void onCreated(int moveId, Bundle extras) {
@@ -146,6 +156,8 @@ public class StorageNotification extends SystemUI {
mContext.registerReceiver(mSnoozeReceiver, new IntentFilter(ACTION_SNOOZE_VOLUME),
android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
+ mContext.registerReceiver(mFinishReceiver, new IntentFilter(ACTION_FINISH_WIZARD),
+ android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
// Kick current state into place
final List<DiskInfo> disks = mStorageManager.getDisks();
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index f645764..82399da 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -960,44 +960,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
return nai != null ? nai.network : null;
}
- /**
- * Find the first Provisioning network.
- *
- * @return NetworkInfo or null if none.
- */
- private NetworkInfo getProvisioningNetworkInfo() {
- enforceAccessPermission();
-
- // Find the first Provisioning Network
- NetworkInfo provNi = null;
- for (NetworkInfo ni : getAllNetworkInfo()) {
- if (ni.isConnectedToProvisioningNetwork()) {
- provNi = ni;
- break;
- }
- }
- if (DBG) log("getProvisioningNetworkInfo: X provNi=" + provNi);
- return provNi;
- }
-
- /**
- * Find the first Provisioning network or the ActiveDefaultNetwork
- * if there is no Provisioning network
- *
- * @return NetworkInfo or null if none.
- */
- @Override
- public NetworkInfo getProvisioningOrActiveNetworkInfo() {
- enforceAccessPermission();
-
- NetworkInfo provNi = getProvisioningNetworkInfo();
- if (provNi == null) {
- provNi = getActiveNetworkInfo();
- }
- if (DBG) log("getProvisioningOrActiveNetworkInfo: X provNi=" + provNi);
- return provNi;
- }
-
public NetworkInfo getActiveNetworkInfoUnfiltered() {
enforceAccessPermission();
final int uid = Binder.getCallingUid();
@@ -1567,14 +1529,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
};
- /** @hide */
- @Override
- public void captivePortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) {
- enforceConnectivityInternalPermission();
- if (DBG) log("captivePortalCheckCompleted: ni=" + info + " captive=" + isCaptivePortal);
-// mNetTrackers[info.getType()].captivePortalCheckCompleted(isCaptivePortal);
- }
-
/**
* Setup data activity tracking for the given network.
*
@@ -3357,7 +3311,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
* <?xml version="1.0" encoding="utf-8"?>
* <provisioningUrls>
* <provisioningUrl mcc="310" mnc="4">http://myserver.com/foo?mdn=%3$s&amp;iccid=%1$s&amp;imei=%2$s</provisioningUrl>
- * <redirectedUrl mcc="310" mnc="4">http://www.google.com</redirectedUrl>
* </provisioningUrls>
*/
private static final String PROVISIONING_URL_PATH =
@@ -3368,33 +3321,15 @@ public class ConnectivityService extends IConnectivityManager.Stub
private static final String TAG_PROVISIONING_URLS = "provisioningUrls";
/** XML tag for individual url */
private static final String TAG_PROVISIONING_URL = "provisioningUrl";
- /** XML tag for redirected url */
- private static final String TAG_REDIRECTED_URL = "redirectedUrl";
/** XML attribute for mcc */
private static final String ATTR_MCC = "mcc";
/** XML attribute for mnc */
private static final String ATTR_MNC = "mnc";
- private static final int REDIRECTED_PROVISIONING = 1;
- private static final int PROVISIONING = 2;
-
- private String getProvisioningUrlBaseFromFile(int type) {
+ private String getProvisioningUrlBaseFromFile() {
FileReader fileReader = null;
XmlPullParser parser = null;
Configuration config = mContext.getResources().getConfiguration();
- String tagType;
-
- switch (type) {
- case PROVISIONING:
- tagType = TAG_PROVISIONING_URL;
- break;
- case REDIRECTED_PROVISIONING:
- tagType = TAG_REDIRECTED_URL;
- break;
- default:
- throw new RuntimeException("getProvisioningUrlBaseFromFile: Unexpected parameter " +
- type);
- }
try {
fileReader = new FileReader(mProvisioningUrlFile);
@@ -3408,7 +3343,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
String element = parser.getName();
if (element == null) break;
- if (element.equals(tagType)) {
+ if (element.equals(TAG_PROVISIONING_URL)) {
String mcc = parser.getAttributeValue(null, ATTR_MCC);
try {
if (mcc != null && Integer.parseInt(mcc) == config.mcc) {
@@ -3443,19 +3378,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
@Override
- public String getMobileRedirectedProvisioningUrl() {
- enforceConnectivityInternalPermission();
- String url = getProvisioningUrlBaseFromFile(REDIRECTED_PROVISIONING);
- if (TextUtils.isEmpty(url)) {
- url = mContext.getResources().getString(R.string.mobile_redirected_provisioning_url);
- }
- return url;
- }
-
- @Override
public String getMobileProvisioningUrl() {
enforceConnectivityInternalPermission();
- String url = getProvisioningUrlBaseFromFile(PROVISIONING);
+ String url = getProvisioningUrlBaseFromFile();
if (TextUtils.isEmpty(url)) {
url = mContext.getResources().getString(R.string.mobile_provisioning_url);
log("getMobileProvisioningUrl: mobile_provisioining_url from resource =" + url);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e9b9767..667abb6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -31,7 +31,6 @@ import static com.android.server.am.ActivityManagerDebugConfig.*;
import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
-import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE;
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
@@ -10338,11 +10337,12 @@ public final class ActivityManagerService extends ActivityManagerNative
void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
- if (mRunningVoice == null) {
+ boolean wasRunningVoice = mRunningVoice != null;
+ mRunningVoice = session;
+ if (!wasRunningVoice) {
mVoiceWakeLock.acquire();
updateSleepIfNeededLocked();
}
- mRunningVoice = session;
}
}
@@ -11495,7 +11495,7 @@ public final class ActivityManagerService extends ActivityManagerNative
for (int i=0; i<ris.size(); i++) {
ActivityInfo ai = ris.get(i).activityInfo;
ComponentName comp = new ComponentName(ai.packageName, ai.name);
- if (false && lastDoneReceivers.contains(comp)) {
+ if (lastDoneReceivers.contains(comp)) {
// We already did the pre boot receiver for this app with the current
// platform version, so don't do it again...
ris.remove(i);
@@ -18595,29 +18595,24 @@ public final class ActivityManagerService extends ActivityManagerNative
return;
}
boolean isInteraction;
- if (!mSleeping) {
- isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+ // To avoid some abuse patterns, we are going to be careful about what we consider
+ // to be an app interaction. Being the top activity doesn't count while the display
+ // is sleeping, nor do short foreground services.
+ if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
+ isInteraction = true;
app.fgInteractionTime = 0;
- } else {
- // If the display is off, we are going to be more restrictive about what we consider
- // to be an app interaction. Being the top activity doesn't count, nor do generally
- // foreground services.
- if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
- isInteraction = true;
- app.fgInteractionTime = 0;
- } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
- final long now = SystemClock.elapsedRealtime();
- if (app.fgInteractionTime == 0) {
- app.fgInteractionTime = now;
- isInteraction = false;
- } else {
- isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
- }
+ } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
+ final long now = SystemClock.elapsedRealtime();
+ if (app.fgInteractionTime == 0) {
+ app.fgInteractionTime = now;
+ isInteraction = false;
} else {
- isInteraction = app.curProcState
- <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
- app.fgInteractionTime = 0;
+ isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
}
+ } else {
+ isInteraction = app.curProcState
+ <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+ app.fgInteractionTime = 0;
}
if (isInteraction && !app.reportedInteraction) {
String[] packages = app.getPackageList();
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index f222dba..2eb8797 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -801,7 +801,7 @@ public class SyncManager {
for (String authority : syncableAuthorities) {
int isSyncable = getIsSyncable(account.account, account.userId,
authority);
- if (isSyncable == 0) {
+ if (isSyncable == AuthorityInfo.NOT_SYNCABLE) {
continue;
}
final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
@@ -813,8 +813,9 @@ public class SyncManager {
final boolean allowParallelSyncs = syncAdapterInfo.type.allowParallelSyncs();
final boolean isAlwaysSyncable = syncAdapterInfo.type.isAlwaysSyncable();
if (isSyncable < 0 && isAlwaysSyncable) {
- mSyncStorageEngine.setIsSyncable(account.account, account.userId, authority, 1);
- isSyncable = 1;
+ mSyncStorageEngine.setIsSyncable(
+ account.account, account.userId, authority, AuthorityInfo.SYNCABLE);
+ isSyncable = AuthorityInfo.SYNCABLE;
}
if (onlyThoseWithUnkownSyncableState && isSyncable >= 0) {
continue;
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index d68b615..cca0c16 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -301,6 +301,30 @@ public class SyncStorageEngine extends Handler {
}
public static class AuthorityInfo {
+ // Legal values of getIsSyncable
+ /**
+ * Default state for a newly installed adapter. An uninitialized adapter will receive an
+ * initialization sync which are governed by a different set of rules to that of regular
+ * syncs.
+ */
+ public static final int NOT_INITIALIZED = -1;
+ /**
+ * The adapter will not receive any syncs. This is behaviourally equivalent to
+ * setSyncAutomatically -> false. However setSyncAutomatically is surfaced to the user
+ * while this is generally meant to be controlled by the developer.
+ */
+ public static final int NOT_SYNCABLE = 0;
+ /**
+ * The adapter is initialized and functioning. This is the normal state for an adapter.
+ */
+ public static final int SYNCABLE = 1;
+ /**
+ * The adapter is syncable but still requires an initialization sync. For example an adapter
+ * than has been restored from a previous device will be in this state. Not meant for
+ * external use.
+ */
+ public static final int SYNCABLE_NOT_INITIALIZED = 2;
+
final EndPoint target;
final int ident;
boolean enabled;
@@ -349,12 +373,11 @@ public class SyncStorageEngine extends Handler {
}
private void defaultInitialisation() {
- syncable = -1; // default to "unknown"
+ syncable = NOT_INITIALIZED; // default to "unknown"
backoffTime = -1; // if < 0 then we aren't in backoff mode
backoffDelay = -1; // if < 0 then we aren't in backoff mode
PeriodicSync defaultSync;
- // Old version is one sync a day. Empty bundle gets replaced by any addPeriodicSync()
- // call.
+ // Old version is one sync a day.
if (target.target_provider) {
defaultSync =
new PeriodicSync(target.account, target.provider,
@@ -663,6 +686,12 @@ public class SyncStorageEngine extends Handler {
}
return;
}
+ // If the adapter was syncable but missing its initialization sync, set it to
+ // uninitialized now. This is to give it a chance to run any one-time initialization
+ // logic.
+ if (sync && authority.syncable == AuthorityInfo.SYNCABLE_NOT_INITIALIZED) {
+ authority.syncable = AuthorityInfo.NOT_INITIALIZED;
+ }
authority.enabled = sync;
writeAccountInfoLocked();
}
@@ -682,7 +711,7 @@ public class SyncStorageEngine extends Handler {
new EndPoint(account, providerName, userId),
"get authority syncable");
if (authority == null) {
- return -1;
+ return AuthorityInfo.NOT_INITIALIZED;
}
return authority.syncable;
}
@@ -696,7 +725,7 @@ public class SyncStorageEngine extends Handler {
return authorityInfo.syncable;
}
}
- return -1;
+ return AuthorityInfo.NOT_INITIALIZED;
}
}
@@ -720,7 +749,8 @@ public class SyncStorageEngine extends Handler {
}
public void setIsTargetServiceActive(ComponentName cname, int userId, boolean active) {
- setSyncableStateForEndPoint(new EndPoint(cname, userId), active ? 1 : 0);
+ setSyncableStateForEndPoint(new EndPoint(cname, userId), active ?
+ AuthorityInfo.SYNCABLE : AuthorityInfo.NOT_SYNCABLE);
}
/**
@@ -733,10 +763,8 @@ public class SyncStorageEngine extends Handler {
AuthorityInfo aInfo;
synchronized (mAuthorities) {
aInfo = getOrCreateAuthorityLocked(target, -1, false);
- if (syncable > 1) {
- syncable = 1;
- } else if (syncable < -1) {
- syncable = -1;
+ if (syncable < AuthorityInfo.NOT_INITIALIZED) {
+ syncable = AuthorityInfo.NOT_INITIALIZED;
}
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.d(TAG, "setIsSyncable: " + aInfo.toString() + " -> " + syncable);
@@ -750,7 +778,7 @@ public class SyncStorageEngine extends Handler {
aInfo.syncable = syncable;
writeAccountInfoLocked();
}
- if (syncable > 0) {
+ if (syncable == AuthorityInfo.SYNCABLE) {
requestSync(aInfo, SyncOperation.REASON_IS_SYNCABLE, new Bundle());
}
reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
@@ -2012,7 +2040,7 @@ public class SyncStorageEngine extends Handler {
int userId = user == null ? 0 : Integer.parseInt(user);
if (accountType == null && packageName == null) {
accountType = "com.google";
- syncable = "unknown";
+ syncable = String.valueOf(AuthorityInfo.NOT_INITIALIZED);
}
authority = mAuthorities.get(id);
if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
@@ -2052,11 +2080,19 @@ public class SyncStorageEngine extends Handler {
}
if (authority != null) {
authority.enabled = enabled == null || Boolean.parseBoolean(enabled);
- if ("unknown".equals(syncable)) {
- authority.syncable = -1;
- } else {
- authority.syncable =
- (syncable == null || Boolean.parseBoolean(syncable)) ? 1 : 0;
+ try {
+ authority.syncable = (syncable == null) ?
+ AuthorityInfo.NOT_INITIALIZED : Integer.parseInt(syncable);
+ } catch (NumberFormatException e) {
+ // On L we stored this as {"unknown", "true", "false"} so fall back to this
+ // format.
+ if ("unknown".equals(syncable)) {
+ authority.syncable = AuthorityInfo.NOT_INITIALIZED;
+ } else {
+ authority.syncable = Boolean.parseBoolean(syncable) ?
+ AuthorityInfo.SYNCABLE : AuthorityInfo.NOT_SYNCABLE;
+ }
+
}
} else {
Log.w(TAG, "Failure adding authority: account="
@@ -2190,11 +2226,7 @@ public class SyncStorageEngine extends Handler {
out.attribute(null, "package", info.service.getPackageName());
out.attribute(null, "class", info.service.getClassName());
}
- if (authority.syncable < 0) {
- out.attribute(null, "syncable", "unknown");
- } else {
- out.attribute(null, "syncable", Boolean.toString(authority.syncable != 0));
- }
+ out.attribute(null, "syncable", Integer.toString(authority.syncable));
for (PeriodicSync periodicSync : authority.periodicSyncs) {
out.startTag(null, "periodicSync");
out.attribute(null, "period", Long.toString(periodicSync.period));
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 7f0be57..c52a1c1 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -33,6 +33,7 @@ import android.os.MessageQueue;
import android.os.RemoteException;
import android.os.SELinux;
import android.os.ServiceManager;
+import android.os.UserHandle;
import android.util.Slog;
import com.android.server.SystemService;
@@ -389,12 +390,12 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
}
}
- public List<Fingerprint> getEnrolledFingerprints(int groupId) {
- return mFingerprintUtils.getFingerprintsForUser(mContext, groupId);
+ public List<Fingerprint> getEnrolledFingerprints(int userId) {
+ return mFingerprintUtils.getFingerprintsForUser(mContext, userId);
}
- public boolean hasEnrolledFingerprints(int groupId) {
- return mFingerprintUtils.getFingerprintsForUser(mContext, groupId).size() > 0;
+ public boolean hasEnrolledFingerprints(int userId) {
+ return mFingerprintUtils.getFingerprintsForUser(mContext, userId).size() > 0;
}
boolean hasPermission(String permission) {
@@ -598,6 +599,15 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
public void enroll(final IBinder token, final byte[] cryptoToken, final int groupId,
final IFingerprintServiceReceiver receiver, final int flags) {
checkPermission(MANAGE_FINGERPRINT);
+ final int limit = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser);
+ final int callingUid = Binder.getCallingUid();
+ final int userId = UserHandle.getUserId(callingUid);
+ final int enrolled = FingerprintService.this.getEnrolledFingerprints(userId).size();
+ if (enrolled >= limit) {
+ Slog.w(TAG, "Too many fingerprints registered");
+ return;
+ }
final byte [] cryptoClone = Arrays.copyOf(cryptoToken, cryptoToken.length);
final boolean restricted = isRestricted();
@@ -689,11 +699,11 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
}
@Override // Binder call
- public List<Fingerprint> getEnrolledFingerprints(int groupId, String opPackageName) {
+ public List<Fingerprint> getEnrolledFingerprints(int userId, String opPackageName) {
if (!canUseFingerprint(opPackageName)) {
return Collections.emptyList();
}
- return FingerprintService.this.getEnrolledFingerprints(groupId);
+ return FingerprintService.this.getEnrolledFingerprints(userId);
}
@Override // Binder call
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index 77b800e..7999321 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -246,6 +246,8 @@ abstract class HdmiCecLocalDevice {
return handleRequestActiveSource(message);
case Constants.MESSAGE_GET_MENU_LANGUAGE:
return handleGetMenuLanguage(message);
+ case Constants.MESSAGE_SET_MENU_LANGUAGE:
+ return handleSetMenuLanguage(message);
case Constants.MESSAGE_GIVE_PHYSICAL_ADDRESS:
return handleGivePhysicalAddress();
case Constants.MESSAGE_GIVE_OSD_NAME:
@@ -377,6 +379,14 @@ abstract class HdmiCecLocalDevice {
}
@ServiceThreadOnly
+ protected boolean handleSetMenuLanguage(HdmiCecMessage message) {
+ assertRunOnServiceThread();
+ Slog.w(TAG, "Only Playback device can handle <Set Menu Language>:" + message.toString());
+ // 'return false' will cause to reply with <Feature Abort>.
+ return false;
+ }
+
+ @ServiceThreadOnly
protected boolean handleGiveOsdName(HdmiCecMessage message) {
assertRunOnServiceThread();
// Note that since this method is called after logical address allocation is done,
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index 30a9b43..493471b 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -26,9 +26,14 @@ import android.os.SystemProperties;
import android.provider.Settings.Global;
import android.util.Slog;
+import com.android.internal.app.LocalePicker;
+import com.android.internal.app.LocalePicker.LocaleInfo;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly;
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+
/**
* Represent a logical device of type Playback residing in Android system.
*/
@@ -306,6 +311,35 @@ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDevice {
return true; // Broadcast message.
}
+ @ServiceThreadOnly
+ protected boolean handleSetMenuLanguage(HdmiCecMessage message) {
+ assertRunOnServiceThread();
+
+ try {
+ String iso3Language = new String(message.getParams(), 0, 3, "US-ASCII");
+
+ // Don't use Locale.getAvailableLocales() since it returns a locale
+ // which is not available on Settings.
+ final List<LocaleInfo> localeInfos = LocalePicker.getAllAssetLocales(
+ mService.getContext(), false);
+ for (LocaleInfo localeInfo : localeInfos) {
+ if (localeInfo.getLocale().getISO3Language().equals(iso3Language)) {
+ // WARNING: CEC adopts ISO/FDIS-2 for language code, while Android requires
+ // additional country variant to pinpoint the locale. This keeps the right
+ // locale from being chosen. 'eng' in the CEC command, for instance,
+ // will always be mapped to en-AU among other variants like en-US, en-GB,
+ // an en-IN, which may not be the expected one.
+ LocalePicker.updateLocale(localeInfo.getLocale());
+ return true;
+ }
+ }
+ Slog.w(TAG, "Can't handle <Set Menu Language> of " + iso3Language);
+ return false;
+ } catch (UnsupportedEncodingException e) {
+ return false;
+ }
+ }
+
@Override
@ServiceThreadOnly
protected void sendStandby(int deviceId) {
diff --git a/services/core/java/com/android/server/notification/ValidateNotificationPeople.java b/services/core/java/com/android/server/notification/ValidateNotificationPeople.java
index 10f1696..4af7d4e 100644
--- a/services/core/java/com/android/server/notification/ValidateNotificationPeople.java
+++ b/services/core/java/com/android/server/notification/ValidateNotificationPeople.java
@@ -51,7 +51,7 @@ import java.util.concurrent.TimeUnit;
public class ValidateNotificationPeople implements NotificationSignalExtractor {
// Using a shorter log tag since setprop has a limit of 32chars on variable name.
private static final String TAG = "ValidateNoPeople";
- private static final boolean INFO = true;
+ private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);;
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final boolean ENABLE_PEOPLE_VALIDATOR = true;
@@ -100,7 +100,7 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
public void onChange(boolean selfChange, Uri uri, int userId) {
super.onChange(selfChange, uri, userId);
if (DEBUG || mEvictionCount % 100 == 0) {
- if (INFO) Slog.i(TAG, "mEvictionCount: " + mEvictionCount);
+ if (VERBOSE) Slog.i(TAG, "mEvictionCount: " + mEvictionCount);
}
mPeopleCache.evictAll();
mEvictionCount++;
@@ -113,20 +113,20 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
public RankingReconsideration process(NotificationRecord record) {
if (!mEnabled) {
- if (INFO) Slog.i(TAG, "disabled");
+ if (VERBOSE) Slog.i(TAG, "disabled");
return null;
}
if (record == null || record.getNotification() == null) {
- if (INFO) Slog.i(TAG, "skipping empty notification");
+ if (VERBOSE) Slog.i(TAG, "skipping empty notification");
return null;
}
if (record.getUserId() == UserHandle.USER_ALL) {
- if (INFO) Slog.i(TAG, "skipping global notification");
+ if (VERBOSE) Slog.i(TAG, "skipping global notification");
return null;
}
Context context = getContextAsUser(record.getUser());
if (context == null) {
- if (INFO) Slog.i(TAG, "skipping notification that lacks a context");
+ if (VERBOSE) Slog.i(TAG, "skipping notification that lacks a context");
return null;
}
return validatePeople(context, record);
@@ -220,7 +220,7 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
return null;
}
- if (INFO) Slog.i(TAG, "Validating: " + key + " for " + context.getUserId());
+ if (VERBOSE) Slog.i(TAG, "Validating: " + key + " for " + context.getUserId());
final LinkedList<String> pendingLookups = new LinkedList<String>();
for (int personIdx = 0; personIdx < people.length && personIdx < MAX_PEOPLE; personIdx++) {
final String handle = people[personIdx];
@@ -244,7 +244,7 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
affinityOut[0] = affinity;
if (pendingLookups.isEmpty()) {
- if (INFO) Slog.i(TAG, "final affinity: " + affinity);
+ if (VERBOSE) Slog.i(TAG, "final affinity: " + affinity);
if (affinity != NONE) MetricsLogger.count(mBaseContext, "note_with_people", 1);
return null;
}
@@ -422,7 +422,7 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
@Override
public void work() {
- if (INFO) Slog.i(TAG, "Executing: validation for: " + mKey);
+ if (VERBOSE) Slog.i(TAG, "Executing: validation for: " + mKey);
long timeStartMs = System.currentTimeMillis();
for (final String handle: mPendingLookups) {
LookupResult lookupResult = null;
@@ -463,7 +463,7 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
public void applyChangesLocked(NotificationRecord operand) {
float affinityBound = operand.getContactAffinity();
operand.setContactAffinity(Math.max(mContactAffinity, affinityBound));
- if (INFO) Slog.i(TAG, "final affinity: " + operand.getContactAffinity());
+ if (VERBOSE) Slog.i(TAG, "final affinity: " + operand.getContactAffinity());
}
public float getContactAffinity() {
diff --git a/services/core/java/com/android/server/pm/KeySetManagerService.java b/services/core/java/com/android/server/pm/KeySetManagerService.java
index 1ee07a5..0de0c92 100644
--- a/services/core/java/com/android/server/pm/KeySetManagerService.java
+++ b/services/core/java/com/android/server/pm/KeySetManagerService.java
@@ -16,6 +16,9 @@
package com.android.server.pm;
+import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
+
+import com.android.internal.util.Preconditions;
import android.content.pm.PackageParser;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -98,6 +101,7 @@ public class KeySetManagerService {
mRefCount++;
return;
}
+
public long decrRefCountLPw() {
mRefCount--;
return mRefCount;
@@ -168,25 +172,82 @@ public class KeySetManagerService {
}
/**
+ * addScannedPackageLPw directly modifies the package metadata in pm.Settings
+ * at a point of no-return. We need to make sure that the scanned package does
+ * not contain bad keyset meta-data that could generate an incorrect
+ * PackageSetting. Verify that there is a signing keyset, there are no issues
+ * with null objects, and the upgrade and defined keysets match.
+ *
+ * Returns true if the package can safely be added to the keyset metadata.
+ */
+ public void assertScannedPackageValid(PackageParser.Package pkg)
+ throws PackageManagerException {
+ if (pkg == null || pkg.packageName == null) {
+ throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
+ "Passed invalid package to keyset validation.");
+ }
+ ArraySet<PublicKey> signingKeys = pkg.mSigningKeys;
+ if (signingKeys == null || !(signingKeys.size() > 0) || signingKeys.contains(null)) {
+ throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
+ "Package has invalid signing-key-set.");
+ }
+ ArrayMap<String, ArraySet<PublicKey>> definedMapping = pkg.mKeySetMapping;
+ if (definedMapping != null) {
+ if (definedMapping.containsKey(null) || definedMapping.containsValue(null)) {
+ throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
+ "Package has null defined key set.");
+ }
+ int defMapSize = definedMapping.size();
+ for (int i = 0; i < defMapSize; i++) {
+ if (!(definedMapping.valueAt(i).size() > 0)
+ || definedMapping.valueAt(i).contains(null)) {
+ throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
+ "Package has null/no public keys for defined key-sets.");
+ }
+ }
+ }
+ ArraySet<String> upgradeAliases = pkg.mUpgradeKeySets;
+ if (upgradeAliases != null) {
+ if (definedMapping == null || !(definedMapping.keySet().containsAll(upgradeAliases))) {
+ throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
+ "Package has upgrade-key-sets without corresponding definitions.");
+ }
+ }
+ }
+
+ public void addScannedPackageLPw(PackageParser.Package pkg) {
+ Preconditions.checkNotNull(pkg, "Attempted to add null pkg to ksms.");
+ Preconditions.checkNotNull(pkg.packageName, "Attempted to add null pkg to ksms.");
+ PackageSetting ps = mPackages.get(pkg.packageName);
+ Preconditions.checkNotNull(ps, "pkg: " + pkg.packageName
+ + "does not have a corresponding entry in mPackages.");
+ addSigningKeySetToPackageLPw(ps, pkg.mSigningKeys);
+ if (pkg.mKeySetMapping != null) {
+ addDefinedKeySetsToPackageLPw(ps, pkg.mKeySetMapping);
+ if (pkg.mUpgradeKeySets != null) {
+ addUpgradeKeySetsToPackageLPw(ps, pkg.mUpgradeKeySets);
+ }
+ }
+ }
+
+ /**
* Informs the system that the given package was signed by the provided KeySet.
*/
- public void addSigningKeySetToPackageLPw(String packageName,
+ void addSigningKeySetToPackageLPw(PackageSetting pkg,
ArraySet<PublicKey> signingKeys) {
/* check existing keyset for reuse or removal */
- PackageSetting pkg = mPackages.get(packageName);
long signingKeySetId = pkg.keySetData.getProperSigningKeySet();
if (signingKeySetId != PackageKeySetData.KEYSET_UNASSIGNED) {
ArraySet<PublicKey> existingKeys = getPublicKeysFromKeySetLPr(signingKeySetId);
- if (existingKeys.equals(signingKeys)) {
+ if (existingKeys != null && existingKeys.equals(signingKeys)) {
/* no change in signing keys, leave PackageSetting alone */
return;
} else {
/* old keyset no longer valid, remove ref */
- KeySetHandle ksh = mKeySets.get(signingKeySetId);
decrementKeySetLPw(signingKeySetId);
}
}
@@ -212,13 +273,12 @@ public class KeySetManagerService {
return KEYSET_NOT_FOUND;
}
- /*
+ /**
* Inform the system that the given package defines the given KeySets.
* Remove any KeySets the package no longer defines.
*/
- public void addDefinedKeySetsToPackageLPw(String packageName,
+ void addDefinedKeySetsToPackageLPw(PackageSetting pkg,
ArrayMap<String, ArraySet<PublicKey>> definedMapping) {
- PackageSetting pkg = mPackages.get(packageName);
ArrayMap<String, Long> prevDefinedKeySets = pkg.keySetData.getAliases();
/* add all of the newly defined KeySets */
@@ -227,7 +287,7 @@ public class KeySetManagerService {
for (int i = 0; i < defMapSize; i++) {
String alias = definedMapping.keyAt(i);
ArraySet<PublicKey> pubKeys = definedMapping.valueAt(i);
- if (alias != null && pubKeys != null && pubKeys.size() > 0) {
+ if (alias != null && pubKeys != null || pubKeys.size() > 0) {
KeySetHandle ks = addKeySetLPw(pubKeys);
newKeySetAliases.put(alias, ks.getId());
}
@@ -250,9 +310,8 @@ public class KeySetManagerService {
* alias in its manifest to be an upgradeKeySet. This must be called
* after all of the defined KeySets have been added.
*/
- public void addUpgradeKeySetsToPackageLPw(String packageName,
- ArraySet<String> upgradeAliases) {
- PackageSetting pkg = mPackages.get(packageName);
+ void addUpgradeKeySetsToPackageLPw(PackageSetting pkg,
+ ArraySet<String> upgradeAliases) {
final int uaSize = upgradeAliases.size();
for (int i = 0; i < uaSize; i++) {
pkg.keySetData.addUpgradeKeySet(upgradeAliases.valueAt(i));
@@ -290,11 +349,11 @@ public class KeySetManagerService {
* identify a {@link KeySetHandle}.
*/
public ArraySet<PublicKey> getPublicKeysFromKeySetLPr(long id) {
- if(mKeySetMapping.get(id) == null) {
+ ArraySet<Long> pkIds = mKeySetMapping.get(id);
+ if (pkIds == null) {
return null;
}
ArraySet<PublicKey> mPubKeys = new ArraySet<PublicKey>();
- ArraySet<Long> pkIds = mKeySetMapping.get(id);
final int pkSize = pkIds.size();
for (int i = 0; i < pkSize; i++) {
mPubKeys.add(mPublicKeys.get(pkIds.valueAt(i)).getKey());
@@ -376,6 +435,10 @@ public class KeySetManagerService {
*/
private void decrementKeySetLPw(long id) {
KeySetHandle ks = mKeySets.get(id);
+ if (ks == null) {
+ /* nothing to do */
+ return;
+ }
if (ks.decrRefCountLPw() <= 0) {
ArraySet<Long> pubKeys = mKeySetMapping.get(id);
final int pkSize = pubKeys.size();
@@ -385,7 +448,6 @@ public class KeySetManagerService {
mKeySets.delete(id);
mKeySetMapping.delete(id);
}
- return;
}
/*
@@ -394,16 +456,20 @@ public class KeySetManagerService {
*/
private void decrementPublicKeyLPw(long id) {
PublicKeyHandle pk = mPublicKeys.get(id);
+ if (pk == null) {
+ /* nothing to do */
+ return;
+ }
if (pk.decrRefCountLPw() <= 0) {
mPublicKeys.delete(id);
}
- return;
}
/**
* Adds the given PublicKey to the system, deduping as it goes.
*/
private long addPublicKeyLPw(PublicKey key) {
+ Preconditions.checkNotNull(key, "Cannot add null public key!");
long id = getIdForPublicKeyLPr(key);
if (id != PUBLIC_KEY_NOT_FOUND) {
@@ -473,6 +539,8 @@ public class KeySetManagerService {
/* remove refs from common keysets and public keys */
PackageSetting pkg = mPackages.get(packageName);
+ Preconditions.checkNotNull(pkg, "pkg name: " + packageName
+ + "does not have a corresponding entry in mPackages.");
long signingKeySetId = pkg.keySetData.getProperSigningKeySet();
decrementKeySetLPw(signingKeySetId);
ArrayMap<String, Long> definedKeySets = pkg.keySetData.getAliases();
@@ -715,16 +783,36 @@ public class KeySetManagerService {
final int numRefCounts = keySetRefCounts.size();
for (int i = 0; i < numRefCounts; i++) {
KeySetHandle ks = mKeySets.get(keySetRefCounts.keyAt(i));
+ if (ks == null) {
+ /* something went terribly wrong and we have references to a non-existent key-set */
+ Slog.wtf(TAG, "Encountered non-existent key-set reference when reading settings");
+ continue;
+ }
ks.setRefCountLPw(keySetRefCounts.valueAt(i));
}
+ /*
+ * In case something went terribly wrong and we have keysets with no associated packges
+ * that refer to them, record the orphaned keyset ids, and remove them using
+ * decrementKeySetLPw() after all keyset references have been set so that the associtaed
+ * public keys have the appropriate references from all keysets.
+ */
+ ArraySet<Long> orphanedKeySets = new ArraySet<Long>();
final int numKeySets = mKeySets.size();
for (int i = 0; i < numKeySets; i++) {
+ if (mKeySets.valueAt(i).getRefCountLPr() == 0) {
+ Slog.wtf(TAG, "Encountered key-set w/out package references when reading settings");
+ orphanedKeySets.add(mKeySets.keyAt(i));
+ }
ArraySet<Long> pubKeys = mKeySetMapping.valueAt(i);
final int pkSize = pubKeys.size();
for (int j = 0; j < pkSize; j++) {
mPublicKeys.get(pubKeys.valueAt(j)).incrRefCountLPw();
}
}
+ final int numOrphans = orphanedKeySets.size();
+ for (int i = 0; i < numOrphans; i++) {
+ decrementKeySetLPw(orphanedKeySets.valueAt(i));
+ }
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 548d93c..5b7dd70 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -5109,16 +5109,18 @@ public class PackageManagerService extends IPackageManager.Stub {
&& !isCompatSignatureUpdateNeeded(pkg)
&& !isRecoverSignatureUpdateNeeded(pkg)) {
long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
+ KeySetManagerService ksms = mSettings.mKeySetManagerService;
+ ArraySet<PublicKey> signingKs;
+ synchronized (mPackages) {
+ signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
+ }
if (ps.signatures.mSignatures != null
&& ps.signatures.mSignatures.length != 0
- && mSigningKeySetId != PackageKeySetData.KEYSET_UNASSIGNED) {
+ && signingKs != null) {
// Optimization: reuse the existing cached certificates
// if the package appears to be unchanged.
pkg.mSignatures = ps.signatures.mSignatures;
- KeySetManagerService ksms = mSettings.mKeySetManagerService;
- synchronized (mPackages) {
- pkg.mSigningKeys = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
- }
+ pkg.mSigningKeys = signingKs;
return;
}
@@ -6590,6 +6592,10 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ // Make sure we're not adding any bogus keyset info
+ KeySetManagerService ksms = mSettings.mKeySetManagerService;
+ ksms.assertScannedPackageValid(pkg);
+
// writer
synchronized (mPackages) {
// We don't expect installation to fail beyond this point
@@ -6626,20 +6632,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
// Add the package's KeySets to the global KeySetManagerService
- KeySetManagerService ksms = mSettings.mKeySetManagerService;
- try {
- ksms.addSigningKeySetToPackageLPw(pkg.packageName, pkg.mSigningKeys);
- if (pkg.mKeySetMapping != null) {
- ksms.addDefinedKeySetsToPackageLPw(pkg.packageName, pkg.mKeySetMapping);
- if (pkg.mUpgradeKeySets != null) {
- ksms.addUpgradeKeySetsToPackageLPw(pkg.packageName, pkg.mUpgradeKeySets);
- }
- }
- } catch (NullPointerException e) {
- Slog.e(TAG, "Could not add KeySet to " + pkg.packageName, e);
- } catch (IllegalArgumentException e) {
- Slog.e(TAG, "Could not add KeySet to malformed package" + pkg.packageName, e);
- }
+ ksms.addScannedPackageLPw(pkg);
int N = pkg.providers.size();
StringBuilder r = null;
@@ -11188,7 +11181,7 @@ public class PackageManagerService extends IPackageManager.Stub {
KeySetManagerService ksms = mSettings.mKeySetManagerService;
for (int i = 0; i < upgradeKeySets.length; i++) {
Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
- if (newPkg.mSigningKeys.containsAll(upgradeSet)) {
+ if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
return true;
}
}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 095b7d7..4082ff3 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -966,6 +966,7 @@ public class UserManagerService extends IUserManager.Stub {
writeBoolean(serializer, restrictions, UserManager.DISALLOW_ADJUST_VOLUME);
writeBoolean(serializer, restrictions, UserManager.DISALLOW_OUTGOING_CALLS);
writeBoolean(serializer, restrictions, UserManager.DISALLOW_SMS);
+ writeBoolean(serializer, restrictions, UserManager.DISALLOW_FUN);
writeBoolean(serializer, restrictions, UserManager.DISALLOW_CREATE_WINDOWS);
writeBoolean(serializer, restrictions, UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE);
writeBoolean(serializer, restrictions, UserManager.DISALLOW_OUTGOING_BEAM);
@@ -1096,6 +1097,7 @@ public class UserManagerService extends IUserManager.Stub {
readBoolean(parser, restrictions, UserManager.DISALLOW_ADJUST_VOLUME);
readBoolean(parser, restrictions, UserManager.DISALLOW_OUTGOING_CALLS);
readBoolean(parser, restrictions, UserManager.DISALLOW_SMS);
+ readBoolean(parser, restrictions, UserManager.DISALLOW_FUN);
readBoolean(parser, restrictions, UserManager.DISALLOW_CREATE_WINDOWS);
readBoolean(parser, restrictions, UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE);
readBoolean(parser, restrictions, UserManager.DISALLOW_OUTGOING_BEAM);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index ea66a04..f1f61f3 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -209,6 +209,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_UNMUTE_MICROPHONE);
DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_ADJUST_VOLUME);
DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_SMS);
+ DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_FUN);
DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_SAFE_BOOT);
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java
index 2557974..7f9a0de 100644
--- a/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java
@@ -118,7 +118,7 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
signingKeys.add(keyA);
- mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+ mKsms.addSigningKeySetToPackageLPw(ps, signingKeys);
assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1));
assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
@@ -145,10 +145,10 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
signingKeys.add(keyA);
- mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+ mKsms.addSigningKeySetToPackageLPw(ps, signingKeys);
/* add again, to represent upgrade of package */
- mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+ mKsms.addSigningKeySetToPackageLPw(ps, signingKeys);
assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1));
assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
@@ -175,13 +175,13 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
signingKeys.add(keyA);
- mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+ mKsms.addSigningKeySetToPackageLPw(ps, signingKeys);
/* now upgrade with new key */
PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
signingKeys.removeAt(0);
signingKeys.add(keyB);
- mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+ mKsms.addSigningKeySetToPackageLPw(ps, signingKeys);
assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1));
assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2));
@@ -212,14 +212,14 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
signingKeys.add(keyA);
- mKsms.addSigningKeySetToPackageLPw(ps1.name, signingKeys);
- mKsms.addSigningKeySetToPackageLPw(ps2.name, signingKeys);
+ mKsms.addSigningKeySetToPackageLPw(ps1, signingKeys);
+ mKsms.addSigningKeySetToPackageLPw(ps2, signingKeys);
/* now upgrade with new key */
PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
signingKeys.removeAt(0);
signingKeys.add(keyB);
- mKsms.addSigningKeySetToPackageLPw(ps1.name, signingKeys);
+ mKsms.addSigningKeySetToPackageLPw(ps1, signingKeys);
assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1));
assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2));
@@ -255,13 +255,13 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
ArraySet<PublicKey> signingKeys1 = new ArraySet<PublicKey>();
PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
signingKeys1.add(keyA);
- mKsms.addSigningKeySetToPackageLPw(ps1.name, signingKeys1);
+ mKsms.addSigningKeySetToPackageLPw(ps1, signingKeys1);
/* collect second signing key and add */
ArraySet<PublicKey> signingKeys2 = new ArraySet<PublicKey>();
PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
signingKeys2.add(keyB);
- mKsms.addSigningKeySetToPackageLPw(ps2.name, signingKeys2);
+ mKsms.addSigningKeySetToPackageLPw(ps2, signingKeys2);
/* verify first is unchanged */
assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1));
@@ -300,10 +300,10 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
signingKeys.add(keyA);
- mKsms.addSigningKeySetToPackageLPw(ps1.name, signingKeys);
+ mKsms.addSigningKeySetToPackageLPw(ps1, signingKeys);
/* add again for second package */
- mKsms.addSigningKeySetToPackageLPw(ps2.name, signingKeys);
+ mKsms.addSigningKeySetToPackageLPw(ps2, signingKeys);
assertEquals(2, KeySetUtils.getKeySetRefCount(mKsms, 1));
assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
@@ -333,12 +333,12 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
signingKeys.add(keyA);
- mKsms.addSigningKeySetToPackageLPw(ps1.name, signingKeys);
+ mKsms.addSigningKeySetToPackageLPw(ps1, signingKeys);
/* give ps2 a superset (add keyB) */
PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
signingKeys.add(keyB);
- mKsms.addSigningKeySetToPackageLPw(ps2.name, signingKeys);
+ mKsms.addSigningKeySetToPackageLPw(ps2, signingKeys);
assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1));
assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2));
@@ -374,12 +374,12 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
signingKeys.add(keyA);
- mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+ mKsms.addSigningKeySetToPackageLPw(ps, signingKeys);
/* now with additional key */
PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
signingKeys.add(keyB);
- mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+ mKsms.addSigningKeySetToPackageLPw(ps, signingKeys);
assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1));
assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2));
@@ -413,7 +413,7 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
keys.add(keyA);
definedKS.put("aliasA", keys);
- mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+ mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS);
assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1));
assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
@@ -441,7 +441,7 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
keys.add(keyA);
definedKS.put("aliasA", keys);
definedKS.put("aliasA2", keys);
- mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+ mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS);
assertEquals(2, KeySetUtils.getKeySetRefCount(mKsms, 1));
assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
@@ -470,7 +470,7 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
keys.add(keyA);
definedKS.put("aliasA", keys);
- mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+ mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS);
/* now upgrade to different defined key-set */
keys = new ArraySet<PublicKey>();
@@ -478,7 +478,7 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
keys.add(keyB);
definedKS.remove("aliasA");
definedKS.put("aliasB", keys);
- mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+ mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS);
assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1));
assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1));
@@ -510,14 +510,14 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
keys.add(keyA);
definedKS.put("aliasA", keys);
- mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+ mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS);
/* now upgrade to different set w/same alias as before */
keys = new ArraySet<PublicKey>();
PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
keys.add(keyB);
definedKS.put("aliasA", keys);
- mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+ mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS);
assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1));
assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1));
@@ -551,7 +551,7 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
keys2.add(keyB);
definedKS.put("aliasA", keys1);
definedKS.put("aliasB", keys2);
- mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+ mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS);
/* now upgrade to different set (B, C) */
keys1 = new ArraySet<PublicKey>();
@@ -559,7 +559,7 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
keys1.add(keyC);
definedKS.remove("aliasA");
definedKS.put("aliasC", keys1);
- mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+ mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS);
assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 3));
assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 3));
@@ -612,7 +612,7 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
keys1.add(keyA);
definedKS.put("aliasA", keys1);
- mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+ mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS);
/* now upgrade to different set */
ArraySet<PublicKey> keys2 = new ArraySet<PublicKey>();
@@ -620,12 +620,12 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
keys2.add(keyB);
definedKS.remove("aliasA");
definedKS.put("aliasB", keys2);
- mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+ mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS);
/* upgrade back to original */
definedKS.remove("aliasB");
definedKS.put("aliasA", keys1);
- mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+ mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS);
assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1));
assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 2));
@@ -655,10 +655,10 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
keys.add(keyA);
definedKS.put("aliasA", keys);
- mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+ mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS);
ArraySet<String> upgradeKS = new ArraySet<String>();
upgradeKS.add("aliasA");
- mKsms.addUpgradeKeySetsToPackageLPw(ps.name, upgradeKS);
+ mKsms.addUpgradeKeySetsToPackageLPw(ps, upgradeKS);
assertEquals(1, ps.keySetData.getUpgradeKeySets().length);
assertEquals(1, ps.keySetData.getUpgradeKeySets()[0]);
@@ -677,11 +677,11 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
keys.add(keyA);
definedKS.put("aliasA", keys);
- mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+ mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS);
ArraySet<String> upgradeKS = new ArraySet<String>();
upgradeKS.add("aliasB");
try {
- mKsms.addUpgradeKeySetsToPackageLPw(ps.name, upgradeKS);
+ mKsms.addUpgradeKeySetsToPackageLPw(ps, upgradeKS);
} catch (IllegalArgumentException e) {
/* should have been caught in packagemanager, so exception thrown */
@@ -704,17 +704,17 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
keys.add(keyA);
definedKS.put("aliasA", keys);
- mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+ mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS);
ArraySet<String> upgradeKS = new ArraySet<String>();
upgradeKS.add("aliasA");
- mKsms.addUpgradeKeySetsToPackageLPw(ps.name, upgradeKS);
+ mKsms.addUpgradeKeySetsToPackageLPw(ps, upgradeKS);
keys = new ArraySet<PublicKey>();
PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
keys.add(keyB);
definedKS.remove("aliasA");
definedKS.put("aliasB", keys);
- mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+ mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS);
assertNull(ps.keySetData.getUpgradeKeySets());
}
@@ -729,7 +729,7 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
signingKeys.add(keyA);
- mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+ mKsms.addSigningKeySetToPackageLPw(ps, signingKeys);
/* remove its references */
mKsms.removeAppKeySetDataLPw(ps.name);
@@ -754,8 +754,8 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
signingKeys.add(keyA);
- mKsms.addSigningKeySetToPackageLPw(ps1.name, signingKeys);
- mKsms.addSigningKeySetToPackageLPw(ps2.name, signingKeys);
+ mKsms.addSigningKeySetToPackageLPw(ps1, signingKeys);
+ mKsms.addSigningKeySetToPackageLPw(ps2, signingKeys);
/* remove references from first package */
mKsms.removeAppKeySetDataLPw(ps1.name);
@@ -784,13 +784,13 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
/* removal requires signing keyset to be specified (since all apps are
* assumed to have it). We skipped this in the defined tests, but can't
* here. */
- mKsms.addSigningKeySetToPackageLPw(ps.name, keys);
+ mKsms.addSigningKeySetToPackageLPw(ps, keys);
definedKS.put("aliasA", keys);
- mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+ mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS);
ArraySet<String> upgradeKS = new ArraySet<String>();
upgradeKS.add("aliasA");
- mKsms.addUpgradeKeySetsToPackageLPw(ps.name, upgradeKS);
+ mKsms.addUpgradeKeySetsToPackageLPw(ps, upgradeKS);
mKsms.removeAppKeySetDataLPw(ps.name);
assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1));
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index b0fca95..fafe44a 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -853,7 +853,38 @@ public class VoiceInteractionManagerService extends SystemService {
PackageMonitor mPackageMonitor = new PackageMonitor() {
@Override
public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
- return super.onHandleForceStop(intent, packages, uid, doit);
+ if (DEBUG) Slog.d(TAG, "onHandleForceStop uid=" + uid + " doit=" + doit);
+
+ int userHandle = UserHandle.getUserId(uid);
+ ComponentName curInteractor = getCurInteractor(userHandle);
+ ComponentName curRecognizer = getCurRecognizer(userHandle);
+ boolean hit = false;
+ for (String pkg : packages) {
+ if (curInteractor != null && pkg.equals(curInteractor.getPackageName())) {
+ hit = true;
+ break;
+ } else if (curRecognizer != null
+ && pkg.equals(curRecognizer.getPackageName())) {
+ hit = true;
+ break;
+ }
+ }
+ if (hit && doit) {
+ // The user is force stopping our current interactor/recognizer.
+ // Clear the current settings and restore default state.
+ synchronized (VoiceInteractionManagerService.this) {
+ mSoundTriggerHelper.stopAllRecognitions();
+ if (mImpl != null) {
+ mImpl.shutdownLocked();
+ mImpl = null;
+ }
+ setCurInteractor(null, userHandle);
+ setCurRecognizer(null, userHandle);
+ initForUser(userHandle);
+ switchImplementationIfNeededLocked(true);
+ }
+ }
+ return hit;
}
@Override
@@ -865,51 +896,53 @@ public class VoiceInteractionManagerService extends SystemService {
int userHandle = getChangingUserId();
if (DEBUG) Slog.d(TAG, "onSomePackagesChanged user=" + userHandle);
- ComponentName curInteractor = getCurInteractor(userHandle);
- ComponentName curRecognizer = getCurRecognizer(userHandle);
- if (curRecognizer == null) {
- // Could a new recognizer appear when we don't have one pre-installed?
- if (anyPackagesAppearing()) {
- curRecognizer = findAvailRecognizer(null, userHandle);
- if (curRecognizer != null) {
- setCurRecognizer(curRecognizer, userHandle);
+ synchronized (VoiceInteractionManagerService.this) {
+ ComponentName curInteractor = getCurInteractor(userHandle);
+ ComponentName curRecognizer = getCurRecognizer(userHandle);
+ if (curRecognizer == null) {
+ // Could a new recognizer appear when we don't have one pre-installed?
+ if (anyPackagesAppearing()) {
+ curRecognizer = findAvailRecognizer(null, userHandle);
+ if (curRecognizer != null) {
+ setCurRecognizer(curRecognizer, userHandle);
+ }
}
- }
- return;
- }
-
- if (curInteractor != null) {
- int change = isPackageDisappearing(curInteractor.getPackageName());
- if (change == PACKAGE_PERMANENT_CHANGE) {
- // The currently set interactor is permanently gone; fall back to
- // the default config.
- setCurInteractor(null, userHandle);
- setCurRecognizer(null, userHandle);
- initForUser(userHandle);
return;
}
- change = isPackageAppearing(curInteractor.getPackageName());
- if (change != PACKAGE_UNCHANGED) {
- // If current interactor is now appearing, for any reason, then
- // restart our connection with it.
- if (mImpl != null && curInteractor.getPackageName().equals(
- mImpl.mComponent.getPackageName())) {
- switchImplementationIfNeededLocked(true);
+ if (curInteractor != null) {
+ int change = isPackageDisappearing(curInteractor.getPackageName());
+ if (change == PACKAGE_PERMANENT_CHANGE) {
+ // The currently set interactor is permanently gone; fall back to
+ // the default config.
+ setCurInteractor(null, userHandle);
+ setCurRecognizer(null, userHandle);
+ initForUser(userHandle);
+ return;
+ }
+
+ change = isPackageAppearing(curInteractor.getPackageName());
+ if (change != PACKAGE_UNCHANGED) {
+ // If current interactor is now appearing, for any reason, then
+ // restart our connection with it.
+ if (mImpl != null && curInteractor.getPackageName().equals(
+ mImpl.mComponent.getPackageName())) {
+ switchImplementationIfNeededLocked(true);
+ }
}
+ return;
}
- return;
- }
- // There is no interactor, so just deal with a simple recognizer.
- int change = isPackageDisappearing(curRecognizer.getPackageName());
- if (change == PACKAGE_PERMANENT_CHANGE
- || change == PACKAGE_TEMPORARY_CHANGE) {
- setCurRecognizer(findAvailRecognizer(null, userHandle), userHandle);
+ // There is no interactor, so just deal with a simple recognizer.
+ int change = isPackageDisappearing(curRecognizer.getPackageName());
+ if (change == PACKAGE_PERMANENT_CHANGE
+ || change == PACKAGE_TEMPORARY_CHANGE) {
+ setCurRecognizer(findAvailRecognizer(null, userHandle), userHandle);
- } else if (isPackageModified(curRecognizer.getPackageName())) {
- setCurRecognizer(findAvailRecognizer(curRecognizer.getPackageName(),
- userHandle), userHandle);
+ } else if (isPackageModified(curRecognizer.getPackageName())) {
+ setCurRecognizer(findAvailRecognizer(curRecognizer.getPackageName(),
+ userHandle), userHandle);
+ }
}
}
};
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 1cc275d..8291a30 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -667,7 +667,7 @@ public class TelephonyManager {
IPhoneSubInfo info = getSubscriberInfo();
if (info == null)
return null;
- return info.getDeviceSvnUsingSubId(subId[0]);
+ return info.getDeviceSvnUsingSubId(subId[0], mContext.getOpPackageName());
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
@@ -744,7 +744,7 @@ public class TelephonyManager {
IPhoneSubInfo info = getSubscriberInfo();
if (info == null)
return null;
- return info.getImeiForSubscriber(subId[0]);
+ return info.getImeiForSubscriber(subId[0], mContext.getOpPackageName());
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
@@ -773,7 +773,7 @@ public class TelephonyManager {
IPhoneSubInfo info = getSubscriberInfo();
if (info == null)
return null;
- String nai = info.getNaiForSubscriber(subId[0]);
+ String nai = info.getNaiForSubscriber(subId[0], mContext.getOpPackageName());
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Rlog.v(TAG, "Nai = " + nai);
}
@@ -1856,7 +1856,7 @@ public class TelephonyManager {
IPhoneSubInfo info = getSubscriberInfo();
if (info == null)
return null;
- return info.getIccSerialNumberForSubscriber(subId);
+ return info.getIccSerialNumberForSubscriber(subId, mContext.getOpPackageName());
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
@@ -1938,7 +1938,7 @@ public class TelephonyManager {
IPhoneSubInfo info = getSubscriberInfo();
if (info == null)
return null;
- return info.getSubscriberIdForSubscriber(subId);
+ return info.getSubscriberIdForSubscriber(subId, mContext.getOpPackageName());
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
@@ -1959,7 +1959,7 @@ public class TelephonyManager {
IPhoneSubInfo info = getSubscriberInfo();
if (info == null)
return null;
- return info.getGroupIdLevel1();
+ return info.getGroupIdLevel1(mContext.getOpPackageName());
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
@@ -1983,7 +1983,7 @@ public class TelephonyManager {
IPhoneSubInfo info = getSubscriberInfo();
if (info == null)
return null;
- return info.getGroupIdLevel1ForSubscriber(subId);
+ return info.getGroupIdLevel1ForSubscriber(subId, mContext.getOpPackageName());
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
@@ -2029,7 +2029,7 @@ public class TelephonyManager {
IPhoneSubInfo info = getSubscriberInfo();
if (info == null)
return null;
- return info.getLine1NumberForSubscriber(subId);
+ return info.getLine1NumberForSubscriber(subId, mContext.getOpPackageName());
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
@@ -2122,7 +2122,7 @@ public class TelephonyManager {
IPhoneSubInfo info = getSubscriberInfo();
if (info == null)
return null;
- return info.getLine1AlphaTagForSubscriber(subId);
+ return info.getLine1AlphaTagForSubscriber(subId, mContext.getOpPackageName());
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
@@ -2178,7 +2178,7 @@ public class TelephonyManager {
IPhoneSubInfo info = getSubscriberInfo();
if (info == null)
return null;
- return info.getMsisdnForSubscriber(subId);
+ return info.getMsisdnForSubscriber(subId, mContext.getOpPackageName());
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
@@ -2211,7 +2211,7 @@ public class TelephonyManager {
IPhoneSubInfo info = getSubscriberInfo();
if (info == null)
return null;
- return info.getVoiceMailNumberForSubscriber(subId);
+ return info.getVoiceMailNumberForSubscriber(subId, mContext.getOpPackageName());
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
@@ -2350,7 +2350,7 @@ public class TelephonyManager {
IPhoneSubInfo info = getSubscriberInfo();
if (info == null)
return null;
- return info.getVoiceMailAlphaTagForSubscriber(subId);
+ return info.getVoiceMailAlphaTagForSubscriber(subId, mContext.getOpPackageName());
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
diff --git a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
index c91a59c..ed85392 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
@@ -25,12 +25,12 @@ interface IPhoneSubInfo {
/**
* Retrieves the unique device ID, e.g., IMEI for GSM phones.
*/
- String getDeviceId();
+ String getDeviceId(String callingPackage);
/**
* Retrieves the unique Network Access ID
*/
- String getNaiForSubscriber(int subId);
+ String getNaiForSubscriber(int subId, String callingPackage);
/**
* Retrieves the unique device ID of a phone for the device, e.g., IMEI
@@ -41,91 +41,91 @@ interface IPhoneSubInfo {
/**
* Retrieves the IMEI.
*/
- String getImeiForSubscriber(int subId);
+ String getImeiForSubscriber(int subId, String callingPackage);
/**
* Retrieves the software version number for the device, e.g., IMEI/SV
* for GSM phones.
*/
- String getDeviceSvn();
+ String getDeviceSvn(String callingPackage);
/**
* Retrieves the software version number of a subId for the device, e.g., IMEI/SV
* for GSM phones.
*/
- String getDeviceSvnUsingSubId(int subId);
+ String getDeviceSvnUsingSubId(int subId, String callingPackage);
/**
* Retrieves the unique sbuscriber ID, e.g., IMSI for GSM phones.
*/
- String getSubscriberId();
+ String getSubscriberId(String callingPackage);
/**
* Retrieves the unique subscriber ID of a given subId, e.g., IMSI for GSM phones.
*/
- String getSubscriberIdForSubscriber(int subId);
+ String getSubscriberIdForSubscriber(int subId, String callingPackage);
/**
* Retrieves the Group Identifier Level1 for GSM phones.
*/
- String getGroupIdLevel1();
+ String getGroupIdLevel1(String callingPackage);
/**
* Retrieves the Group Identifier Level1 for GSM phones of a subId.
*/
- String getGroupIdLevel1ForSubscriber(int subId);
+ String getGroupIdLevel1ForSubscriber(int subId, String callingPackage);
/**
* Retrieves the serial number of the ICC, if applicable.
*/
- String getIccSerialNumber();
+ String getIccSerialNumber(String callingPackage);
/**
* Retrieves the serial number of a given subId.
*/
- String getIccSerialNumberForSubscriber(int subId);
+ String getIccSerialNumberForSubscriber(int subId, String callingPackage);
/**
* Retrieves the phone number string for line 1.
*/
- String getLine1Number();
+ String getLine1Number(String callingPackage);
/**
* Retrieves the phone number string for line 1 of a subcription.
*/
- String getLine1NumberForSubscriber(int subId);
+ String getLine1NumberForSubscriber(int subId, String callingPackage);
/**
* Retrieves the alpha identifier for line 1.
*/
- String getLine1AlphaTag();
+ String getLine1AlphaTag(String callingPackage);
/**
* Retrieves the alpha identifier for line 1 of a subId.
*/
- String getLine1AlphaTagForSubscriber(int subId);
+ String getLine1AlphaTagForSubscriber(int subId, String callingPackage);
/**
* Retrieves MSISDN Number.
*/
- String getMsisdn();
+ String getMsisdn(String callingPackage);
/**
* Retrieves the Msisdn of a subId.
*/
- String getMsisdnForSubscriber(int subId);
+ String getMsisdnForSubscriber(int subId, String callingPackage);
/**
* Retrieves the voice mail number.
*/
- String getVoiceMailNumber();
+ String getVoiceMailNumber(String callingPackage);
/**
* Retrieves the voice mail number of a given subId.
*/
- String getVoiceMailNumberForSubscriber(int subId);
+ String getVoiceMailNumberForSubscriber(int subId, String callingPackage);
/**
* Retrieves the complete voice mail number.
@@ -140,13 +140,13 @@ interface IPhoneSubInfo {
/**
* Retrieves the alpha identifier associated with the voice mail number.
*/
- String getVoiceMailAlphaTag();
+ String getVoiceMailAlphaTag(String callingPackage);
/**
* Retrieves the alpha identifier associated with the voice mail number
* of a subId.
*/
- String getVoiceMailAlphaTagForSubscriber(int subId);
+ String getVoiceMailAlphaTagForSubscriber(int subId, String callingPackage);
/**
* Returns the IMS private user identity (IMPI) that was loaded from the ISIM.
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index a1d5dd5..5d55ec6 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -684,6 +684,18 @@ public class WifiConfiguration implements Parcelable {
/**
* @hide
+ * For debug: date at which the config was last updated
+ */
+ public String updateTime;
+
+ /**
+ * @hide
+ * For debug: date at which the config was last updated
+ */
+ public String creationTime;
+
+ /**
+ * @hide
* The WiFi configuration is considered to have no internet access for purpose of autojoining
* if there has been a report of it having no internet access, and, it never have had
* internet access in the past.
@@ -1000,6 +1012,12 @@ public class WifiConfiguration implements Parcelable {
sbuf.append(" numNoInternetAccessReports ");
sbuf.append(this.numNoInternetAccessReports).append("\n");
}
+ if (this.updateTime != null) {
+ sbuf.append("creation=").append(this.updateTime).append("\n");
+ }
+ if (this.creationTime != null) {
+ sbuf.append("update=").append(this.creationTime).append("\n");
+ }
if (this.didSelfAdd) sbuf.append(" didSelfAdd");
if (this.selfAdded) sbuf.append(" selfAdded");
if (this.validatedInternetAccess) sbuf.append(" validatedInternetAccess");
@@ -1505,6 +1523,8 @@ public class WifiConfiguration implements Parcelable {
userApproved = source.userApproved;
numNoInternetAccessReports = source.numNoInternetAccessReports;
noInternetAccessExpected = source.noInternetAccessExpected;
+ creationTime = source.creationTime;
+ updateTime = source.updateTime;
}
}