Merge "Add a hidden method to query profile owner name for a user" into lmp-dev
diff --git a/CleanSpec.mk b/CleanSpec.mk
index c7cf940..7bc30fd 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -221,6 +221,7 @@
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/services.core_intermediates)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/services_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/inputflinger $(PRODUCT_OUT)/symbols/system/bin/inputflinger)
# ******************************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
diff --git a/api/current.txt b/api/current.txt
index 8f75785..5159a3a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -929,6 +929,7 @@
field public static final int orderingFromXml = 16843239; // 0x10101e7
field public static final int orientation = 16842948; // 0x10100c4
field public static final int outAnimation = 16843128; // 0x1010178
+ field public static final int outlineProvider = 16843961; // 0x10104b9
field public static final int overScrollFooter = 16843459; // 0x10102c3
field public static final int overScrollHeader = 16843458; // 0x10102c2
field public static final int overScrollMode = 16843457; // 0x10102c1
@@ -8667,7 +8668,7 @@
method public void removeSessionCallback(android.content.pm.PackageInstaller.SessionCallback);
method public void uninstall(java.lang.String, android.content.IntentSender);
field public static final java.lang.String ACTION_SESSION_DETAILS = "android.content.pm.action.SESSION_DETAILS";
- field public static final java.lang.String EXTRA_PACKAGE_NAMES = "android.content.pm.extra.PACKAGE_NAMES";
+ field public static final java.lang.String EXTRA_PACKAGE_NAME = "android.content.pm.extra.PACKAGE_NAME";
field public static final java.lang.String EXTRA_SESSION_ID = "android.content.pm.extra.SESSION_ID";
field public static final java.lang.String EXTRA_STATUS = "android.content.pm.extra.STATUS";
field public static final java.lang.String EXTRA_STATUS_MESSAGE = "android.content.pm.extra.STATUS_MESSAGE";
@@ -16381,16 +16382,16 @@
method public void addCallback(android.media.session.MediaController.Callback, android.os.Handler);
method public void adjustVolume(int, int);
method public boolean dispatchMediaButtonEvent(android.view.KeyEvent);
- method public android.media.session.MediaController.AudioInfo getAudioInfo();
method public android.os.Bundle getExtras();
method public long getFlags();
- method public android.app.PendingIntent getLaunchActivity();
method public android.media.MediaMetadata getMetadata();
method public java.lang.String getPackageName();
+ method public android.media.session.MediaController.PlaybackInfo getPlaybackInfo();
method public android.media.session.PlaybackState getPlaybackState();
method public java.util.List<android.media.session.MediaSession.Item> getQueue();
method public java.lang.CharSequence getQueueTitle();
method public int getRatingType();
+ method public android.app.PendingIntent getSessionActivity();
method public android.media.session.MediaSession.Token getSessionToken();
method public android.media.session.MediaController.TransportControls getTransportControls();
method public void removeCallback(android.media.session.MediaController.Callback);
@@ -16398,17 +16399,9 @@
method public void setVolumeTo(int, int);
}
- public static final class MediaController.AudioInfo {
- method public android.media.AudioAttributes getAudioAttributes();
- method public int getCurrentVolume();
- method public int getMaxVolume();
- method public int getVolumeControl();
- method public int getVolumeType();
- }
-
public static abstract class MediaController.Callback {
ctor public MediaController.Callback();
- method public void onAudioInfoChanged(android.media.session.MediaController.AudioInfo);
+ method public void onAudioInfoChanged(android.media.session.MediaController.PlaybackInfo);
method public void onExtrasChanged(android.os.Bundle);
method public void onMetadataChanged(android.media.MediaMetadata);
method public void onPlaybackStateChanged(android.media.session.PlaybackState);
@@ -16418,6 +16411,16 @@
method public void onSessionEvent(java.lang.String, android.os.Bundle);
}
+ public static final class MediaController.PlaybackInfo {
+ method public android.media.AudioAttributes getAudioAttributes();
+ method public int getCurrentVolume();
+ method public int getMaxVolume();
+ method public int getPlaybackType();
+ method public int getVolumeControl();
+ field public static final int PLAYBACK_TYPE_LOCAL = 1; // 0x1
+ field public static final int PLAYBACK_TYPE_REMOTE = 2; // 0x2
+ }
+
public final class MediaController.TransportControls {
method public void fastForward();
method public void pause();
@@ -16447,7 +16450,6 @@
method public void setCallback(android.media.session.MediaSession.Callback, android.os.Handler);
method public void setExtras(android.os.Bundle);
method public void setFlags(int);
- method public void setLaunchActivity(android.app.PendingIntent);
method public void setMediaButtonReceiver(android.app.PendingIntent);
method public void setMetadata(android.media.MediaMetadata);
method public void setPlaybackState(android.media.session.PlaybackState);
@@ -16455,10 +16457,9 @@
method public void setPlaybackToRemote(android.media.VolumeProvider);
method public void setQueue(java.util.List<android.media.session.MediaSession.Item>);
method public void setQueueTitle(java.lang.CharSequence);
+ method public void setSessionActivity(android.app.PendingIntent);
field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
- field public static final int PLAYBACK_TYPE_LOCAL = 1; // 0x1
- field public static final int PLAYBACK_TYPE_REMOTE = 2; // 0x2
}
public static abstract class MediaSession.Callback {
@@ -16505,6 +16506,7 @@
public final class MediaSessionManager {
method public void addOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener, android.content.ComponentName);
+ method public void addOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener, android.content.ComponentName, android.os.Handler);
method public java.util.List<android.media.session.MediaController> getActiveSessions(android.content.ComponentName);
method public void removeOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener);
}
@@ -16516,7 +16518,7 @@
public final class PlaybackState implements android.os.Parcelable {
method public int describeContents();
method public long getActions();
- method public long getBufferPosition();
+ method public long getBufferedPosition();
method public java.util.List<android.media.session.PlaybackState.CustomAction> getCustomActions();
method public java.lang.CharSequence getErrorMessage();
method public long getLastPositionUpdateTime();
@@ -16560,7 +16562,7 @@
method public android.media.session.PlaybackState build();
method public android.media.session.PlaybackState.Builder setActions(long);
method public android.media.session.PlaybackState.Builder setActiveItem(long);
- method public android.media.session.PlaybackState.Builder setBufferPosition(long);
+ method public android.media.session.PlaybackState.Builder setBufferedPosition(long);
method public android.media.session.PlaybackState.Builder setErrorMessage(java.lang.CharSequence);
method public android.media.session.PlaybackState.Builder setState(int, long, float, long);
method public android.media.session.PlaybackState.Builder setState(int, long, float);
@@ -18463,25 +18465,8 @@
package android.net.wifi.passpoint {
public abstract interface IWifiPasspointManager implements android.os.IInterface {
- method public abstract boolean addCredential(android.net.wifi.passpoint.WifiPasspointCredential) throws android.os.RemoteException;
- method public abstract java.util.List<android.net.wifi.passpoint.WifiPasspointCredential> getCredentials() throws android.os.RemoteException;
method public abstract android.os.Messenger getMessenger() throws android.os.RemoteException;
method public abstract int getPasspointState() throws android.os.RemoteException;
- method public abstract boolean removeCredential(android.net.wifi.passpoint.WifiPasspointCredential) throws android.os.RemoteException;
- method public abstract java.util.List<android.net.wifi.passpoint.WifiPasspointPolicy> requestCredentialMatch(java.util.List<android.net.wifi.ScanResult>) throws android.os.RemoteException;
- method public abstract boolean updateCredential(android.net.wifi.passpoint.WifiPasspointCredential) throws android.os.RemoteException;
- }
-
- public class WifiPasspointCredential implements android.os.Parcelable {
- ctor public WifiPasspointCredential(java.lang.String, java.lang.String, android.net.wifi.WifiEnterpriseConfig);
- method public int describeContents();
- method public android.net.wifi.WifiEnterpriseConfig getEnterpriseConfig();
- method public java.lang.String getHomeSpFqdn();
- method public java.lang.String getRealm();
- method public void setEnterpriseConfig(android.net.wifi.WifiEnterpriseConfig);
- method public void setHomeFqdn(java.lang.String);
- method public void setRealm(java.lang.String);
- method public void writeToParcel(android.os.Parcel, int);
}
public class WifiPasspointInfo implements android.os.Parcelable {
@@ -18654,17 +18639,6 @@
field public java.lang.String ssid;
}
- public class WifiPasspointPolicy implements android.os.Parcelable {
- method public android.net.wifi.WifiConfiguration createWifiConfiguration();
- method public int describeContents();
- method public java.lang.String getBssid();
- method public android.net.wifi.passpoint.WifiPasspointCredential getCredential();
- method public int getCredentialPriority();
- method public int getRoamingPriority();
- method public java.lang.String getSsid();
- method public void writeToParcel(android.os.Parcel, int);
- }
-
}
package android.nfc {
@@ -28569,8 +28543,8 @@
method public final int getCallerDisplayNamePresentation();
method public final android.telecomm.Conference getConference();
method public final java.util.List<android.telecomm.Connection> getConferenceableConnections();
- method public final int getFailureCode();
- method public final java.lang.String getFailureMessage();
+ method public final int getDisconnectCause();
+ method public final java.lang.String getDisconnectMessage();
method public final android.net.Uri getHandle();
method public final int getHandlePresentation();
method public final int getState();
@@ -34958,6 +34932,8 @@
ctor public ViewOutlineProvider();
method public abstract void getOutline(android.view.View, android.graphics.Outline);
field public static final android.view.ViewOutlineProvider BACKGROUND;
+ field public static final android.view.ViewOutlineProvider BOUNDS;
+ field public static final android.view.ViewOutlineProvider PADDED_BOUNDS;
}
public class ViewOverlay {
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 3c13115..1691d8e 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -178,8 +178,13 @@
//}
AssetManager assets = new AssetManager();
- if (assets.addAssetPath(resDir) == 0) {
- return null;
+ // resDir can be null if the 'android' package is creating a new Resources object.
+ // This is fine, since each AssetManager automatically loads the 'android' package
+ // already.
+ if (resDir != null) {
+ if (assets.addAssetPath(resDir) == 0) {
+ return null;
+ }
}
if (splitResDirs != null) {
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 4ac701f..7419ebc 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -105,10 +105,14 @@
public static final String EXTRA_STATUS_MESSAGE = "android.content.pm.extra.STATUS_MESSAGE";
/**
- * List of package names that are relevant to a status.
+ * Package name relevant to a status.
*
- * @see Intent#getStringArrayExtra(String)
+ * @see Intent#getStringExtra(String)
*/
+ public static final String EXTRA_PACKAGE_NAME = "android.content.pm.extra.PACKAGE_NAME";
+
+ /** {@hide} */
+ @Deprecated
public static final String EXTRA_PACKAGE_NAMES = "android.content.pm.extra.PACKAGE_NAMES";
/** {@hide} */
@@ -178,8 +182,8 @@
* permission, incompatible certificates, etc. The user may be able to
* uninstall another app to fix the issue.
* <p>
- * The result may also contain {@link #EXTRA_PACKAGE_NAMES} with the
- * specific packages identified as the cause of the conflict.
+ * The result may also contain {@link #EXTRA_PACKAGE_NAME} with the
+ * specific package identified as the cause of the conflict.
*
* @see #EXTRA_STATUS_MESSAGE
*/
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 2c50f25..eb8b762 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -596,7 +596,7 @@
public final static int PARSE_ON_SDCARD = 1<<5;
public final static int PARSE_IS_SYSTEM_DIR = 1<<6;
public final static int PARSE_IS_PRIVILEGED = 1<<7;
- public final static int PARSE_GET_SIGNATURES = 1<<8;
+ public final static int PARSE_COLLECT_CERTIFICATES = 1<<8;
public final static int PARSE_TRUSTED_OVERLAY = 1<<9;
private static final Comparator<String> sSplitNameComparator = new SplitNameComparator();
@@ -1087,34 +1087,6 @@
}
}
- /**
- * Only collect certificates on the manifest; does not validate signatures
- * across remainder of package.
- */
- private static Signature[] collectManifestCertificates(File apkFile)
- throws PackageParserException {
- final String apkPath = apkFile.getAbsolutePath();
- try {
- final StrictJarFile jarFile = new StrictJarFile(apkPath);
- try {
- final ZipEntry jarEntry = jarFile.findEntry(ANDROID_MANIFEST_FILENAME);
- if (jarEntry == null) {
- throw new PackageParserException(INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
- "Package " + apkPath + " has no manifest");
- }
-
- final Certificate[][] certs = loadCertificates(jarFile, jarEntry);
- return convertToSignatures(certs);
-
- } finally {
- jarFile.close();
- }
- } catch (GeneralSecurityException | IOException | RuntimeException e) {
- throw new PackageParserException(INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING,
- "Failed to collect certificates from " + apkPath, e);
- }
- }
-
private static Signature[] convertToSignatures(Certificate[][] certs)
throws CertificateEncodingException {
final Signature[] res = new Signature[certs.length];
@@ -1129,7 +1101,8 @@
* file, including package name, split name, and install location.
*
* @param apkFile path to a single APK
- * @param flags optional parse flags, such as {@link #PARSE_GET_SIGNATURES}
+ * @param flags optional parse flags, such as
+ * {@link #PARSE_COLLECT_CERTIFICATES}
*/
public static ApkLite parseApkLite(File apkFile, int flags)
throws PackageParserException {
@@ -1154,11 +1127,12 @@
final Resources res = new Resources(assets, metrics, null);
parser = assets.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME);
- // Only collect certificates on the manifest; does not validate
- // signatures across remainder of package.
final Signature[] signatures;
- if ((flags & PARSE_GET_SIGNATURES) != 0) {
- signatures = collectManifestCertificates(apkFile);
+ if ((flags & PARSE_COLLECT_CERTIFICATES) != 0) {
+ // TODO: factor signature related items out of Package object
+ final Package tempPkg = new Package(null);
+ collectCertificates(tempPkg, apkFile, 0);
+ signatures = tempPkg.mSignatures;
} else {
signatures = null;
}
diff --git a/core/java/android/content/res/ResourcesKey.java b/core/java/android/content/res/ResourcesKey.java
index 53e0f2c..e0f1b3a 100644
--- a/core/java/android/content/res/ResourcesKey.java
+++ b/core/java/android/content/res/ResourcesKey.java
@@ -62,8 +62,12 @@
return false;
}
ResourcesKey peer = (ResourcesKey) obj;
- if (!mResDir.equals(peer.mResDir)) {
- return false;
+ if (mResDir != peer.mResDir) {
+ if (mResDir == null || peer.mResDir == null) {
+ return false;
+ } else if (!mResDir.equals(peer.mResDir)) {
+ return false;
+ }
}
if (mDisplayId != peer.mDisplayId) {
return false;
diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java
index d60a2c2..b52a0c5 100644
--- a/core/java/android/hardware/Sensor.java
+++ b/core/java/android/hardware/Sensor.java
@@ -348,7 +348,7 @@
* A sensor of this type returns the number of steps taken by the user since the last reboot
* while activated. The value is returned as a float (with the fractional part set to zero) and
* is reset to zero only on a system reboot. The timestamp of the event is set to the time when
- * the first step for that event was taken. This sensor is implemented in hardware and is
+ * the last step for that event was taken. This sensor is implemented in hardware and is
* expected to be low power.
* <p>
* See {@link android.hardware.SensorEvent#values SensorEvent.values} for more details.
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 5189155..e215669 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -57,8 +57,7 @@
/**
* Key for user restrictions. Specifies if a user is disallowed from changing Wi-Fi
- * access points.
- * The default value is <code>false</code>.
+ * access points. The default value is <code>false</code>.
* <p/>
* Type: Boolean
* @see #setUserRestrictions(Bundle)
@@ -119,7 +118,7 @@
/**
* Key for user restrictions. Specifies if a user is disallowed from transferring files over
- * USB. The default value is <code>false</code>.
+ * USB. This can only be set by device owners. The default value is <code>false</code>.
* <p/>
* Type: Boolean
* @see #setUserRestrictions(Bundle)
@@ -139,8 +138,7 @@
/**
* Key for user restrictions. Specifies if a user is disallowed from removing itself and other
- * users.
- * The default value is <code>false</code>.
+ * users. The default value is <code>false</code>.
* <p/>
* Type: Boolean
* @see #setUserRestrictions(Bundle)
@@ -170,7 +168,8 @@
/**
* Key for user restrictions. Specifies if a user is disallowed from configuring Tethering
- * & portable hotspots. The default value is <code>false</code>.
+ * & portable hotspots. This can only be set by device owners. The default value is
+ * <code>false</code>.
* <p/>
* Type: Boolean
* @see #setUserRestrictions(Bundle)
@@ -180,8 +179,8 @@
/**
* Key for user restrictions. Specifies if a user is disallowed from factory resetting
- * from Settings.
- * The default value is <code>false</code>.
+ * from Settings. This can only be set by device owners. The default value is
+ * <code>false</code>.
* <p>
* @see #setUserRestrictions(Bundle)
* @see #getUserRestrictions()
@@ -190,7 +189,7 @@
/**
* Key for user restrictions. Specifies if a user is disallowed from adding new users and
- * profiles. The default value is <code>false</code>.
+ * profiles. This can only be set by device owners. The default value is <code>false</code>.
* <p>
* Type: Boolean
* @see #setUserRestrictions(Bundle)
@@ -210,7 +209,7 @@
/**
* Key for user restrictions. Specifies if a user is disallowed from configuring cell
- * broadcasts. The default value is <code>false</code>.
+ * broadcasts. This can only be set by device owners. The default value is <code>false</code>.
* <p>
* Type: Boolean
* @see #setUserRestrictions(Bundle)
@@ -220,7 +219,7 @@
/**
* Key for user restrictions. Specifies if a user is disallowed from configuring mobile
- * networks. The default value is <code>false</code>.
+ * networks. This can only be set by device owners. The default value is <code>false</code>.
* <p>
* Type: Boolean
* @see #setUserRestrictions(Bundle)
@@ -249,7 +248,8 @@
/**
* Key for user restrictions. Specifies if a user is disallowed from mounting
- * physical external media. The default value is <code>false</code>.
+ * physical external media. This can only be set by device owners. The default value is
+ * <code>false</code>.
* <p/>
* Type: Boolean
* @see #setUserRestrictions(Bundle)
@@ -259,7 +259,7 @@
/**
* Key for user restrictions. Specifies if a user is disallowed from adjusting microphone
- * volume.
+ * volume. If set, the microphone will be muted. This can only be set by device owners.
* The default value is <code>false</code>.
* <p/>
* Type: Boolean
@@ -270,7 +270,7 @@
/**
* Key for user restrictions. Specifies if a user is disallowed from adjusting the master
- * volume.
+ * volume. If set, the master volume will be muted. This can only be set by device owners.
* The default value is <code>false</code>.
* <p/>
* Type: Boolean
@@ -292,8 +292,7 @@
/**
* Key for user restrictions. Specifies that the user is not allowed to send or receive
- * SMS messages.
- * The default value is <code>false</code>.
+ * SMS messages. This can only be set by device owners. The default value is <code>false</code>.
* <p/>
* Type: Boolean
* @see #setUserRestrictions(Bundle)
@@ -311,7 +310,7 @@
* <li>{@link LayoutParams#TYPE_SYSTEM_ERROR}</li>
* <li>{@link LayoutParams#TYPE_SYSTEM_OVERLAY}</li>
*
- * <p>The default value is <code>false</code>.
+ * <p>This can only be set by device owners. The default value is <code>false</code>.
* <p/>
* Type: Boolean
* @see #setUserRestrictions(Bundle)
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 8c9b819..de90899 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -349,6 +349,8 @@
*/
abstract HardwareLayer createTextureLayer();
+ abstract void buildLayer(RenderNode node);
+
abstract boolean copyLayerInto(HardwareLayer layer, Bitmap bitmap);
/**
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index f9333d5..50341fc 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -332,6 +332,11 @@
}
@Override
+ void buildLayer(RenderNode node) {
+ nBuildLayer(mNativeProxy, node.getNativeDisplayList());
+ }
+
+ @Override
boolean copyLayerInto(final HardwareLayer layer, final Bitmap bitmap) {
return nCopyLayerInto(mNativeProxy,
layer.getDeferredLayerUpdater(), bitmap.mNativeBitmap);
@@ -468,6 +473,7 @@
private static native long nCreateDisplayListLayer(long nativeProxy, int width, int height);
private static native long nCreateTextureLayer(long nativeProxy);
+ private static native void nBuildLayer(long nativeProxy, long node);
private static native boolean nCopyLayerInto(long nativeProxy, long layer, long bitmap);
private static native void nPushLayerUpdate(long nativeProxy, long layer);
private static native void nCancelLayerUpdate(long nativeProxy, long layer);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 3adc41a..243d7d7 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4047,6 +4047,10 @@
mBackgroundTintMode = Drawable.parseTintMode(a.getInt(
R.styleable.View_backgroundTintMode, -1), mBackgroundTintMode);
break;
+ case R.styleable.View_outlineProvider:
+ setOutlineProviderFromAttribute(a.getInt(R.styleable.View_outlineProvider,
+ PROVIDER_BACKGROUND));
+ break;
}
}
@@ -10824,14 +10828,6 @@
}
/**
- * Deprecated, pending removal
- *
- * @hide
- */
- @Deprecated
- public void setOutline(@Nullable Outline outline) {}
-
- /**
* Returns whether the Outline should be used to clip the contents of the View.
* <p>
* Note that this flag will only be respected if the View's Outline returns true from
@@ -10860,6 +10856,28 @@
}
}
+ // correspond to the enum values of View_outlineProvider
+ private static final int PROVIDER_BACKGROUND = 0;
+ private static final int PROVIDER_NONE = 1;
+ private static final int PROVIDER_BOUNDS = 2;
+ private static final int PROVIDER_PADDED_BOUNDS = 3;
+ private void setOutlineProviderFromAttribute(int providerInt) {
+ switch (providerInt) {
+ case PROVIDER_BACKGROUND:
+ setOutlineProvider(ViewOutlineProvider.BACKGROUND);
+ break;
+ case PROVIDER_NONE:
+ setOutlineProvider(null);
+ break;
+ case PROVIDER_BOUNDS:
+ setOutlineProvider(ViewOutlineProvider.BOUNDS);
+ break;
+ case PROVIDER_PADDED_BOUNDS:
+ setOutlineProvider(ViewOutlineProvider.PADDED_BOUNDS);
+ break;
+ }
+ }
+
/**
* Sets the {@link ViewOutlineProvider} of the view, which generates the Outline that defines
* the shape of the shadow it casts, and enables outline clipping.
@@ -13640,11 +13658,10 @@
switch (mLayerType) {
case LAYER_TYPE_HARDWARE:
- // The only part of a hardware layer we can build in response to
- // this call is to ensure the display list is up to date.
- // The actual rendering of the display list into the layer must
- // be done at playback time
updateDisplayListIfDirty();
+ if (attachInfo.mHardwareRenderer != null && mRenderNode.isValid()) {
+ attachInfo.mHardwareRenderer.buildLayer(mRenderNode);
+ }
break;
case LAYER_TYPE_SOFTWARE:
buildDrawingCache(true);
diff --git a/core/java/android/view/ViewOutlineProvider.java b/core/java/android/view/ViewOutlineProvider.java
index 170c5d8..a1a02f6 100644
--- a/core/java/android/view/ViewOutlineProvider.java
+++ b/core/java/android/view/ViewOutlineProvider.java
@@ -44,6 +44,35 @@
};
/**
+ * Maintains the outline of the View to match its rectangular bounds,
+ * at <code>1.0f</code> alpha.
+ *
+ * This can be used to enable Views that are opaque but lacking a background cast a shadow.
+ */
+ public static final ViewOutlineProvider BOUNDS = new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ outline.setRect(0, 0, view.getWidth(), view.getHeight());
+ }
+ };
+
+ /**
+ * Maintains the outline of the View to match its rectangular padded bounds,
+ * at <code>1.0f</code> alpha.
+ *
+ * This can be used to enable Views that are opaque but lacking a background cast a shadow.
+ */
+ public static final ViewOutlineProvider PADDED_BOUNDS = new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ outline.setRect(view.getPaddingLeft(),
+ view.getPaddingTop(),
+ view.getWidth() - view.getPaddingRight(),
+ view.getHeight() - view.getPaddingBottom());
+ }
+ };
+
+ /**
* Called to get the provider to populate the Outline.
*
* This method will be called by a View when its owned Drawables are invalidated, when the
diff --git a/core/java/android/widget/SimpleMonthView.java b/core/java/android/widget/SimpleMonthView.java
index a0d9475..27763eb 100644
--- a/core/java/android/widget/SimpleMonthView.java
+++ b/core/java/android/widget/SimpleMonthView.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.content.res.ColorStateList;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
@@ -38,6 +39,7 @@
import com.android.internal.R;
import com.android.internal.widget.ExploreByTouchHelper;
+import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Formatter;
import java.util.List;
@@ -72,6 +74,9 @@
// used for scaling to the device density
private static float mScale = 0;
+ /** Single-letter (when available) formatter for the day of week label. */
+ private SimpleDateFormat mDayFormatter = new SimpleDateFormat("EEEEE", Locale.getDefault());
+
// affects the padding on the sides of this view
private int mPadding = 0;
@@ -181,6 +186,13 @@
initView();
}
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+
+ mDayFormatter = new SimpleDateFormat("EEEEE", newConfig.locale);
+ }
+
void setTextColor(ColorStateList colors) {
final Resources res = getContext().getResources();
@@ -426,16 +438,16 @@
}
private void drawWeekDayLabels(Canvas canvas) {
- int y = mMonthHeaderSize - (mMonthDayLabelTextSize / 2);
- int dayWidthHalf = (mWidth - mPadding * 2) / (mNumDays * 2);
+ final int y = mMonthHeaderSize - (mMonthDayLabelTextSize / 2);
+ final int dayWidthHalf = (mWidth - mPadding * 2) / (mNumDays * 2);
for (int i = 0; i < mNumDays; i++) {
- int calendarDay = (i + mWeekStart) % mNumDays;
- int x = (2 * i + 1) * dayWidthHalf + mPadding;
+ final int calendarDay = (i + mWeekStart) % mNumDays;
mDayLabelCalendar.set(Calendar.DAY_OF_WEEK, calendarDay);
- canvas.drawText("" + mDayLabelCalendar.getDisplayName(Calendar.DAY_OF_WEEK,
- Calendar.SHORT, Locale.getDefault()).toUpperCase(Locale.getDefault()).charAt(0),
- x, y, mMonthDayLabelPaint);
+
+ final String dayLabel = mDayFormatter.format(mDayLabelCalendar.getTime());
+ final int x = (2 * i + 1) * dayWidthHalf + mPadding;
+ canvas.drawText(dayLabel, x, y, mMonthDayLabelPaint);
}
}
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 636c712..61b4567 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -22,6 +22,7 @@
import android.app.usage.UsageStatsManager;
import android.os.AsyncTask;
import android.provider.Settings;
+import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Slog;
import android.widget.AbsListView;
@@ -278,12 +279,15 @@
});
}
- final TextView titleView = (TextView) findViewById(R.id.title);
- if (titleView != null) {
- if (title == null) {
- title = getTitleForAction(intent.getAction(), defaultTitleRes);
+ if (title == null) {
+ title = getTitleForAction(intent.getAction(), defaultTitleRes);
+ }
+ if (!TextUtils.isEmpty(title)) {
+ final TextView titleView = (TextView) findViewById(R.id.title);
+ if (titleView != null) {
+ titleView.setText(title);
}
- titleView.setText(title);
+ setTitle(title);
}
final ImageView iconView = (ImageView) findViewById(R.id.icon);
diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java
index d76d0d4..179d5e8 100644
--- a/core/java/com/android/internal/content/NativeLibraryHelper.java
+++ b/core/java/com/android/internal/content/NativeLibraryHelper.java
@@ -19,15 +19,25 @@
import static android.content.pm.PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS;
import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
import static android.content.pm.PackageManager.NO_NATIVE_LIBRARIES;
+import static android.system.OsConstants.S_IRGRP;
+import static android.system.OsConstants.S_IROTH;
+import static android.system.OsConstants.S_IRWXU;
+import static android.system.OsConstants.S_IXGRP;
+import static android.system.OsConstants.S_IXOTH;
import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
import android.content.pm.PackageParser.Package;
import android.content.pm.PackageParser.PackageLite;
import android.content.pm.PackageParser.PackageParserException;
+import android.os.Build;
+import android.os.SELinux;
+import android.system.ErrnoException;
+import android.system.Os;
import android.util.Slog;
import dalvik.system.CloseGuard;
+import dalvik.system.VMRuntime;
import java.io.Closeable;
import java.io.File;
@@ -44,6 +54,10 @@
private static final boolean DEBUG_NATIVE = false;
+ // Special value for {@code PackageParser.Package#cpuAbiOverride} to indicate
+ // that the cpuAbiOverride must be clear.
+ public static final String CLEAR_ABI_OVERRIDE = "-";
+
/**
* A handle to an opened package, consisting of one or more APKs. Used as
* input to the various NativeLibraryHelper methods. Allows us to scan and
@@ -126,27 +140,17 @@
private static native long nativeSumNativeBinaries(long handle, String cpuAbi);
- /**
- * Sums the size of native binaries in an APK for a given ABI.
- *
- * @return size of all native binary files in bytes
- */
- public static long sumNativeBinariesLI(Handle handle, String[] abis) {
+ private native static int nativeCopyNativeBinaries(long handle,
+ String sharedLibraryPath, String abiToCopy);
+
+ private static long sumNativeBinaries(Handle handle, String abi) {
long sum = 0;
for (long apkHandle : handle.apkHandles) {
- // NOTE: For a given APK handle, we parse the central directory precisely
- // once, but prefix matching of entries requires a CD traversal, which can
- // take a while (even if it needs no additional I/O).
- for (String abi : abis) {
- sum += nativeSumNativeBinaries(apkHandle, abi);
- }
+ sum += nativeSumNativeBinaries(apkHandle, abi);
}
return sum;
}
- private native static int nativeCopyNativeBinaries(long handle,
- String sharedLibraryPath, String abiToCopy);
-
/**
* Copies native binaries to a shared library directory.
*
@@ -244,9 +248,171 @@
}
}
+ private static void createNativeLibrarySubdir(File path) throws IOException {
+ if (!path.isDirectory()) {
+ path.delete();
+
+ if (!path.mkdir()) {
+ throw new IOException("Cannot create " + path.getPath());
+ }
+
+ try {
+ Os.chmod(path.getPath(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
+ } catch (ErrnoException e) {
+ throw new IOException("Cannot chmod native library directory "
+ + path.getPath(), e);
+ }
+ } else if (!SELinux.restorecon(path)) {
+ throw new IOException("Cannot set SELinux context for " + path.getPath());
+ }
+ }
+
+ private static long sumNativeBinaries(Handle handle, String[] abiList) {
+ int abi = findSupportedAbi(handle, abiList);
+ if (abi >= 0) {
+ return sumNativeBinaries(handle, abiList[abi]);
+ } else {
+ return 0;
+ }
+ }
+
+ public static int copyNativeBinariesIfNeededLI(Handle handle, File libraryRoot,
+ String[] abiList, boolean useIsaSubdir) throws IOException {
+ createNativeLibrarySubdir(libraryRoot);
+
+ /*
+ * If this is an internal application or our nativeLibraryPath points to
+ * the app-lib directory, unpack the libraries if necessary.
+ */
+ int abi = findSupportedAbi(handle, abiList);
+ if (abi >= 0) {
+ /*
+ * If we have a matching instruction set, construct a subdir under the native
+ * library root that corresponds to this instruction set.
+ */
+ final String instructionSet = VMRuntime.getInstructionSet(abiList[abi]);
+ final File subDir;
+ if (useIsaSubdir) {
+ final File isaSubdir = new File(libraryRoot, instructionSet);
+ createNativeLibrarySubdir(isaSubdir);
+ subDir = isaSubdir;
+ } else {
+ subDir = libraryRoot;
+ }
+
+ int copyRet = copyNativeBinariesIfNeededLI(handle, subDir, abiList[abi]);
+ if (copyRet != PackageManager.INSTALL_SUCCEEDED) {
+ return copyRet;
+ }
+ }
+
+ return abi;
+ }
+
+ public static int copyNativeBinariesIfNeededLI(Handle handle, File libraryRoot,
+ String abiOverride, boolean multiArch) {
+ try {
+ if (multiArch) {
+ // Warn if we've set an abiOverride for multi-lib packages..
+ // By definition, we need to copy both 32 and 64 bit libraries for
+ // such packages.
+ if (abiOverride != null && !CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
+ Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
+ }
+
+ int copyRet = PackageManager.NO_NATIVE_LIBRARIES;
+ if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
+ copyRet = copyNativeBinariesIfNeededLI(handle, libraryRoot,
+ Build.SUPPORTED_32_BIT_ABIS, true /* use isa specific subdirs */);
+ if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
+ copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
+ Slog.w(TAG, "Failure copying 32 bit native libraries; copyRet=" +copyRet);
+ return copyRet;
+ }
+ }
+
+ if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
+ copyRet = copyNativeBinariesIfNeededLI(handle, libraryRoot,
+ Build.SUPPORTED_64_BIT_ABIS, true /* use isa specific subdirs */);
+ if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
+ copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
+ Slog.w(TAG, "Failure copying 64 bit native libraries; copyRet=" +copyRet);
+ return copyRet;
+ }
+ }
+ } else {
+ String cpuAbiOverride = null;
+ if (CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
+ cpuAbiOverride = null;
+ } else if (abiOverride != null) {
+ cpuAbiOverride = abiOverride;
+ }
+
+ String[] abiList = (cpuAbiOverride != null) ?
+ new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
+ if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
+ hasRenderscriptBitcode(handle)) {
+ abiList = Build.SUPPORTED_32_BIT_ABIS;
+ }
+
+ int copyRet = copyNativeBinariesIfNeededLI(handle, libraryRoot, abiList,
+ true /* use isa specific subdirs */);
+ if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
+ Slog.w(TAG, "Failure copying native libraries [errorCode=" + copyRet + "]");
+ return copyRet;
+ }
+ }
+
+ return PackageManager.INSTALL_SUCCEEDED;
+ } catch (IOException e) {
+ Slog.e(TAG, "Copying native libraries failed", e);
+ return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+ }
+ }
+
+ public static long sumNativeBinaries(Handle handle, String abiOverride, boolean multiArch)
+ throws IOException {
+ long sum = 0;
+ if (multiArch) {
+ // Warn if we've set an abiOverride for multi-lib packages..
+ // By definition, we need to copy both 32 and 64 bit libraries for
+ // such packages.
+ if (abiOverride != null && !CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
+ Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
+ }
+
+ if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
+ sum += sumNativeBinaries(handle, Build.SUPPORTED_32_BIT_ABIS);
+ }
+
+ if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
+ sum += sumNativeBinaries(handle, Build.SUPPORTED_64_BIT_ABIS);
+ }
+ } else {
+ String cpuAbiOverride = null;
+ if (CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
+ cpuAbiOverride = null;
+ } else if (abiOverride != null) {
+ cpuAbiOverride = abiOverride;
+ }
+
+ String[] abiList = (cpuAbiOverride != null) ?
+ new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
+ if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
+ hasRenderscriptBitcode(handle)) {
+ abiList = Build.SUPPORTED_32_BIT_ABIS;
+ }
+
+ sum += sumNativeBinaries(handle, abiList);
+ }
+ return sum;
+ }
+
// We don't care about the other return values for now.
private static final int BITCODE_PRESENT = 1;
+ private static native int hasRenderscriptBitcode(long apkHandle);
+
public static boolean hasRenderscriptBitcode(Handle handle) throws IOException {
for (long apkHandle : handle.apkHandles) {
final int res = hasRenderscriptBitcode(apkHandle);
@@ -258,6 +424,4 @@
}
return false;
}
-
- private static native int hasRenderscriptBitcode(long apkHandle);
}
diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java
index fd96f64..a529cc3 100644
--- a/core/java/com/android/internal/content/PackageHelper.java
+++ b/core/java/com/android/internal/content/PackageHelper.java
@@ -17,13 +17,17 @@
package com.android.internal.content;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Environment;
+import android.os.Environment.UserEnvironment;
import android.os.FileUtils;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.UserHandle;
import android.os.storage.IMountService;
import android.os.storage.StorageManager;
import android.os.storage.StorageResultCode;
@@ -215,7 +219,7 @@
/**
* Extract public files for the single given APK.
*/
- public static int extractPublicFiles(String apkPath, File publicZipFile)
+ public static long extractPublicFiles(File apkFile, File publicZipFile)
throws IOException {
final FileOutputStream fstr;
final ZipOutputStream publicZipOutStream;
@@ -226,12 +230,13 @@
} else {
fstr = new FileOutputStream(publicZipFile);
publicZipOutStream = new ZipOutputStream(fstr);
+ Log.d(TAG, "Extracting " + apkFile + " to " + publicZipFile);
}
- int size = 0;
+ long size = 0L;
try {
- final ZipFile privateZip = new ZipFile(apkPath);
+ final ZipFile privateZip = new ZipFile(apkFile.getAbsolutePath());
try {
// Copy manifest, resources.arsc and res directory to public zip
for (final ZipEntry zipEntry : Collections.list(privateZip.entries())) {
@@ -308,8 +313,15 @@
* Given a requested {@link PackageInfo#installLocation} and calculated
* install size, pick the actual location to install the app.
*/
- public static int resolveInstallLocation(Context context, int installLocation, long sizeBytes,
- int installFlags) {
+ public static int resolveInstallLocation(Context context, String packageName,
+ int installLocation, long sizeBytes, int installFlags) {
+ ApplicationInfo existingInfo = null;
+ try {
+ existingInfo = context.getPackageManager().getApplicationInfo(packageName,
+ PackageManager.GET_UNINSTALLED_PACKAGES);
+ } catch (NameNotFoundException ignored) {
+ }
+
final int prefer;
final boolean checkBoth;
if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
@@ -325,7 +337,16 @@
prefer = RECOMMEND_INSTALL_EXTERNAL;
checkBoth = true;
} else if (installLocation == PackageInfo.INSTALL_LOCATION_AUTO) {
- prefer = RECOMMEND_INSTALL_INTERNAL;
+ // When app is already installed, prefer same medium
+ if (existingInfo != null) {
+ if ((existingInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
+ prefer = RECOMMEND_INSTALL_EXTERNAL;
+ } else {
+ prefer = RECOMMEND_INSTALL_INTERNAL;
+ }
+ } else {
+ prefer = RECOMMEND_INSTALL_INTERNAL;
+ }
checkBoth = true;
} else {
prefer = RECOMMEND_INSTALL_INTERNAL;
@@ -337,14 +358,15 @@
boolean fitsOnInternal = false;
if (checkBoth || prefer == RECOMMEND_INSTALL_INTERNAL) {
- fitsOnInternal = (sizeBytes
- <= storage.getStorageBytesUntilLow(Environment.getDataDirectory()));
+ final File target = Environment.getDataDirectory();
+ fitsOnInternal = (sizeBytes <= storage.getStorageBytesUntilLow(target));
}
boolean fitsOnExternal = false;
if (!emulated && (checkBoth || prefer == RECOMMEND_INSTALL_EXTERNAL)) {
- fitsOnExternal = (sizeBytes
- <= storage.getStorageBytesUntilLow(Environment.getExternalStorageDirectory()));
+ final File target = new UserEnvironment(UserHandle.USER_OWNER)
+ .getExternalStorageDirectory();
+ fitsOnExternal = (sizeBytes <= storage.getStorageBytesUntilLow(target));
}
if (prefer == RECOMMEND_INSTALL_INTERNAL) {
@@ -377,4 +399,12 @@
return PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
}
}
+
+ public static String replaceEnd(String str, String before, String after) {
+ if (!str.endsWith(before)) {
+ throw new IllegalArgumentException(
+ "Expected " + str + " to end with " + before);
+ }
+ return str.substring(0, str.length() - before.length()) + after;
+ }
}
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index d183d8e..4e3419a 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -264,6 +264,13 @@
return reinterpret_cast<jlong>(layer);
}
+static void android_view_ThreadedRenderer_buildLayer(JNIEnv* env, jobject clazz,
+ jlong proxyPtr, jlong nodePtr) {
+ RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+ RenderNode* node = reinterpret_cast<RenderNode*>(nodePtr);
+ proxy->buildLayer(node);
+}
+
static jboolean android_view_ThreadedRenderer_copyLayerInto(JNIEnv* env, jobject clazz,
jlong proxyPtr, jlong layerPtr, jlong bitmapPtr) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
@@ -367,6 +374,7 @@
{ "nInvokeFunctor", "(JZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor },
{ "nCreateDisplayListLayer", "(JII)J", (void*) android_view_ThreadedRenderer_createDisplayListLayer },
{ "nCreateTextureLayer", "(J)J", (void*) android_view_ThreadedRenderer_createTextureLayer },
+ { "nBuildLayer", "(JJ)V", (void*) android_view_ThreadedRenderer_buildLayer },
{ "nCopyLayerInto", "(JJJ)Z", (void*) android_view_ThreadedRenderer_copyLayerInto },
{ "nPushLayerUpdate", "(JJ)V", (void*) android_view_ThreadedRenderer_pushLayerUpdate },
{ "nCancelLayerUpdate", "(JJ)V", (void*) android_view_ThreadedRenderer_cancelLayerUpdate },
diff --git a/core/res/res/anim/progress_indeterminate_horizontal_rect1.xml b/core/res/res/anim/progress_indeterminate_horizontal_rect1.xml
new file mode 100644
index 0000000..980c8e4
--- /dev/null
+++ b/core/res/res/anim/progress_indeterminate_horizontal_rect1.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="2000"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:repeatCount="infinite"
+ android:pathData="M -522.59998 0 l 0.0 0 l 0.0 0 l 0.0 0 l 0.0 0 l 0.0 0 l 0.0 0 l 0.0 0 l 0.0 0 l 0.0 0 l 0.0 0 l 0.0 0 l 0.0 0 l 0.0 0 l 0.0 0 l 0.0 0 l 0.0 0 l 0.0 0 l 0.0 0 l 0.0 0 l 0.0 0 l 0.0 0 l 0.0 0 l 0.0 0 l 0.0 0 l 0.1294 0 l 0.33832 0 l 0.5545 0 l 0.77088 0 l 0.98065 0 l 1.19641 0 l 1.41351 0 l 1.63153 0 l 1.85053 0 l 2.07052 0 l 2.29081 0 l 2.5115 0 l 2.73261 0 l 2.95355 0 l 3.17404 0 l 3.39423 0 l 3.61355 0 l 3.83164 0 l 4.04849 0 l 4.26367 0 l 5.74725 0 l 6.10266 0 l 6.45981 0 l 6.81781 0 l 7.17655 0 l 7.53366 0 l 7.88861 0 l 8.23975 0 l 8.58447 0 l 8.92157 0 l 9.24811 0 l 9.56137 0 l 9.85907 0 l 10.13778 0 l 10.39557 0 l 10.62876 0 l 10.83572 0 l 11.01492 0 l 11.16397 0 l 11.28324 0 l 11.3714 0 l 11.43011 0 l 11.45966 0 l 11.4611 0 l 11.43691 0 l 11.38878 0 l 11.31834 0 l 11.2276 0 l 11.11856 0 l 10.99338 0 l 10.85347 0 l 10.69954 0 l 10.53393 0 l 10.37447 0 l 10.37077 0 l 10.43095 0 l 10.52757 0 l 10.6715 0 l 10.8764 0 l 11.15665 0 l 11.52708 0 l 11.9948 0 l 12.55024 0 l 13.14534 0 l 13.68079 0 l 14.02233 0 l 14.06503 0 l 13.79804 0 l 13.295 0 l 12.65849 0 l 11.9693 0 l 11.2773 0 l 10.60766 0 l 9.97053 0 l 9.36723 0 l 8.79752 0 l 8.25793 0 l 7.74495 0 l 7.25633 0 l 6.78856 0 l 6.33934 0 l 5.9071 0 l 5.48941 0 l 5.08502 0 l 4.69292 0 l 4.33431 0 l 4.00734 0 l 3.68829 0 l 3.37685 0 l 3.07246 0 l 2.7744 0 l 2.48253 0 l 2.20102 0 l 1.91748 0 l 1.63726 0 l 1.36773 0 "
+ android:interpolator="@interpolator/progress_indeterminate_horizontal_rect1_grp_position" />
+ <objectAnimator
+ android:duration="2000"
+ android:propertyXName="scaleX"
+ android:propertyYName="scaleY"
+ android:repeatCount="infinite"
+ android:pathData="M 0.1 1 l 0.0 0 l 0.00882427215576 0 l 0.00982859611511 0 l 0.0108650398254 0 l 0.011930847168 0 l 0.0130220413208 0 l 0.0141334056854 0 l 0.0152582168579 0 l 0.0163880157471 0 l 0.0175127220154 0 l 0.0186203575134 0 l 0.0196973228455 0 l 0.0207285499573 0 l 0.0216978645325 0 l 0.0225887107849 0 l 0.0233847427368 0 l 0.0240707015991 0 l 0.0246334838867 0 l 0.0250626373291 0 l 0.0253514099121 0 l 0.0254969406128 0 l 0.0255004882813 0 l 0.0253670883179 0 l 0.0251052856445 0 l 0.0247262573242 0 l 0.0242431640625 0 l 0.0236701583862 0 l 0.0230218887329 0 l 0.0223124694824 0 l 0.021555557251 0 l 0.0207632446289 0 l 0.0199468231201 0 l 0.0191157531738 0 l 0.0182782745361 0 l 0.0173241424561 0 l 0.0152210998535 0 l 0.0126258087158 0 l 0.00973388671875 0 l 0.00647575378418 0 l 0.00276618957519 0 l -0.00149223327636 0 l -0.00639404296875 0 l -0.0119906616211 0 l -0.0182067108154 0 l -0.0247090148926 0 l -0.0308044433594 0 l -0.0355574798584 0 l -0.0382397460938 0 l -0.0387688446045 0 l -0.0376621246338 0 l -0.0356225204468 0 l -0.03321434021 0 l -0.0307815170288 0 l -0.0284958267212 0 l -0.0264254379272 0 l -0.024584236145 0 l -0.0229611587524 0 l -0.0215351867676 0 l -0.0202828598023 0 l -0.0191815567017 0 l -0.018210849762 0 l -0.0173528671265 0 l -0.0165923118591 0 l -0.0159160423279 0 l -0.0153129196167 0 l -0.0147735023499 0 l -0.0141336250305 0 l -0.0133926582336 0 l -0.01270362854 0 l -0.0120610809326 0 l -0.0114603328705 0 l -0.0108972930908 0 l -0.0103683567047 0 l -0.00987038612366 0 l -0.00940062522888 0 l -0.00895661354065 0 l -0.00853617668152 0 "
+ android:interpolator="@interpolator/progress_indeterminate_horizontal_rect1_grp_scale" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/progress_indeterminate_horizontal_rect2.xml b/core/res/res/anim/progress_indeterminate_horizontal_rect2.xml
new file mode 100644
index 0000000..8f0b2e8
--- /dev/null
+++ b/core/res/res/anim/progress_indeterminate_horizontal_rect2.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="2000"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:repeatCount="infinite"
+ android:pathData="M -197.60001 0 l 1.42626 0 l 1.80754 0 l 2.18779 0 l 2.5611 0 l 2.9181 0 l 3.25482 0 l 3.5716 0 l 3.86255 0 l 4.12494 0 l 4.35758 0 l 4.56035 0 l 4.73427 0 l 4.88091 0 l 5.00271 0 l 5.10274 0 l 5.18401 0 l 5.24911 0 l 5.30098 0 l 5.34226 0 l 5.37535 0 l 5.40181 0 l 5.42322 0 l 5.44123 0 l 5.45705 0 l 5.47099 0 l 5.48396 0 l 5.4967 0 l 5.5095 0 l 5.52215 0 l 5.53528 0 l 5.54913 0 l 5.56306 0 l 5.57743 0 l 5.59244 0 l 5.60744 0 l 5.62244 0 l 5.63767 0 l 5.65263 0 l 5.6669 0 l 5.6807 0 l 5.69401 0 l 5.70899 0 l 5.7517 0 l 5.80327 0 l 5.8571 0 l 5.914 0 l 5.9745 0 l 6.03849 0 l 6.10729 0 l 6.18126 0 l 6.26117 0 l 6.3484 0 l 6.44406 0 l 6.54867 0 l 6.66372 0 l 6.79021 0 l 6.92859 0 l 7.07807 0 l 7.23712 0 l 7.40254 0 l 7.56885 0 l 7.72841 0 l 7.87199 0 l 7.98993 0 l 8.07417 0 l 8.12013 0 l 8.12656 0 l 8.09511 0 l 8.03091 0 l 7.93996 0 l 7.82788 0 l 7.69977 0 l 7.56065 0 l 7.41323 0 l 7.26063 0 l 7.10471 0 l 6.94624 0 l 6.78694 0 l 6.63904 0 l 6.50302 0 l 6.36688 0 l 6.23044 0 l 6.09357 0 l 5.95706 0 l 5.82065 0 l 5.68396 0 l 5.54773 0 l 5.41144 0 l 5.27533 0 l 5.13922 0 l 5.00348 0 l 4.86804 0 l 4.73251 0 l 4.59732 0 l 4.46259 0 l 4.32812 0 l 4.19373 0 l 4.05993 0 l 3.92673 0 l 3.79376 0 l 3.6612 0 l 3.52936 0 l 3.39819 0 l 3.26749 0 l 3.13726 0 l 3.00797 0 l 2.87939 0 l 2.75159 0 l 2.62445 0 l 2.49811 0 l 2.37268 0 l 2.24817 0 l 2.12457 0 l 2.00174 0 l 1.87997 0 l 1.76185 0 l 1.64154 0 l 1.51962 0 l 1.40018 0 l 1.28421 0 "
+ android:interpolator="@interpolator/progress_indeterminate_horizontal_rect2_grp_position" />
+ <objectAnimator
+ android:duration="2000"
+ android:propertyXName="scaleX"
+ android:propertyYName="scaleY"
+ android:repeatCount="infinite"
+ android:pathData="M 0.1 1 l 0.00930031776428 0 l 0.0112302875519 0 l 0.0131314373016 0 l 0.014971075058 0 l 0.0167151069641 0 l 0.0183303451538 0 l 0.0197867202759 0 l 0.0210597610474 0 l 0.0221322822571 0 l 0.0229952049255 0 l 0.0236479568482 0 l 0.0240972709656 0 l 0.0243561935425 0 l 0.0244421386719 0 l 0.0243751525879 0 l 0.0241764450073 0 l 0.0238669586182 0 l 0.0234665298462 0 l 0.0229933547974 0 l 0.0224634552002 0 l 0.0218908691406 0 l 0.0212874603272 0 l 0.0206631851196 0 l 0.0200262451172 0 l 0.019383354187 0 l 0.0187397766113 0 l 0.018099899292 0 l 0.0174669647217 0 l 0.0168434906006 0 l 0.0162316131592 0 l 0.0156324005127 0 l 0.0150471496582 0 l 0.0144763183594 0 l 0.0139205169678 0 l 0.0133796691894 0 l 0.0128540802002 0 l 0.0123434448242 0 l 0.0118475341797 0 l 0.0113663482666 0 l 0.0108992004395 0 l 0.0104459381103 0 l 0.00998542785645 0 l 0.00933837890625 0 l 0.0086334991455 0 l 0.00791206359864 0 l 0.00717010498047 0 l 0.00640274047851 0 l 0.00560478210449 0 l 0.00477012634278 0 l 0.00389221191406 0 l 0.00296325683594 0 l 0.00197517395019 0 l 0.00091903686524 0 l -0.00021408081055 0 l -0.00143287658691 0 l -0.00274444580079 0 l -0.00415267944336 0 l -0.00565589904785 0 l -0.00724327087402 0 l -0.00889205932617 0 l -0.0105648040771 0 l -0.0122087860107 0 l -0.0137604522705 0 l -0.0151544952393 0 l -0.0163356018066 0 l -0.0172690582275 0 l -0.017946395874 0 l -0.0183829498291 0 l -0.0186113739014 0 l -0.018671798706 0 l -0.0186050415039 0 l -0.0184476470947 0 l -0.018229598999 0 l -0.017974319458 0 l -0.0176993560791 0 l -0.0174169921875 0 l -0.0171360397339 0 l -0.0168621444702 0 l -0.0165135955811 0 l -0.0160948562622 0 l -0.0156935882568 0 l -0.0153102493286 0 l -0.0149446105957 0 l -0.0145963287353 0 l -0.0142646408081 0 l -0.0139489364624 0 l -0.0136483383179 0 l -0.0133620071411 0 l -0.0130891799927 0 l -0.0128289794922 0 l -0.0125807571411 0 l -0.0123436355591 0 l -0.0121170043945 0 l -0.0119002914429 0 l -0.0116927337646 0 l -0.0114939498901 0 l -0.0113032531738 0 l -0.0111202430725 0 l -0.010944442749 0 l -0.0107754516601 0 l -0.0106128692627 0 l -0.0104563140869 0 l -0.0103054428101 0 l -0.0101600074768 0 l -0.0100196266174 0 l -0.0098840713501 0 l -0.00975311279297 0 l -0.00962644577026 0 l -0.00950393676758 0 l -0.00938529968262 0 l -0.00927038192749 0 l -0.00915899276733 0 l -0.00905097961426 0 l -0.00894614219665 0 l -0.0088443851471 0 l -0.00874552726745 0 l -0.00864946365357 0 l -0.00855606079101 0 l -0.00846519470215 0 l -0.00837676048279 0 "
+ android:interpolator="@interpolator/progress_indeterminate_horizontal_rect2_grp_scale" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/drawable/progress_indeterminate_horizontal_material.xml b/core/res/res/drawable/progress_indeterminate_horizontal_material.xml
index 4fc68ce..e92f090 100644
--- a/core/res/res/drawable/progress_indeterminate_horizontal_material.xml
+++ b/core/res/res/drawable/progress_indeterminate_horizontal_material.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2014 The Android Open Source Project
@@ -14,20 +13,13 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/vector_drawable_progress_indeterminate_horizontal" >
-
<target
- android:name="path1"
- android:animation="@anim/progress_indeterminate_horizontal_rect1_translate" />
+ android:name="rect2_grp"
+ android:animation="@anim/progress_indeterminate_horizontal_rect2" />
<target
- android:name="path1"
- android:animation="@anim/progress_indeterminate_horizontal_rect1_scale" />
-
- <target
- android:name="path2"
- android:animation="@anim/progress_indeterminate_horizontal_rect2_translate" />
- <target
- android:name="path2"
- android:animation="@anim/progress_indeterminate_horizontal_rect2_scale" />
-</animated-vector>
+ android:name="rect1_grp"
+ android:animation="@anim/progress_indeterminate_horizontal_rect1" />
+</animated-vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/vector_drawable_progress_indeterminate_horizontal.xml b/core/res/res/drawable/vector_drawable_progress_indeterminate_horizontal.xml
index 0cc7202..7ceb772 100644
--- a/core/res/res/drawable/vector_drawable_progress_indeterminate_horizontal.xml
+++ b/core/res/res/drawable/vector_drawable_progress_indeterminate_horizontal.xml
@@ -13,48 +13,47 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<!--
- Copyright (C) 2014 The Android Open Source Project
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="4dp"
- android:viewportHeight="4"
+ android:height="10dp"
+ android:viewportHeight="10"
android:viewportWidth="360"
android:width="360dp" >
<group
- android:name="linear_indeterminate"
- android:translateX="180.0"
- android:translateY="0.0" >
- <group
- android:name="path1"
- android:scaleX="0.1"
- android:translateX="-522.59" >
- <path
- android:name="rect1"
- android:fillColor="?attr/colorControlActivated"
- android:pathData="m 0 1.6 l 288 0 l 0 0.8 l -288 0 z" />
- </group>
- <group
- android:name="path2"
- android:scaleX="0.1"
- android:translateX="-197.6" >
- <path
- android:name="rect2"
- android:fillColor="?attr/colorControlActivated"
- android:pathData="m 0 1.6 l 288 0 l 0 0.8 l -288 0 z" />
+ android:name="v21"
+ android:translateX="180"
+ android:translateY="5" >
+ <group android:name="v21_pivot" >
+ <group
+ android:name="rectangle_path_1_position"
+ android:alpha="0.1" >
+ <path
+ android:name="rectangle_path_1"
+ android:fillColor="?attr/colorControlActivated"
+ android:pathData="M -180.0 -1.0 l 360 0 l 0 2 l -360 0 Z" />
+ </group>
+ <group
+ android:name="rect2_grp"
+ android:scaleX="0.1"
+ android:scaleY="1"
+ android:translateX="-197.60001" >
+ <path
+ android:name="rect2"
+ android:fillColor="?attr/colorControlActivated"
+ android:pathData="M -144.0 -1.0 l 288 0 l 0 2 l -288 0 Z" />
+ </group>
+ <group
+ android:name="rect1_grp"
+ android:scaleX="0.1"
+ android:scaleY="1"
+ android:translateX="-522.59998" >
+ <path
+ android:name="rect1"
+ android:fillColor="?attr/colorControlActivated"
+ android:pathData="M -144.0 -1.0 l 288 0 l 0 2 l -288 0 Z" />
+ </group>
</group>
</group>
+
</vector>
\ No newline at end of file
diff --git a/core/res/res/interpolator/progress_indeterminate_horizontal_rect1_grp_position.xml b/core/res/res/interpolator/progress_indeterminate_horizontal_rect1_grp_position.xml
new file mode 100644
index 0000000..1e5490b
--- /dev/null
+++ b/core/res/res/interpolator/progress_indeterminate_horizontal_rect1_grp_position.xml
@@ -0,0 +1,17 @@
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0 0.0 L 0.00833333333334 0.0 L 0.0166666666667 0.0 L 0.025 0.0 L 0.0333333333333 0.0 L 0.0416666666667 0.0 L 0.05 0.0 L 0.0583333333333 0.0 L 0.0666666666667 0.0 L 0.075 0.0 L 0.0833333333333 0.0 L 0.0916666666667 0.0 L 0.1 0.0 L 0.108333333333 0.0 L 0.116666666667 0.0 L 0.125 0.0 L 0.133333333333 0.0 L 0.141666666667 0.0 L 0.15 0.0 L 0.158333333333 0.0 L 0.166666666667 0.0 L 0.175 0.0 L 0.183333333333 0.0 L 0.191666666667 0.0 L 0.2 0.0 L 0.208333333333 0.000179174746319 L 0.216666666667 0.000647632243805 L 0.225 0.0014154251096 L 0.233333333333 0.00248283027531 L 0.241666666667 0.00384069515149 L 0.25 0.00549731383962 L 0.258333333333 0.00745454178143 L 0.266666666667 0.00971365286228 L 0.275 0.012276004047 L 0.283333333333 0.0151429661471 L 0.291666666667 0.0183149545599 L 0.3 0.0217925231486 L 0.308333333333 0.0255762534696 L 0.316666666667 0.0296659101311 L 0.325 0.0340608700368 L 0.333333333333 0.0387607177895 L 0.341666666667 0.0437642487367 L 0.35 0.049069759749 L 0.358333333333 0.0546755338504 L 0.366666666667 0.0605792586621 L 0.375 0.0685372344023 L 0.383333333333 0.0769873314454 L 0.391666666667 0.0859319590963 L 0.4 0.0953722943142 L 0.408333333333 0.105309361746 L 0.416666666667 0.1157409044 L 0.425 0.126663931413 L 0.433333333333 0.13807316724 L 0.441666666667 0.149959722376 L 0.45 0.162313045726 L 0.458333333333 0.175118515302 L 0.466666666667 0.188357742846 L 0.475 0.20200918308 L 0.483333333333 0.216046541347 L 0.491666666667 0.230440850602 L 0.5 0.245158048258 L 0.508333333333 0.260161814735 L 0.516666666667 0.275413711928 L 0.525 0.290871992396 L 0.533333333333 0.306495421026 L 0.541666666667 0.322240921106 L 0.55 0.338067714457 L 0.558333333333 0.353935424452 L 0.566666666667 0.369805128355 L 0.575 0.385641337381 L 0.583333333333 0.401410902817 L 0.591666666667 0.417082932942 L 0.6 0.4326293192 L 0.608333333333 0.448024722349 L 0.616666666667 0.463246794008 L 0.625 0.478275138165 L 0.633333333333 0.493090341915 L 0.641666666667 0.507676232452 L 0.65 0.522041325423 L 0.658333333333 0.536401295159 L 0.666666666667 0.550844593615 L 0.675 0.565421677727 L 0.683333333333 0.580198055666 L 0.691666666667 0.595258150031 L 0.7 0.610706294803 L 0.708333333333 0.626667358442 L 0.716666666667 0.643276054324 L 0.725 0.66065384465 L 0.733333333333 0.678855644958 L 0.741666666667 0.697798860396 L 0.75 0.71721499193 L 0.758333333333 0.736690248362 L 0.766666666667 0.755795814951 L 0.775 0.774204843176 L 0.783333333333 0.791732522732 L 0.791666666667 0.808305909835 L 0.8 0.823921113596 L 0.808333333333 0.838609094968 L 0.816666666667 0.852414869183 L 0.825 0.865385279222 L 0.833333333333 0.877566835746 L 0.841666666667 0.889001244655 L 0.85 0.899725351699 L 0.858333333333 0.909772887147 L 0.866666666667 0.919172721118 L 0.875 0.927950539019 L 0.883333333333 0.936129852342 L 0.891666666667 0.943730807861 L 0.9 0.950771821528 L 0.908333333333 0.95726991079 L 0.916666666667 0.963271447844 L 0.925 0.968820243268 L 0.933333333333 0.973927263555 L 0.941666666667 0.978603045951 L 0.95 0.982857352297 L 0.958333333333 0.986698947476 L 0.966666666667 0.990136402522 L 0.975 0.993184062492 L 0.983333333333 0.995839116531 L 0.991666666667 0.998106161702 L 1.0 1.0 " />
diff --git a/core/res/res/interpolator/progress_indeterminate_horizontal_rect1_grp_scale.xml b/core/res/res/interpolator/progress_indeterminate_horizontal_rect1_grp_scale.xml
new file mode 100644
index 0000000..dc0e485
--- /dev/null
+++ b/core/res/res/interpolator/progress_indeterminate_horizontal_rect1_grp_scale.xml
@@ -0,0 +1,17 @@
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0 0.0 L 0.366666666667 0.0 L 0.375 0.00607022199531 L 0.383333333333 0.0128313190317 L 0.391666666667 0.0203053863048 L 0.4 0.0285126230744 L 0.408333333333 0.0374704929422 L 0.416666666667 0.0471928710088 L 0.425 0.0576890073411 L 0.433333333333 0.0689623329923 L 0.441666666667 0.0810093447457 L 0.45 0.0938182996083 L 0.458333333333 0.107368099555 L 0.466666666667 0.121627281237 L 0.475 0.136553254984 L 0.483333333333 0.152092042392 L 0.491666666667 0.168178420646 L 0.5 0.184736670404 L 0.508333333333 0.201682058428 L 0.516666666667 0.218922661357 L 0.525 0.236361911116 L 0.533333333333 0.253901271529 L 0.541666666667 0.271443072385 L 0.55 0.288893107328 L 0.558333333333 0.306163048058 L 0.566666666667 0.323172254984 L 0.575 0.339849141772 L 0.583333333333 0.356131857619 L 0.591666666667 0.371968628391 L 0.6 0.387317389244 L 0.608333333333 0.402145469729 L 0.616666666667 0.416428517896 L 0.625 0.430149949228 L 0.633333333333 0.443299687056 L 0.641666666667 0.455873322838 L 0.65 0.467790610602 L 0.658333333333 0.478261214125 L 0.666666666667 0.486946515351 L 0.675 0.493642461739 L 0.683333333333 0.498097136568 L 0.691666666667 0.5 L 0.7 0.501026508147 L 0.708333333333 0.505424974058 L 0.716666666667 0.513673357225 L 0.725 0.526197764281 L 0.733333333333 0.543195110129 L 0.741666666667 0.564385504796 L 0.75 0.588845516061 L 0.758333333333 0.615150659843 L 0.766666666667 0.641819770802 L 0.775 0.667727568443 L 0.783333333333 0.692232321167 L 0.791666666667 0.715080485292 L 0.8 0.736255108924 L 0.808333333333 0.755857404851 L 0.816666666667 0.774035479111 L 0.825 0.790946989585 L 0.833333333333 0.806741984167 L 0.841666666667 0.821556051785 L 0.85 0.835508642948 L 0.858333333333 0.848703647061 L 0.866666666667 0.861230901301 L 0.875 0.873167948783 L 0.883333333333 0.884581809849 L 0.891666666667 0.895530464709 L 0.9 0.906064231101 L 0.908333333333 0.916226932039 L 0.916666666667 0.925949460993 L 0.925 0.935162278452 L 0.933333333333 0.943901111981 L 0.941666666667 0.952197936634 L 0.95 0.960081506342 L 0.958333333333 0.967577760656 L 0.966666666667 0.974710159318 L 0.975 0.981500003726 L 0.983333333333 0.987966699339 L 0.991666666667 0.994127959051 L 1.0 1.0 " />
diff --git a/core/res/res/interpolator/progress_indeterminate_horizontal_rect2_grp_position.xml b/core/res/res/interpolator/progress_indeterminate_horizontal_rect2_grp_position.xml
new file mode 100644
index 0000000..e2c463d
--- /dev/null
+++ b/core/res/res/interpolator/progress_indeterminate_horizontal_rect2_grp_position.xml
@@ -0,0 +1,17 @@
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0 0.0 L 0.00833333333334 0.00229967744922 L 0.0166666666667 0.00521412430783 L 0.025 0.00874167982129 L 0.0333333333333 0.0128711540512 L 0.0416666666667 0.0175762490301 L 0.05 0.0228242656297 L 0.0583333333333 0.0285830529319 L 0.0666666666667 0.0348109630825 L 0.075 0.0414619464217 L 0.0833333333333 0.0484880345538 L 0.0916666666667 0.0558410655969 L 0.1 0.0634745223001 L 0.108333333333 0.0713444188538 L 0.116666666667 0.079410703663 L 0.125 0.0876382751487 L 0.133333333333 0.0959968850049 L 0.141666666667 0.104460460998 L 0.15 0.113007671299 L 0.158333333333 0.121621440773 L 0.166666666667 0.130288564002 L 0.175 0.138998350887 L 0.183333333333 0.147742658893 L 0.191666666667 0.156516005917 L 0.2 0.165314860841 L 0.208333333333 0.174136192385 L 0.216666666667 0.182978436537 L 0.225 0.191841222449 L 0.233333333333 0.200724646865 L 0.241666666667 0.209628467926 L 0.25 0.218553459576 L 0.258333333333 0.227500782731 L 0.266666666667 0.236470566383 L 0.275 0.245463519979 L 0.283333333333 0.254480675444 L 0.291666666667 0.263522016655 L 0.3 0.272587543612 L 0.308333333333 0.281677627163 L 0.316666666667 0.290791831964 L 0.325 0.299929045471 L 0.333333333333 0.309088509865 L 0.341666666667 0.318269435077 L 0.35 0.327474513787 L 0.358333333333 0.336748457377 L 0.366666666667 0.346105551561 L 0.375 0.355549440324 L 0.383333333333 0.365085073683 L 0.391666666667 0.374718256217 L 0.4 0.384454615142 L 0.408333333333 0.394301906021 L 0.416666666667 0.404268464874 L 0.425 0.414363869256 L 0.433333333333 0.424599921812 L 0.441666666667 0.434990214931 L 0.45 0.445549179441 L 0.458333333333 0.45629364862 L 0.466666666667 0.467242068132 L 0.475 0.478413609209 L 0.483333333333 0.489826169306 L 0.491666666667 0.501495178926 L 0.5 0.513430908951 L 0.508333333333 0.525634794401 L 0.516666666667 0.53809595169 L 0.525 0.550788614937 L 0.533333333333 0.563671442642 L 0.541666666667 0.576690097495 L 0.55 0.589782857472 L 0.558333333333 0.602885985073 L 0.566666666667 0.615938403227 L 0.575 0.628887306389 L 0.583333333333 0.641689563312 L 0.591666666667 0.654311104343 L 0.6 0.666726082982 L 0.608333333333 0.678916746891 L 0.616666666667 0.69086971329 L 0.625 0.702576630036 L 0.633333333333 0.714032144017 L 0.641666666667 0.725232143656 L 0.65 0.736175290675 L 0.658333333333 0.746879966241 L 0.666666666667 0.757365325464 L 0.675 0.767631174859 L 0.683333333333 0.77767703071 L 0.691666666667 0.787502199694 L 0.7 0.797107262267 L 0.708333333333 0.806492379668 L 0.716666666667 0.81565710043 L 0.725 0.82460216625 L 0.733333333333 0.833327480383 L 0.741666666667 0.841833333059 L 0.75 0.850119724279 L 0.758333333333 0.858187250623 L 0.766666666667 0.866036395807 L 0.775 0.873667014716 L 0.783333333333 0.88107965556 L 0.791666666667 0.888275060036 L 0.8 0.895253647364 L 0.808333333333 0.902015546533 L 0.816666666667 0.90856170885 L 0.825 0.914893101745 L 0.833333333333 0.921010096065 L 0.841666666667 0.926913352889 L 0.85 0.932604033131 L 0.858333333333 0.938083217089 L 0.866666666667 0.943351662581 L 0.875 0.94841012743 L 0.883333333333 0.953260127273 L 0.891666666667 0.957902806904 L 0.9 0.962339423981 L 0.908333333333 0.966571042677 L 0.916666666667 0.970598952899 L 0.925 0.974424621915 L 0.933333333333 0.978049533117 L 0.941666666667 0.981475153774 L 0.95 0.984702725421 L 0.958333333333 0.987733957184 L 0.966666666667 0.990574734261 L 0.975 0.993221525533 L 0.983333333333 0.995671735064 L 0.991666666667 0.997929361563 L 1.0 1.0 " />
diff --git a/core/res/res/interpolator/progress_indeterminate_horizontal_rect2_grp_scale.xml b/core/res/res/interpolator/progress_indeterminate_horizontal_rect2_grp_scale.xml
new file mode 100644
index 0000000..e19e3bd
--- /dev/null
+++ b/core/res/res/interpolator/progress_indeterminate_horizontal_rect2_grp_scale.xml
@@ -0,0 +1,17 @@
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0 0.0 L 0.00833333333334 0.00574128947512 L 0.0166666666667 0.0126739914922 L 0.025 0.0207803148119 L 0.0333333333333 0.0300222867359 L 0.0416666666667 0.0403408876828 L 0.05 0.0516566104757 L 0.0583333333333 0.0638713854701 L 0.0666666666667 0.0768720363634 L 0.075 0.0905347780463 L 0.0833333333333 0.104730220757 L 0.0916666666667 0.1193286215 L 0.1 0.134204393671 L 0.108333333333 0.149240004408 L 0.116666666667 0.164328670953 L 0.125 0.179375985524 L 0.133333333333 0.194300633561 L 0.141666666667 0.209034228885 L 0.15 0.223520630773 L 0.158333333333 0.237714931359 L 0.166666666667 0.25158211334 L 0.175 0.265095825429 L 0.183333333333 0.278237040065 L 0.191666666667 0.290992875969 L 0.2 0.303355514884 L 0.208333333333 0.315321283173 L 0.216666666667 0.326889756956 L 0.225 0.33806322048 L 0.233333333333 0.348845959658 L 0.241666666667 0.35924381463 L 0.25 0.369263944281 L 0.258333333333 0.378914166866 L 0.266666666667 0.388203101304 L 0.275 0.397139649102 L 0.283333333333 0.40573308855 L 0.291666666667 0.413992650841 L 0.3 0.421927755558 L 0.308333333333 0.429547633895 L 0.316666666667 0.436861375749 L 0.325 0.44387807102 L 0.333333333333 0.450606385724 L 0.341666666667 0.457054891684 L 0.35 0.463219114597 L 0.358333333333 0.468983900047 L 0.366666666667 0.474313547811 L 0.375 0.47919783764 L 0.383333333333 0.483624100194 L 0.391666666667 0.487576651865 L 0.4 0.491036606388 L 0.408333333333 0.493981309661 L 0.416666666667 0.496384057166 L 0.425 0.498213340392 L 0.433333333333 0.499432658452 L 0.441666666667 0.5 L 0.45 0.500132156764 L 0.458333333333 0.501016702806 L 0.466666666667 0.502710909197 L 0.475 0.505274449001 L 0.483333333333 0.50876595913 L 0.491666666667 0.51323738859 L 0.5 0.518726651206 L 0.508333333333 0.525248535726 L 0.516666666667 0.532785286233 L 0.525 0.541279914244 L 0.533333333333 0.550635115456 L 0.541666666667 0.560719439572 L 0.55 0.571380006744 L 0.558333333333 0.582458709253 L 0.566666666667 0.593806906062 L 0.575 0.605296114045 L 0.583333333333 0.61682262358 L 0.591666666667 0.628307922435 L 0.6 0.639696058281 L 0.608333333333 0.65094958827 L 0.616666666667 0.662045528618 L 0.625 0.67297172806 L 0.633333333333 0.6837236181 L 0.641666666667 0.694302070048 L 0.65 0.704711440462 L 0.658333333333 0.714905644026 L 0.666666666667 0.724841350655 L 0.675 0.734529345772 L 0.683333333333 0.743980697388 L 0.691666666667 0.753206332221 L 0.7 0.762216965048 L 0.708333333333 0.771022839665 L 0.716666666667 0.779633823089 L 0.725 0.788059240706 L 0.733333333333 0.796307899828 L 0.741666666667 0.804388136787 L 0.75 0.812307746289 L 0.758333333333 0.820074122707 L 0.766666666667 0.827694118788 L 0.775 0.835174210498 L 0.783333333333 0.842520520564 L 0.791666666667 0.849738700738 L 0.8 0.856834167281 L 0.808333333333 0.863811912571 L 0.816666666667 0.870676681725 L 0.825 0.877432925497 L 0.833333333333 0.884084847374 L 0.841666666667 0.890636403584 L 0.85 0.897091314861 L 0.858333333333 0.90345309 L 0.866666666667 0.909725084729 L 0.875 0.915910419285 L 0.883333333333 0.92201207261 L 0.891666666667 0.928032882355 L 0.9 0.933975497778 L 0.908333333333 0.939842485715 L 0.916666666667 0.945636236386 L 0.925 0.951359045815 L 0.933333333333 0.95701309228 L 0.941666666667 0.962600459864 L 0.95 0.968123109018 L 0.958333333333 0.973582941322 L 0.966666666667 0.978981746494 L 0.975 0.984321249498 L 0.983333333333 0.989603092873 L 0.991666666667 0.994828842625 L 1.0 1.0 " />
diff --git a/core/res/res/layout-sw600dp/date_picker_holo.xml b/core/res/res/layout-sw600dp/date_picker_holo.xml
deleted file mode 100644
index e5c886b..0000000
--- a/core/res/res/layout-sw600dp/date_picker_holo.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2011 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.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:gravity="center"
- android:orientation="vertical" >
-
- <include
- layout="@layout/date_picker_selected_date"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/datepicker_selected_calendar_layout_height" />
-
- <include layout="@layout/date_picker_view_animator" />
-
-</LinearLayout>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index f9ea5d8..08aaa6a 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2513,6 +2513,19 @@
result to valid color values. Saturate(S + D) -->
<enum name="add" value="16" />
</attr>
+
+ <!-- ViewOutlineProvider used to determine the View's Outline. -->
+ <attr name="outlineProvider">
+ <!-- Default, background drawable-driven outline. -->
+ <enum name="background" value="0" />
+ <!-- No outline provider. -->
+ <enum name="none" value="1" />
+ <!-- Generates an opaque outline for the bounds of the view. -->
+ <enum name="bounds" value="2" />
+ <!-- Generates an opaque outline for the padded bounds of the view. -->
+ <enum name="paddedBounds" value="3" />
+ </attr>
+
</declare-styleable>
<!-- Attributes that can be assigned to a tag for a particular View. -->
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index d170fd4..e58bc6f 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -374,7 +374,6 @@
<dimen name="datepicker_year_label_height">64dp</dimen>
<dimen name="datepicker_year_label_text_size">22dp</dimen>
<dimen name="datepicker_component_width">270dp</dimen>
- <dimen name="datepicker_selected_calendar_layout_height">155dp</dimen>
<dimen name="datepicker_selected_date_day_size">75dp</dimen>
<dimen name="datepicker_selected_date_month_size">30dp</dimen>
<dimen name="datepicker_selected_date_year_size">30dp</dimen>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 7ade51d..ed66c65 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2272,6 +2272,7 @@
<public type="attr" name="inset" />
<public type="attr" name="letterSpacing" />
<public type="attr" name="fontFeatureSettings" />
+ <public type="attr" name="outlineProvider" />
<public-padding type="dimen" name="l_resource_pad" end="0x01050010" />
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 00c92fa..4dcbc40 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -17,11 +17,15 @@
import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.ValueAnimator;
+import android.annotation.NonNull;
+import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
+import android.graphics.Outline;
+import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
@@ -129,7 +133,6 @@
private final AnimatedVectorDrawableState mAnimatedVectorState;
-
public AnimatedVectorDrawable() {
mAnimatedVectorState = new AnimatedVectorDrawableState(
new AnimatedVectorDrawableState(null));
@@ -163,6 +166,16 @@
}
@Override
+ protected boolean onStateChange(int[] state) {
+ return mAnimatedVectorState.mVectorDrawable.setState(state);
+ }
+
+ @Override
+ protected boolean onLevelChange(int level) {
+ return mAnimatedVectorState.mVectorDrawable.setLevel(level);
+ }
+
+ @Override
public int getAlpha() {
return mAnimatedVectorState.mVectorDrawable.getAlpha();
}
@@ -178,6 +191,43 @@
}
@Override
+ public void setTintList(ColorStateList tint) {
+ mAnimatedVectorState.mVectorDrawable.setTintList(tint);
+ }
+
+ @Override
+ public void setHotspot(float x, float y) {
+ mAnimatedVectorState.mVectorDrawable.setHotspot(x, y);
+ }
+
+ @Override
+ public void setHotspotBounds(int left, int top, int right, int bottom) {
+ mAnimatedVectorState.mVectorDrawable.setHotspotBounds(left, top, right, bottom);
+ }
+
+ @Override
+ public void setTintMode(PorterDuff.Mode tintMode) {
+ mAnimatedVectorState.mVectorDrawable.setTintMode(tintMode);
+ }
+
+ @Override
+ public boolean setVisible(boolean visible, boolean restart) {
+ mAnimatedVectorState.mVectorDrawable.setVisible(visible, restart);
+ return super.setVisible(visible, restart);
+ }
+
+ /** {@hide} */
+ @Override
+ public void setLayoutDirection(int layoutDirection) {
+ mAnimatedVectorState.mVectorDrawable.setLayoutDirection(layoutDirection);
+ }
+
+ @Override
+ public boolean isStateful() {
+ return mAnimatedVectorState.mVectorDrawable.isStateful();
+ }
+
+ @Override
public int getOpacity() {
return mAnimatedVectorState.mVectorDrawable.getOpacity();
}
@@ -193,6 +243,11 @@
}
@Override
+ public void getOutline(@NonNull Outline outline) {
+ mAnimatedVectorState.mVectorDrawable.getOutline(outline);
+ }
+
+ @Override
public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs, Theme theme)
throws XmlPullParserException, IOException {
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index e52d778..715da7e 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -81,14 +81,14 @@
private static final int TILE_MODE_REPEAT = 1;
private static final int TILE_MODE_MIRROR = 2;
- private final Rect mDstRect = new Rect(); // Gravity.apply() sets this
+ private final Rect mDstRect = new Rect(); // #updateDstRectAndInsetsIfDirty() sets this
private BitmapState mBitmapState;
private PorterDuffColorFilter mTintFilter;
private int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
- private boolean mApplyGravity;
+ private boolean mDstRectAndInsetsDirty = true;
private boolean mMutated;
// These are scaled to match the target density.
@@ -96,7 +96,7 @@
private int mBitmapHeight;
/** Optical insets due to gravity. */
- private Insets mOpticalInsets = null;
+ private Insets mOpticalInsets = Insets.NONE;
// Mirroring matrix for using with Shaders
private Matrix mMirrorMatrix;
@@ -285,7 +285,7 @@
public void setGravity(int gravity) {
if (mBitmapState.mGravity != gravity) {
mBitmapState.mGravity = gravity;
- mApplyGravity = true;
+ mDstRectAndInsetsDirty = true;
invalidateSelf();
}
}
@@ -428,6 +428,7 @@
state.mTileModeX = xmode;
state.mTileModeY = ymode;
state.mRebuildShader = true;
+ mDstRectAndInsetsDirty = true;
invalidateSelf();
}
}
@@ -464,7 +465,7 @@
@Override
protected void onBoundsChange(Rect bounds) {
- mApplyGravity = true;
+ mDstRectAndInsetsDirty = true;
final Shader shader = mBitmapState.mPaint.getShader();
if (shader != null) {
@@ -503,7 +504,6 @@
}
state.mRebuildShader = false;
- copyBounds(mDstRect);
}
final int restoreAlpha;
@@ -523,14 +523,10 @@
clearColorFilter = false;
}
+ updateDstRectAndInsetsIfDirty();
final Shader shader = paint.getShader();
final boolean needMirroring = needMirroring();
if (shader == null) {
- if (mApplyGravity) {
- applyGravity();
- mApplyGravity = false;
- }
-
if (needMirroring) {
canvas.save();
// Mirror the bitmap
@@ -544,11 +540,6 @@
canvas.restore();
}
} else {
- if (mApplyGravity) {
- copyBounds(mDstRect);
- mApplyGravity = false;
- }
-
if (needMirroring) {
// Mirror the bitmap
updateMirrorMatrix(mDstRect.right - mDstRect.left);
@@ -574,39 +565,46 @@
}
}
+ private void updateDstRectAndInsetsIfDirty() {
+ if (mDstRectAndInsetsDirty) {
+ if (mBitmapState.mTileModeX == null && mBitmapState.mTileModeY == null) {
+ final Rect bounds = getBounds();
+ final int layoutDirection = getLayoutDirection();
+ Gravity.apply(mBitmapState.mGravity, mBitmapWidth, mBitmapHeight,
+ bounds, mDstRect, layoutDirection);
+
+ final int left = mDstRect.left - bounds.left;
+ final int top = mDstRect.top - bounds.top;
+ final int right = bounds.right - mDstRect.right;
+ final int bottom = bounds.bottom - mDstRect.bottom;
+ mOpticalInsets = Insets.of(left, top, right, bottom);
+ } else {
+ copyBounds(mDstRect);
+ mOpticalInsets = Insets.NONE;
+ }
+ }
+ mDstRectAndInsetsDirty = false;
+ }
+
/**
* @hide
*/
@Override
public Insets getOpticalInsets() {
- if (mApplyGravity && mBitmapState.mPaint.getShader() == null) {
- applyGravity();
- mApplyGravity = false;
- }
- return mOpticalInsets == null ? Insets.NONE : mOpticalInsets;
- }
-
- private void applyGravity() {
- final Rect bounds = getBounds();
- final int layoutDirection = getLayoutDirection();
- Gravity.apply(mBitmapState.mGravity, mBitmapWidth, mBitmapHeight,
- bounds, mDstRect, layoutDirection);
-
- final int left = mDstRect.left - bounds.left;
- final int top = mDstRect.top - bounds.top;
- final int right = bounds.right - mDstRect.right;
- final int bottom = bounds.bottom - mDstRect.bottom;
- mOpticalInsets = Insets.of(left, top, right, bottom);
+ updateDstRectAndInsetsIfDirty();
+ return mOpticalInsets;
}
@Override
public void getOutline(@NonNull Outline outline) {
- super.getOutline(outline);
- if (mBitmapState.mBitmap == null || mBitmapState.mBitmap.hasAlpha()) {
- // Only opaque Bitmaps can report a non-0 alpha,
- // since only they are guaranteed to fill their bounds
- outline.setAlpha(0.0f);
- }
+ updateDstRectAndInsetsIfDirty();
+ outline.setRect(mDstRect);
+
+ // Only opaque Bitmaps can report a non-0 alpha,
+ // since only they are guaranteed to fill their bounds
+ boolean opaqueOverShape = mBitmapState.mBitmap != null
+ && !mBitmapState.mBitmap.hasAlpha();
+ outline.setAlpha(opaqueOverShape ? getAlpha() / 255.0f : 0.0f);
}
@Override
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index e673b0d..5922135 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -244,6 +244,29 @@
thread.renderState().invokeFunctor(functor, mode, NULL);
}
+void CanvasContext::buildLayer(RenderNode* node) {
+ ATRACE_CALL();
+ if (!mEglManager.hasEglContext() || !mCanvas) {
+ return;
+ }
+ requireGlContext();
+ // buildLayer() will leave the tree in an unknown state, so we must stop drawing
+ stopDrawing();
+
+ TreeInfo info(TreeInfo::MODE_FULL, mRenderThread.renderState());
+ info.frameTimeMs = mRenderThread.timeLord().frameTimeMs();
+ info.damageAccumulator = &mDamageAccumulator;
+ info.renderer = mCanvas;
+ node->prepareTree(info);
+ SkRect ignore;
+ mDamageAccumulator.finish(&ignore);
+ // Tickle the GENERIC property on node to mark it as dirty for damaging
+ // purposes when the frame is actually drawn
+ node->setPropertyFieldsDirty(RenderNode::GENERIC);
+
+ mCanvas->flushLayerUpdates();
+}
+
bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
requireGlContext();
layer->apply();
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 2a01027..0cbed6f 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -65,6 +65,7 @@
// IFrameCallback, Chroreographer-driven frame callback entry point
virtual void doFrame();
+ void buildLayer(RenderNode* node);
bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
void destroyHardwareResources();
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index d9b96f6c..405ce24 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -284,6 +284,18 @@
return layer;
}
+CREATE_BRIDGE2(buildLayer, CanvasContext* context, RenderNode* node) {
+ args->context->buildLayer(args->node);
+ return NULL;
+}
+
+void RenderProxy::buildLayer(RenderNode* node) {
+ SETUP_TASK(buildLayer);
+ args->context = mContext;
+ args->node = node;
+ postAndWait(task);
+}
+
CREATE_BRIDGE3(copyLayerInto, CanvasContext* context, DeferredLayerUpdater* layer,
SkBitmap* bitmap) {
bool success = args->context->copyLayerInto(args->layer, args->bitmap);
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 28d0173..eea3674 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -81,6 +81,7 @@
static void enqueueDestroyLayer(Layer* layer);
ANDROID_API DeferredLayerUpdater* createDisplayListLayer(int width, int height);
ANDROID_API DeferredLayerUpdater* createTextureLayer();
+ ANDROID_API void buildLayer(RenderNode* node);
ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
ANDROID_API void pushLayerUpdate(DeferredLayerUpdater* layer);
ANDROID_API void cancelLayerUpdate(DeferredLayerUpdater* layer);
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index 7cda961..6a4bf07 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -190,14 +190,6 @@
final int mainType = mCurAudioRoutesInfo.mMainType;
- boolean a2dpEnabled;
- try {
- a2dpEnabled = mAudioService.isBluetoothA2dpOn();
- } catch (RemoteException e) {
- Log.e(TAG, "Error querying Bluetooth A2DP state", e);
- a2dpEnabled = false;
- }
-
if (!TextUtils.equals(newRoutes.mBluetoothName, mCurAudioRoutesInfo.mBluetoothName)) {
mCurAudioRoutesInfo.mBluetoothName = newRoutes.mBluetoothName;
if (mCurAudioRoutesInfo.mBluetoothName != null) {
@@ -220,6 +212,7 @@
}
if (mBluetoothA2dpRoute != null) {
+ final boolean a2dpEnabled = isBluetoothA2dpOn();
if (mainType != AudioRoutesInfo.MAIN_SPEAKER &&
mSelectedRoute == mBluetoothA2dpRoute && !a2dpEnabled) {
selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mDefaultAudioVideo, false);
@@ -230,6 +223,15 @@
}
}
+ boolean isBluetoothA2dpOn() {
+ try {
+ return mAudioService.isBluetoothA2dpOn();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error querying Bluetooth A2DP state", e);
+ return false;
+ }
+ }
+
void updateDiscoveryRequest() {
// What are we looking for today?
int routeTypes = 0;
@@ -950,7 +952,7 @@
static void selectDefaultRouteStatic() {
// TODO: Be smarter about the route types here; this selects for all valid.
if (sStatic.mSelectedRoute != sStatic.mBluetoothA2dpRoute
- && sStatic.mBluetoothA2dpRoute != null) {
+ && sStatic.mBluetoothA2dpRoute != null && sStatic.isBluetoothA2dpOn()) {
selectRouteStatic(ROUTE_TYPE_ANY, sStatic.mBluetoothA2dpRoute, false);
} else {
selectRouteStatic(ROUTE_TYPE_ANY, sStatic.mDefaultAudioVideo, false);
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 2ec0293..d7baaa9 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -247,14 +247,14 @@
}
/**
- * Get the current audio info for this session.
+ * Get the current playback info for this session.
*
- * @return The current audio info or null.
+ * @return The current playback info or null.
*/
- public @Nullable AudioInfo getAudioInfo() {
+ public @Nullable PlaybackInfo getPlaybackInfo() {
try {
ParcelableVolumeInfo result = mSessionBinder.getVolumeAttributes();
- return new AudioInfo(result.volumeType, result.audioAttrs, result.controlType,
+ return new PlaybackInfo(result.volumeType, result.audioAttrs, result.controlType,
result.maxVolume, result.currentVolume);
} catch (RemoteException e) {
@@ -269,7 +269,7 @@
*
* @return A {@link PendingIntent} to launch UI or null.
*/
- public @Nullable PendingIntent getLaunchActivity() {
+ public @Nullable PendingIntent getSessionActivity() {
try {
return mSessionBinder.getLaunchPendingIntent();
} catch (RemoteException e) {
@@ -293,9 +293,10 @@
* {@link VolumeProvider#VOLUME_CONTROL_ABSOLUTE}. The flags in
* {@link AudioManager} may be used to affect the handling.
*
- * @see #getAudioInfo()
+ * @see #getPlaybackInfo()
* @param value The value to set it to, between 0 and the reported max.
- * @param flags Any flags to pass with the command.
+ * @param flags Flags from {@link AudioManager} to include with the volume
+ * request.
*/
public void setVolumeTo(int value, int flags) {
try {
@@ -314,7 +315,7 @@
* {@link VolumeProvider#VOLUME_CONTROL_ABSOLUTE}. The flags in
* {@link AudioManager} may be used to affect the handling.
*
- * @see #getAudioInfo()
+ * @see #getPlaybackInfo()
* @param direction The direction to adjust the volume in.
* @param flags Any flags to pass with the command.
*/
@@ -565,7 +566,7 @@
*
* @param info The current audio info for this session.
*/
- public void onAudioInfoChanged(AudioInfo info) {
+ public void onAudioInfoChanged(PlaybackInfo info) {
}
}
@@ -773,9 +774,19 @@
}
/**
- * Holds information about the way audio is handled for this session.
+ * Holds information about the current playback and how audio is handled for
+ * this session.
*/
- public static final class AudioInfo {
+ public static final class PlaybackInfo {
+ /**
+ * The session uses remote playback.
+ */
+ public static final int PLAYBACK_TYPE_REMOTE = 2;
+ /**
+ * The session uses local playback.
+ */
+ public static final int PLAYBACK_TYPE_LOCAL = 1;
+
private final int mVolumeType;
private final int mVolumeControl;
private final int mMaxVolume;
@@ -785,7 +796,7 @@
/**
* @hide
*/
- public AudioInfo(int type, AudioAttributes attrs, int control, int max, int current) {
+ public PlaybackInfo(int type, AudioAttributes attrs, int control, int max, int current) {
mVolumeType = type;
mAudioAttrs = attrs;
mVolumeControl = control;
@@ -794,22 +805,22 @@
}
/**
- * Get the type of volume handling, either local or remote. One of:
+ * Get the type of playback which affects volume handling. One of:
* <ul>
- * <li>{@link MediaSession#PLAYBACK_TYPE_LOCAL}</li>
- * <li>{@link MediaSession#PLAYBACK_TYPE_REMOTE}</li>
+ * <li>{@link #PLAYBACK_TYPE_LOCAL}</li>
+ * <li>{@link #PLAYBACK_TYPE_REMOTE}</li>
* </ul>
*
- * @return The type of volume handling this session is using.
+ * @return The type of playback this session is using.
*/
- public int getVolumeType() {
+ public int getPlaybackType() {
return mVolumeType;
}
/**
* Get the audio attributes for this session. The attributes will affect
* volume handling for the session. When the volume type is
- * {@link MediaSession#PLAYBACK_TYPE_REMOTE} these may be ignored by the
+ * {@link PlaybackInfo#PLAYBACK_TYPE_REMOTE} these may be ignored by the
* remote volume handler.
*
* @return The attributes for this session.
@@ -920,7 +931,7 @@
public void onVolumeInfoChanged(ParcelableVolumeInfo pvi) {
MediaController controller = mController.get();
if (controller != null) {
- AudioInfo info = new AudioInfo(pvi.volumeType, pvi.audioAttrs, pvi.controlType,
+ PlaybackInfo info = new PlaybackInfo(pvi.volumeType, pvi.audioAttrs, pvi.controlType,
pvi.maxVolume, pvi.currentVolume);
controller.postMessage(MSG_UPDATE_VOLUME, info, null);
}
@@ -958,7 +969,7 @@
mCallback.onExtrasChanged((Bundle) msg.obj);
break;
case MSG_UPDATE_VOLUME:
- mCallback.onAudioInfoChanged((AudioInfo) msg.obj);
+ mCallback.onAudioInfoChanged((PlaybackInfo) msg.obj);
break;
case MSG_DESTROYED:
mCallback.onSessionDestroyed();
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index de725fc..eac6809 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -101,16 +101,6 @@
FLAG_EXCLUSIVE_GLOBAL_PRIORITY })
public @interface SessionFlags { }
- /**
- * The session uses local playback.
- */
- public static final int PLAYBACK_TYPE_LOCAL = 1;
-
- /**
- * The session uses remote playback.
- */
- public static final int PLAYBACK_TYPE_REMOTE = 2;
-
private final Object mLock = new Object();
private final MediaSession.Token mSessionToken;
@@ -215,7 +205,7 @@
*
* @param pi The intent to launch to show UI for this Session.
*/
- public void setLaunchActivity(@Nullable PendingIntent pi) {
+ public void setSessionActivity(@Nullable PendingIntent pi) {
try {
mBinder.setLaunchPendingIntent(pi);
} catch (RemoteException e) {
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index 8a1e076..185c6d8 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -148,8 +148,29 @@
public void addOnActiveSessionsChangedListener(
@NonNull OnActiveSessionsChangedListener sessionListener,
@Nullable ComponentName notificationListener) {
+ addOnActiveSessionsChangedListener(sessionListener, notificationListener, null);
+ }
+
+ /**
+ * Add a listener to be notified when the list of active sessions
+ * changes.This requires the
+ * android.Manifest.permission.MEDIA_CONTENT_CONTROL permission be held by
+ * the calling app. You may also retrieve this list if your app is an
+ * enabled notification listener using the
+ * {@link NotificationListenerService} APIs, in which case you must pass the
+ * {@link ComponentName} of your enabled listener. Updates will be posted to
+ * the handler specified or to the caller's thread if the handler is null.
+ *
+ * @param sessionListener The listener to add.
+ * @param notificationListener The enabled notification listener component.
+ * May be null.
+ * @param handler The handler to post events to.
+ */
+ public void addOnActiveSessionsChangedListener(
+ @NonNull OnActiveSessionsChangedListener sessionListener,
+ @Nullable ComponentName notificationListener, @Nullable Handler handler) {
addOnActiveSessionsChangedListener(sessionListener, notificationListener,
- UserHandle.myUserId(), null);
+ UserHandle.myUserId(), handler);
}
/**
diff --git a/media/java/android/media/session/ParcelableVolumeInfo.java b/media/java/android/media/session/ParcelableVolumeInfo.java
index 96a45d9b..f59c975 100644
--- a/media/java/android/media/session/ParcelableVolumeInfo.java
+++ b/media/java/android/media/session/ParcelableVolumeInfo.java
@@ -21,7 +21,7 @@
/**
* Convenience class for passing information about the audio configuration of a
- * session. The public implementation is {@link MediaController.AudioInfo}.
+ * session. The public implementation is {@link MediaController.PlaybackInfo}.
*
* @hide
*/
diff --git a/media/java/android/media/session/PlaybackState.java b/media/java/android/media/session/PlaybackState.java
index 566e218..2ca97dd 100644
--- a/media/java/android/media/session/PlaybackState.java
+++ b/media/java/android/media/session/PlaybackState.java
@@ -217,7 +217,7 @@
private final int mState;
private final long mPosition;
- private final long mBufferPosition;
+ private final long mBufferedPosition;
private final float mSpeed;
private final long mActions;
private List<PlaybackState.CustomAction> mCustomActions;
@@ -226,14 +226,14 @@
private final long mActiveItemId;
private PlaybackState(int state, long position, long updateTime, float speed,
- long bufferPosition, long transportControls,
+ long bufferedPosition, long transportControls,
List<PlaybackState.CustomAction> customActions, long activeItemId,
CharSequence error) {
mState = state;
mPosition = position;
mSpeed = speed;
mUpdateTime = updateTime;
- mBufferPosition = bufferPosition;
+ mBufferedPosition = bufferedPosition;
mActions = transportControls;
mCustomActions = new ArrayList<>(customActions);
mActiveItemId = activeItemId;
@@ -245,7 +245,7 @@
mPosition = in.readLong();
mSpeed = in.readFloat();
mUpdateTime = in.readLong();
- mBufferPosition = in.readLong();
+ mBufferedPosition = in.readLong();
mActions = in.readLong();
mCustomActions = in.createTypedArrayList(CustomAction.CREATOR);
mActiveItemId = in.readLong();
@@ -258,7 +258,7 @@
StringBuilder bob = new StringBuilder("PlaybackState {");
bob.append("state=").append(mState);
bob.append(", position=").append(mPosition);
- bob.append(", buffered position=").append(mBufferPosition);
+ bob.append(", buffered position=").append(mBufferedPosition);
bob.append(", speed=").append(mSpeed);
bob.append(", updated=").append(mUpdateTime);
bob.append(", actions=").append(mActions);
@@ -280,7 +280,7 @@
dest.writeLong(mPosition);
dest.writeFloat(mSpeed);
dest.writeLong(mUpdateTime);
- dest.writeLong(mBufferPosition);
+ dest.writeLong(mBufferedPosition);
dest.writeLong(mActions);
dest.writeTypedList(mCustomActions);
dest.writeLong(mActiveItemId);
@@ -310,12 +310,12 @@
}
/**
- * Get the current buffer position in ms. This is the farthest playback
+ * Get the current buffered position in ms. This is the farthest playback
* point that can be reached from the current position using only buffered
* content.
*/
- public long getBufferPosition() {
- return mBufferPosition;
+ public long getBufferedPosition() {
+ return mBufferedPosition;
}
/**
@@ -711,7 +711,7 @@
private int mState;
private long mPosition;
- private long mBufferPosition;
+ private long mBufferedPosition;
private float mSpeed;
private long mActions;
private CharSequence mErrorMessage;
@@ -736,7 +736,7 @@
}
mState = from.mState;
mPosition = from.mPosition;
- mBufferPosition = from.mBufferPosition;
+ mBufferedPosition = from.mBufferedPosition;
mSpeed = from.mSpeed;
mActions = from.mActions;
if (from.mCustomActions != null) {
@@ -889,15 +889,16 @@
}
/**
- * Set the current buffer position in ms. This is the farthest playback
- * point that can be reached from the current position using only
- * buffered content.
+ * Set the current buffered position in ms. This is the farthest
+ * playback point that can be reached from the current position using
+ * only buffered content.
*
- * @param bufferPosition The position in ms that playback is buffered to.
+ * @param bufferedPosition The position in ms that playback is buffered
+ * to.
* @return this
*/
- public Builder setBufferPosition(long bufferPosition) {
- mBufferPosition = bufferPosition;
+ public Builder setBufferedPosition(long bufferedPosition) {
+ mBufferedPosition = bufferedPosition;
return this;
}
@@ -931,7 +932,7 @@
* @return A new state instance.
*/
public PlaybackState build() {
- return new PlaybackState(mState, mPosition, mUpdateTime, mSpeed, mBufferPosition,
+ return new PlaybackState(mState, mPosition, mUpdateTime, mSpeed, mBufferedPosition,
mActions, mCustomActions, mActiveItemId, mErrorMessage);
}
}
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 4c225c1..fae30e5 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -30,7 +30,6 @@
import android.content.pm.PackageParser.PackageParserException;
import android.content.res.ObbInfo;
import android.content.res.ObbScanner;
-import android.os.Build;
import android.os.Environment;
import android.os.Environment.UserEnvironment;
import android.os.FileUtils;
@@ -67,7 +66,6 @@
*/
public class DefaultContainerService extends IntentService {
private static final String TAG = "DefContainer";
- private static final boolean localLOGV = false;
private static final String LIB_DIR_NAME = "lib";
@@ -112,7 +110,7 @@
return copyPackageToContainerInner(pkg, handle, containerId, key, isExternal,
isForwardLocked, abiOverride);
} catch (PackageParserException | IOException e) {
- Slog.w(TAG, "Failed to parse package at " + packagePath);
+ Slog.w(TAG, "Failed to copy package at " + packagePath, e);
return null;
} finally {
IoUtils.closeQuietly(handle);
@@ -188,7 +186,7 @@
ret.installLocation = pkg.installLocation;
ret.verifiers = pkg.verifiers;
ret.recommendedInstallLocation = PackageHelper.resolveInstallLocation(context,
- pkg.installLocation, sizeBytes, flags);
+ pkg.packageName, pkg.installLocation, sizeBytes, flags);
ret.multiArch = pkg.multiArch;
return ret;
@@ -313,161 +311,73 @@
private String copyPackageToContainerInner(PackageLite pkg, NativeLibraryHelper.Handle handle,
String newCid, String key, boolean isExternal, boolean isForwardLocked,
- String abiOverride) {
- // TODO: extend to support copying all split APKs
- if (!ArrayUtils.isEmpty(pkg.splitNames)) {
- throw new UnsupportedOperationException("Copying split APKs not yet supported");
- }
+ String abiOverride) throws IOException {
- final String resFileName = "pkg.apk";
- final String publicResFileName = "res.zip";
-
- if (pkg.multiArch) {
- // TODO: Support multiArch installs on ASEC.
- throw new IllegalArgumentException("multiArch not supported on ASEC installs.");
- }
-
- // The .apk file
- final String codePath = pkg.baseCodePath;
- final File codeFile = new File(codePath);
- final String[] abis;
- try {
- abis = calculateAbiList(handle, abiOverride, pkg.multiArch);
- } catch (IOException ioe) {
- Slog.w(TAG, "Problem determining app ABIS: " + ioe);
- return null;
- }
-
- // Calculate size of container needed to hold base APK. Round up to
- // nearest MB, and tack on an extra MB for filesystem overhead.
- final int sizeMb;
- try {
- final long sizeBytes = calculateInstalledSizeInner(pkg, handle, isForwardLocked, abis);
- sizeMb = ((int) ((sizeBytes + MB_IN_BYTES) / MB_IN_BYTES)) + 1;
- } catch (IOException e) {
- Slog.w(TAG, "Problem when trying to copy " + codeFile.getPath());
- return null;
- }
+ // Calculate container size, rounding up to nearest MB and adding an
+ // extra MB for filesystem overhead
+ final long sizeBytes = calculateInstalledSizeInner(pkg, handle, isForwardLocked,
+ abiOverride);
+ final int sizeMb = ((int) ((sizeBytes + MB_IN_BYTES) / MB_IN_BYTES)) + 1;
// Create new container
- final String newCachePath = PackageHelper.createSdDir(sizeMb, newCid, key, Process.myUid(),
+ final String newMountPath = PackageHelper.createSdDir(sizeMb, newCid, key, Process.myUid(),
isExternal);
- if (newCachePath == null) {
- Slog.e(TAG, "Failed to create container " + newCid);
- return null;
+ if (newMountPath == null) {
+ throw new IOException("Failed to create container " + newCid);
}
-
- if (localLOGV) {
- Slog.i(TAG, "Created container for " + newCid + " at path : " + newCachePath);
- }
-
- final File resFile = new File(newCachePath, resFileName);
- if (FileUtils.copyFile(new File(codePath), resFile)) {
- if (localLOGV) {
- Slog.i(TAG, "Copied " + codePath + " to " + resFile);
- }
- } else {
- Slog.e(TAG, "Failed to copy " + codePath + " to " + resFile);
- // Clean up container
- PackageHelper.destroySdDir(newCid);
- return null;
- }
+ final File targetDir = new File(newMountPath);
try {
- Os.chmod(resFile.getAbsolutePath(), 0640);
+ // Copy all APKs
+ copyFile(pkg.baseCodePath, targetDir, "base.apk", isForwardLocked);
+ if (!ArrayUtils.isEmpty(pkg.splitNames)) {
+ for (int i = 0; i < pkg.splitNames.length; i++) {
+ copyFile(pkg.splitCodePaths[i], targetDir,
+ "split_" + pkg.splitNames[i] + ".apk", isForwardLocked);
+ }
+ }
+
+ // Extract native code
+ final File libraryRoot = new File(targetDir, LIB_DIR_NAME);
+ final int res = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle, libraryRoot,
+ abiOverride, pkg.multiArch);
+ if (res != PackageManager.INSTALL_SUCCEEDED) {
+ throw new IOException("Failed to extract native code, res=" + res);
+ }
+
+ if (!PackageHelper.finalizeSdDir(newCid)) {
+ throw new IOException("Failed to finalize " + newCid);
+ }
+
+ if (PackageHelper.isContainerMounted(newCid)) {
+ PackageHelper.unMountSdDir(newCid);
+ }
+
} catch (ErrnoException e) {
- Slog.e(TAG, "Could not chown APK: " + e.getMessage());
PackageHelper.destroySdDir(newCid);
- return null;
- }
-
- if (isForwardLocked) {
- File publicZipFile = new File(newCachePath, publicResFileName);
- try {
- PackageHelper.extractPublicFiles(resFile.getAbsolutePath(), publicZipFile);
- if (localLOGV) {
- Slog.i(TAG, "Copied resources to " + publicZipFile);
- }
- } catch (IOException e) {
- Slog.e(TAG, "Could not chown public APK " + publicZipFile.getAbsolutePath() + ": "
- + e.getMessage());
- PackageHelper.destroySdDir(newCid);
- return null;
- }
-
- try {
- Os.chmod(publicZipFile.getAbsolutePath(), 0644);
- } catch (ErrnoException e) {
- Slog.e(TAG, "Could not chown public resource file: " + e.getMessage());
- PackageHelper.destroySdDir(newCid);
- return null;
- }
- }
-
- final File sharedLibraryDir = new File(newCachePath, LIB_DIR_NAME);
- if (sharedLibraryDir.mkdir()) {
- int ret = PackageManager.INSTALL_SUCCEEDED;
- if (abis != null) {
- // TODO(multiArch): Support multi-arch installs on asecs. Note that we are NOT
- // using an ISA specific subdir here for now.
- final String abi = abis[0];
- ret = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle,
- sharedLibraryDir, abi);
-
- if (ret != PackageManager.INSTALL_SUCCEEDED) {
- Slog.e(TAG, "Could not copy native libraries to " + sharedLibraryDir.getPath());
- PackageHelper.destroySdDir(newCid);
- return null;
- }
- }
- } else {
- Slog.e(TAG, "Could not create native lib directory: " + sharedLibraryDir.getPath());
+ throw e.rethrowAsIOException();
+ } catch (IOException e) {
PackageHelper.destroySdDir(newCid);
- return null;
+ throw e;
}
- if (!PackageHelper.finalizeSdDir(newCid)) {
- Slog.e(TAG, "Failed to finalize " + newCid + " at path " + newCachePath);
- // Clean up container
- PackageHelper.destroySdDir(newCid);
- return null;
- }
-
- if (localLOGV) {
- Slog.i(TAG, "Finalized container " + newCid);
- }
-
- if (PackageHelper.isContainerMounted(newCid)) {
- if (localLOGV) {
- Slog.i(TAG, "Unmounting " + newCid + " at path " + newCachePath);
- }
-
- // Force a gc to avoid being killed.
- Runtime.getRuntime().gc();
- PackageHelper.unMountSdDir(newCid);
- } else {
- if (localLOGV) {
- Slog.i(TAG, "Container " + newCid + " not mounted");
- }
- }
-
- return newCachePath;
+ return newMountPath;
}
private int copyPackageInner(PackageLite pkg, IParcelFileDescriptorFactory target)
throws IOException, RemoteException {
- copyFile(pkg.baseCodePath, "base.apk", target);
+ copyFile(pkg.baseCodePath, target, "base.apk");
if (!ArrayUtils.isEmpty(pkg.splitNames)) {
for (int i = 0; i < pkg.splitNames.length; i++) {
- copyFile(pkg.splitCodePaths[i], "split_" + pkg.splitNames[i] + ".apk", target);
+ copyFile(pkg.splitCodePaths[i], target, "split_" + pkg.splitNames[i] + ".apk");
}
}
return PackageManager.INSTALL_SUCCEEDED;
}
- private void copyFile(String sourcePath, String targetName,
- IParcelFileDescriptorFactory target) throws IOException, RemoteException {
+ private void copyFile(String sourcePath, IParcelFileDescriptorFactory target, String targetName)
+ throws IOException, RemoteException {
Slog.d(TAG, "Copying " + sourcePath + " to " + targetName);
InputStream in = null;
OutputStream out = null;
@@ -482,76 +392,58 @@
}
}
+ private void copyFile(String sourcePath, File targetDir, String targetName,
+ boolean isForwardLocked) throws IOException, ErrnoException {
+ final File sourceFile = new File(sourcePath);
+ final File targetFile = new File(targetDir, targetName);
+
+ Slog.d(TAG, "Copying " + sourceFile + " to " + targetFile);
+ if (!FileUtils.copyFile(sourceFile, targetFile)) {
+ throw new IOException("Failed to copy " + sourceFile + " to " + targetFile);
+ }
+
+ if (isForwardLocked) {
+ final String publicTargetName = PackageHelper.replaceEnd(targetName,
+ ".apk", ".zip");
+ final File publicTargetFile = new File(targetDir, publicTargetName);
+
+ PackageHelper.extractPublicFiles(sourceFile, publicTargetFile);
+
+ Os.chmod(targetFile.getAbsolutePath(), 0640);
+ Os.chmod(publicTargetFile.getAbsolutePath(), 0644);
+ } else {
+ Os.chmod(targetFile.getAbsolutePath(), 0644);
+ }
+ }
+
private long calculateInstalledSizeInner(PackageLite pkg, boolean isForwardLocked,
String abiOverride) throws IOException {
NativeLibraryHelper.Handle handle = null;
try {
handle = NativeLibraryHelper.Handle.create(pkg);
- return calculateInstalledSizeInner(pkg, handle, isForwardLocked,
- calculateAbiList(handle, abiOverride, pkg.multiArch));
+ return calculateInstalledSizeInner(pkg, handle, isForwardLocked, abiOverride);
} finally {
IoUtils.closeQuietly(handle);
}
}
private long calculateInstalledSizeInner(PackageLite pkg, NativeLibraryHelper.Handle handle,
- boolean isForwardLocked, String[] abis) throws IOException {
+ boolean isForwardLocked, String abiOverride) throws IOException {
long sizeBytes = 0;
// Include raw APKs, and possibly unpacked resources
for (String codePath : pkg.getAllCodePaths()) {
- sizeBytes += new File(codePath).length();
+ final File codeFile = new File(codePath);
+ sizeBytes += codeFile.length();
if (isForwardLocked) {
- sizeBytes += PackageHelper.extractPublicFiles(codePath, null);
+ sizeBytes += PackageHelper.extractPublicFiles(codeFile, null);
}
}
// Include all relevant native code
- if (!ArrayUtils.isEmpty(abis)) {
- sizeBytes += NativeLibraryHelper.sumNativeBinariesLI(handle, abis);
- }
+ sizeBytes += NativeLibraryHelper.sumNativeBinaries(handle, abiOverride, pkg.multiArch);
return sizeBytes;
}
-
- private String[] calculateAbiList(NativeLibraryHelper.Handle handle, String abiOverride,
- boolean isMultiArch) throws IOException {
- if (isMultiArch) {
- final int abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
- final int abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
-
- if (abi32 >= 0 && abi64 >= 0) {
- return new String[] { Build.SUPPORTED_64_BIT_ABIS[abi64], Build.SUPPORTED_32_BIT_ABIS[abi32] };
- } else if (abi64 >= 0) {
- return new String[] { Build.SUPPORTED_64_BIT_ABIS[abi64] };
- } else if (abi32 >= 0) {
- return new String[] { Build.SUPPORTED_32_BIT_ABIS[abi32] };
- }
-
- if (abi64 != PackageManager.NO_NATIVE_LIBRARIES || abi32 != PackageManager.NO_NATIVE_LIBRARIES) {
- throw new IOException("Error determining ABI list: errorCode=[" + abi32 + "," + abi64 + "]");
- }
-
- } else {
- String[] abiList = Build.SUPPORTED_ABIS;
- if (abiOverride != null) {
- abiList = new String[] { abiOverride };
- } else if (Build.SUPPORTED_64_BIT_ABIS.length > 0 &&
- NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
- abiList = Build.SUPPORTED_32_BIT_ABIS;
- }
-
- final int abi = NativeLibraryHelper.findSupportedAbi(handle,abiList);
- if (abi >= 0) {
- return new String[]{Build.SUPPORTED_ABIS[abi]};
- }
-
- if (abi != PackageManager.NO_NATIVE_LIBRARIES) {
- throw new IOException("Error determining ABI list: errorCode=" + abi);
- }
- }
-
- return null;
- }
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 0d79ee2..dc12cc7 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -218,7 +218,7 @@
handleFingerprintProcessed(msg.arg1);
break;
case MSG_FACE_UNLOCK_STATE_CHANGED:
- handleFaceUnlockStateChanged(msg.arg1 != 0);
+ handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
break;
}
}
@@ -227,6 +227,7 @@
private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
private SparseBooleanArray mUserFingerprintRecognized = new SparseBooleanArray();
+ private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
@Override
public void onTrustChanged(boolean enabled, int userId, boolean initiatedByUser) {
@@ -297,15 +298,20 @@
}
}
- private void handleFaceUnlockStateChanged(boolean running) {
+ private void handleFaceUnlockStateChanged(boolean running, int userId) {
+ mUserFaceUnlockRunning.put(userId, running);
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
- cb.onFaceUnlockStateChanged(running);
+ cb.onFaceUnlockStateChanged(running, userId);
}
}
}
+ public boolean isFaceUnlockRunning(int userId) {
+ return mUserFaceUnlockRunning.get(userId);
+ }
+
private boolean isTrustDisabled(int userId) {
final DevicePolicyManager dpm =
(DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
@@ -398,9 +404,11 @@
} else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
dispatchBootCompleted();
} else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
- mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1, 0));
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1,
+ getSendingUserId()));
} else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
- mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0, 0));
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0,
+ getSendingUserId()));
}
}
};
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 0acb9d0..33cab8f 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -197,5 +197,5 @@
/**
* Called when the state of face unlock changed.
*/
- public void onFaceUnlockStateChanged(boolean running) { }
+ public void onFaceUnlockStateChanged(boolean running, int userId) { }
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 13301fb..edefb13 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -70,7 +70,7 @@
// database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
// is properly propagated through your change. Not doing so will result in a loss of user
// settings.
- private static final int DATABASE_VERSION = 107;
+ private static final int DATABASE_VERSION = 108;
private Context mContext;
private int mUserHandle;
@@ -1714,6 +1714,25 @@
upgradeVersion = 107;
}
+ if (upgradeVersion < 108) {
+ // Reset the auto-brightness setting to default since the behavior
+ // of the feature is now quite different and is being presented to
+ // the user in a new way as "adaptive brightness".
+ db.beginTransaction();
+ SQLiteStatement stmt = null;
+ try {
+ stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
+ + " VALUES(?,?);");
+ loadBooleanSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_MODE,
+ R.bool.def_screen_brightness_automatic_mode);
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ if (stmt != null) stmt.close();
+ }
+ upgradeVersion = 108;
+ }
+
// *** Remember to update DATABASE_VERSION above!
if (upgradeVersion != currentVersion) {
diff --git a/core/res/res/anim/progress_indeterminate_horizontal_rect1_scale.xml b/packages/SystemUI/res/anim/progress_indeterminate_horizontal_rect1_scale.xml
similarity index 100%
rename from core/res/res/anim/progress_indeterminate_horizontal_rect1_scale.xml
rename to packages/SystemUI/res/anim/progress_indeterminate_horizontal_rect1_scale.xml
diff --git a/core/res/res/anim/progress_indeterminate_horizontal_rect1_translate.xml b/packages/SystemUI/res/anim/progress_indeterminate_horizontal_rect1_translate.xml
similarity index 100%
rename from core/res/res/anim/progress_indeterminate_horizontal_rect1_translate.xml
rename to packages/SystemUI/res/anim/progress_indeterminate_horizontal_rect1_translate.xml
diff --git a/core/res/res/anim/progress_indeterminate_horizontal_rect2_scale.xml b/packages/SystemUI/res/anim/progress_indeterminate_horizontal_rect2_scale.xml
similarity index 100%
rename from core/res/res/anim/progress_indeterminate_horizontal_rect2_scale.xml
rename to packages/SystemUI/res/anim/progress_indeterminate_horizontal_rect2_scale.xml
diff --git a/core/res/res/anim/progress_indeterminate_horizontal_rect2_translate.xml b/packages/SystemUI/res/anim/progress_indeterminate_horizontal_rect2_translate.xml
similarity index 100%
rename from core/res/res/anim/progress_indeterminate_horizontal_rect2_translate.xml
rename to packages/SystemUI/res/anim/progress_indeterminate_horizontal_rect2_translate.xml
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
index b28624f..5be74ec 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png
index 9ce434d..305c9fb 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
index 51dce69..3e676ab 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
index 3f3e288..d3e1f7a 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
index 9856cbf..d632600 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
index 6910456..8984a49d 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png
index e8c6ec6..2e8f8f0 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
index 06dcd20..ec499d4 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
index 240f536..13e8a4f 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png
index e464347..c697da7 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png
index f8b59e8..94404df 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png
index 1b578a6..9d0014d 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png
index 80ecaba..9a8b0e9 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png
index c7bf2c7..80d60af 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png
index 278de42..2dfe964 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png
index 464831c..fd1cc27 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png
index c24132c..183aa0d 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png
index bc84f22..6f763a4 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png
index f4e219e..3dc75a3 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back.png
index ece2e37..83040fd 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back_land.png
index d524dcf..9917be4 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png
index 373e84a..c116bbe 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png
index e5a102a..1446850 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png
index 6b19593..83040fd 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png
index a5e0686..9917be4 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
index f878093..447c655 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png
index 7780b16..d5ca622 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
index 343d0dd..47985de 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
index 8e9583b..7b5fe8b 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
index 7d38703..9fcb705 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
index 6e186a3..23c24ba 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png
index 12b4042..41c1acb 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
index e2a89c3..11a92f0 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
index 311720b..7fb14a8 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png
index 67e4ee7..eaac305 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png
index dfef430..b5d3739 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png
index de6d109..9915260 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png
index 7d0c3fbe..4a349e2 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png
index 3baeb52..d14da80 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png
index d5b48e8..4f5e723 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png
index 26d7e7b..05b9b44 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png
index c49198d..2035323 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png
index 2a21f29..69b541b 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png
index 538d7d1..3f2b8b4 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png
index eb8e80b..23e5e8f 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png
index 1c2c35a..4b7f3ac 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png
index eec613f..41054f6 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png
index 1c0bad8..e4a7181 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png
index 1293fa8..be678e0 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png
index 96a9cce..24d37e0 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png
index 9ffc80a..9443656 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png
index aa9b57b..c3c64f4 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png
index b343522..0ab43ce 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png
index f2f7b50..3c58211 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png
index 383398c..14ff6d3 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png
index 53444ab..eb74d0d 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png
index 4294937..e29c9d0 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png
index 7cb3ee4..cfecdcf 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png
index b017946..d98208a 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png
index e8dd07c..71cc61b 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png
index f396ea9..bdecf06 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back.png
index 1b817cf..01edd86 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_ime.png
index 21b7a06..52bd6e8 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_land.png
index 676fc14..b0dd0f0 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home.png
index 26f4ba9..b5c189d 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home_land.png
index ea21b60..42e9e31 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu.png
index c7d77c2..669d8ba 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu_land.png
index ae12cfd..0fbf1f6 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent.png
index 8c27d45..023b94c 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent_land.png
index c98827c..5884492 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
index ec2951d..4956aad 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png
index 5103190..e9a6223 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
index 818aa4f..e9767a1 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png
index 254f757..acaf32d 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
index f0de417..20cb101 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png
index 97f1526..cc620a2 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png
index 773fa94..aa8a60e 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png
index 8a8e941..88d6a41 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
index ad7dfc3..8acdd3c 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png
index 77969b8..01edd86 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png
index b171f92..52bd6e8 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png
index ad35c65..b0dd0f0 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png
index d60229f..b5c189d 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png
index 8fffa8e..42e9e31 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png
index 9215055..669d8ba 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png
index bcf7eb1..0fbf1f6 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png
index a261f85..023b94c 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png
index 4c612f7..5884492 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/indeterminate_anim.xml b/packages/SystemUI/res/drawable/indeterminate_anim.xml
index 52c6d16..13b1ccf 100644
--- a/packages/SystemUI/res/drawable/indeterminate_anim.xml
+++ b/packages/SystemUI/res/drawable/indeterminate_anim.xml
@@ -18,15 +18,15 @@
<target
android:name="path1"
- android:animation="@*android:anim/progress_indeterminate_horizontal_rect1_translate" />
+ android:animation="@anim/progress_indeterminate_horizontal_rect1_translate" />
<target
android:name="path1"
- android:animation="@*android:anim/progress_indeterminate_horizontal_rect1_scale" />
+ android:animation="@anim/progress_indeterminate_horizontal_rect1_scale" />
<target
android:name="path2"
- android:animation="@*android:anim/progress_indeterminate_horizontal_rect2_translate" />
+ android:animation="@anim/progress_indeterminate_horizontal_rect2_translate" />
<target
android:name="path2"
- android:animation="@*android:anim/progress_indeterminate_horizontal_rect2_scale" />
+ android:animation="@anim/progress_indeterminate_horizontal_rect2_scale" />
</animated-vector>
diff --git a/packages/SystemUI/res/drawable/trust_circle.xml b/packages/SystemUI/res/drawable/trust_circle.xml
deleted file mode 100644
index 56fc62e..0000000
--- a/packages/SystemUI/res/drawable/trust_circle.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- ~ Copyright (C) 2014 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="ring"
- android:innerRadius="22dp" android:thickness="2dp">
- <solid android:color="#4cffffff" />
-</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index 8e9b501..ca07c87 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -31,7 +31,7 @@
android:layout_gravity="bottom|center_horizontal"
android:textStyle="italic"
android:textColor="#ffffff"
- android:textAppearance="?android:attr/textAppearanceSmall"/>
+ android:textAppearance="?android:attr/textAppearanceSmall" />
<FrameLayout
android:id="@+id/preview_container"
@@ -66,6 +66,7 @@
android:layout_gravity="bottom|center_horizontal"
android:src="@drawable/ic_lock_24dp"
android:scaleType="center"
- android:tint="#ffffffff" />
+ android:tint="#ffffffff"
+ android:contentDescription="@string/accessibility_unlock_button" />
</com.android.systemui.statusbar.phone.KeyguardBottomAreaView>
diff --git a/packages/SystemUI/res/layout/volume_panel.xml b/packages/SystemUI/res/layout/volume_panel.xml
index c85a750..4d8aaa7 100644
--- a/packages/SystemUI/res/layout/volume_panel.xml
+++ b/packages/SystemUI/res/layout/volume_panel.xml
@@ -25,7 +25,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/system_secondary_color"
- android:paddingTop="12dp"
+ android:paddingTop="8dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clipChildren="false" />
diff --git a/packages/SystemUI/res/layout/zen_mode_panel.xml b/packages/SystemUI/res/layout/zen_mode_panel.xml
index 9d5f7bd..3949d7d 100644
--- a/packages/SystemUI/res/layout/zen_mode_panel.xml
+++ b/packages/SystemUI/res/layout/zen_mode_panel.xml
@@ -35,8 +35,8 @@
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/qs_panel_padding"
android:layout_marginRight="@dimen/qs_panel_padding"
- android:layout_marginTop="8dp"
- android:layout_marginBottom="12dp"
+ android:layout_marginTop="4dp"
+ android:layout_marginBottom="8dp"
android:clipChildren="false" />
</FrameLayout>
diff --git a/packages/SystemUI/res/values/arrays.xml b/packages/SystemUI/res/values/arrays.xml
index 630a48d..6102aa6 100644
--- a/packages/SystemUI/res/values/arrays.xml
+++ b/packages/SystemUI/res/values/arrays.xml
@@ -25,7 +25,7 @@
<item>100</item>
</array>
<array name="batterymeter_color_values">
- <item>#FFFF3300</item>
+ <item>@*android:color/battery_saver_mode_color</item>
<item>#FFFFFFFF</item>
</array>
<array name="batterymeter_bolt_points">
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index c6b3222..42d9734 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -92,7 +92,7 @@
<!-- The default tiles to display in QuickSettings -->
<string name="quick_settings_tiles_default" translatable="false">
- wifi,bt,inversion,cell,airplane,rotation,flashlight,location,cast
+ wifi,bt,inversion,cell,airplane,rotation,flashlight,location,cast,hotspot
</string>
<!-- The tiles to display in QuickSettings -->
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 1b8eeb2..c8db284 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -430,4 +430,16 @@
<!-- The text size for battery level -->
<dimen name="battery_level_text_size">12sp</dimen>
+
+ <!-- TrustDrawable: Minimum inner radius of the breathing animation -->
+ <dimen name="trust_circle_inner_radius_visible_min">22dp</dimen>
+ <!-- TrustDrawable: Maximum inner radius of the breathing animation -->
+ <dimen name="trust_circle_inner_radius_visible_max">24dp</dimen>
+ <!-- TrustDrawable: Inner radius at the end of the exit animation -->
+ <dimen name="trust_circle_inner_radius_exit">38dp</dimen>
+ <!-- TrustDrawable: Inner radius at the beginning of the enter animation -->
+ <dimen name="trust_circle_inner_radius_enter">18dp</dimen>
+ <!-- TrustDrawable: Thickness of the circle -->
+ <dimen name="trust_circle_thickness">2dp</dimen>
+
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index d49312d..ed3fa58 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -213,6 +213,14 @@
<string name="accessibility_camera_button">Camera</string>
<!-- Content description of the phone button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_phone_button">Phone</string>
+ <!-- Content description of the unlock button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_unlock_button">Unlock</string>
+ <!-- Click action label for accessibility for the unlock button. [CHAR LIMIT=NONE] -->
+ <string name="unlock_label">unlock</string>
+ <!-- Click action label for accessibility for the phone button. [CHAR LIMIT=NONE] -->
+ <string name="phone_label">open phone</string>
+ <!-- Click action label for accessibility for the phone button. [CHAR LIMIT=NONE] -->
+ <string name="camera_label">open camera</string>
<!-- Content description of the switch input method button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_ime_switch_button">Switch input method button.</string>
@@ -306,15 +314,6 @@
<!-- Content description of an item with full signal for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_signal_full">Signal full.</string>
- <!-- Content description of an item that is turned on for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_desc_on">On.</string>
- <!-- Content description of an item that is turned off for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_desc_off">Off.</string>
- <!-- Content description of an item that is connected for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_desc_connected">Connected.</string>
- <!-- Content description of an item that is connecting for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_desc_connecting">Connecting.</string>
-
<!-- Content description of the data connection type GPRS for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_data_connection_gprs">GPRS</string>
@@ -408,24 +407,68 @@
<string name="accessibility_quick_settings_user">User <xliff:g id="user" example="John Doe">%s</xliff:g>.</string>
<!-- Content description of the wifi tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_quick_settings_wifi"><xliff:g id="signal" example="Three bars">%1$s</xliff:g>.</string>
+ <!-- Announcement made when the wifi is turned off (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_wifi_changed_off">Wifi turned off.</string>
+ <!-- Announcement made when the wifi is turned on (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_wifi_changed_on">Wifi turned on.</string>
<!-- Content description of the mobile data tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_quick_settings_mobile">Mobile <xliff:g id="signal" example="Three bars">%1$s</xliff:g>. <xliff:g id="type" example="4G">%2$s</xliff:g>. <xliff:g id="network" example="T-Mobile">%3$s</xliff:g>.</string>
<!-- Content description of the battery tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_quick_settings_battery">Battery <xliff:g id="state" example="50% charging">%s</xliff:g>.</string>
- <!-- Content description of the airplane mode tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_quick_settings_airplane">Airplane Mode <xliff:g id="state" example="Off">%s</xliff:g>.</string>
- <!-- Content description of the bluetooth tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_quick_settings_bluetooth">Bluetooth <xliff:g id="state" example="Off">%s</xliff:g>.</string>
- <!-- Content description of the location tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_quick_settings_location">Location <xliff:g id="state" example="Off">%s</xliff:g>.</string>
+ <!-- Content description of the airplane mode tile in quick settings when off (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_airplane_off">Airplane mode off.</string>
+ <!-- Content description of the airplane mode tile in quick settings when on (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_airplane_on">Airplane mode on.</string>
+ <!-- Announcement made when the airplane mode changes to off (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_airplane_changed_off">Airplane mode turned off.</string>
+ <!-- Announcement made when the airplane mode changes to on (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_airplane_changed_on">Airplane mode turned on.</string>
+ <!-- Content description of the bluetooth tile in quick settings when off (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_bluetooth_off">Bluetooth off.</string>
+ <!-- Content description of the bluetooth tile in quick settings when on (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_bluetooth_on">Bluetooth on.</string>
+ <!-- Content description of the bluetooth tile in quick settings when connecting (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_bluetooth_connecting">Bluetooth connecting.</string>
+ <!-- Content description of the bluetooth tile in quick settings when connected (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_bluetooth_connected">Bluetooth connected.</string>
+ <!-- Announcement made when the bluetooth is turned off (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_bluetooth_changed_off">Bluetooth turned off.</string>
+ <!-- Announcement made when the bluetooth is turned on (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_bluetooth_changed_on">Bluetooth turned on.</string>
+ <!-- Content description of the location tile in quick settings when off (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_location_off">Location reporting off.</string>
+ <!-- Content description of the location tile in quick settings when on (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_location_on">Location reporting on.</string>
+ <!-- Announcement made when the location tile changes to off (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_location_changed_off">Location reporting turned off.</string>
+ <!-- Announcement made when the location tile changes to on (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_location_changed_on">Location reporting turned on.</string>
<!-- Content description of the alarm tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_quick_settings_alarm">Alarm set for <xliff:g id="time" example="Wed 3:30 PM">%s</xliff:g>.</string>
<!-- Content description of quick settings detail panel close button (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_quick_settings_close">Close panel</string>
+ <string name="accessibility_quick_settings_close">Close panel.</string>
<!-- Content description of zen mode time condition plus button (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_quick_settings_more_time">More time</string>
+ <string name="accessibility_quick_settings_more_time">More time.</string>
<!-- Content description of zen mode time condition minus button (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_quick_settings_less_time">Less time</string>
+ <string name="accessibility_quick_settings_less_time">Less time.</string>
+ <!-- Content description of the flashlight tile in quick settings when off (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_flashlight_off">Flashlight off.</string>
+ <!-- Content description of the flashlight tile in quick settings when on (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_flashlight_on">Flashlight on.</string>
+ <!-- Announcement made when the flashlight state changes to off (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_flashlight_changed_off">Flashlight turned off.</string>
+ <!-- Announcement made when the flashlight state changes to on (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_flashlight_changed_on">Flashlight turned on.</string>
+ <!-- Announcement made when the color inversion state changes to off (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_color_inversion_changed_off">Color inversion turned off.</string>
+ <!-- Announcement made when the color inversion state changes to on (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_color_inversion_changed_on">Color inversion turned on.</string>
+ <!-- Announcement made when the hotspot state changes to off (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_hotspot_changed_off">Mobile hotspot turned off.</string>
+ <!-- Announcement made when the hotspot state changes to on (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_hotspot_changed_on">Mobile hotspot turned on.</string>
+ <!-- Announcement made when the screen stopped casting (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_casting_turned_off">Screen casting stopped.</string>
<!-- Content description of the display brightness slider (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_brightness">Display brightness</string>
@@ -480,6 +523,15 @@
<!-- Description of the button in the phone-style notification panel that controls auto-rotation, when auto-rotation is off. [CHAR LIMIT=NONE] -->
<string name="accessibility_rotation_lock_on_portrait">Screen is locked in portrait orientation.</string>
+ <!-- Announcement made when the screen is rotating automatically again (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_rotation_lock_off_changed">Screen will now rotate automatically.</string>
+
+ <!-- Announcement made when the rotation lock state changes to landscape only (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_rotation_lock_on_landscape_changed">Screen is now locked in landscape orientation.</string>
+
+ <!-- Announcement made when the rotation lock state changes to portrait only (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_rotation_lock_on_portrait_changed">Screen is now locked in portrait orientation.</string>
+
<!-- Name of the K-release easter egg: a display case for all our tastiest desserts. [CHAR LIMIT=30] -->
<string name="dessert_case">Dessert Case</string>
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index b9ffdbb..5e2f784 100755
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -33,7 +33,10 @@
import android.util.AttributeSet;
import android.view.View;
-public class BatteryMeterView extends View implements DemoMode {
+import com.android.systemui.statusbar.policy.BatteryController;
+
+public class BatteryMeterView extends View implements DemoMode,
+ BatteryController.BatteryStateChangeCallback {
public static final String TAG = BatteryMeterView.class.getSimpleName();
public static final String ACTION_LEVEL_TEST = "com.android.systemui.BATTERY_LEVEL_TEST";
@@ -68,6 +71,9 @@
private final Path mClipPath = new Path();
private final Path mTextPath = new Path();
+ private BatteryController mBatteryController;
+ private boolean mPowerSaveEnabled;
+
private class BatteryTracker extends BroadcastReceiver {
public static final int UNKNOWN_LEVEL = -1;
@@ -155,6 +161,7 @@
// preload the battery level
mTracker.onReceive(getContext(), sticky);
}
+ mBatteryController.addStateChangedCallback(this);
}
@Override
@@ -162,6 +169,7 @@
super.onDetachedFromWindow();
getContext().unregisterReceiver(mTracker);
+ mBatteryController.removeStateChangedCallback(this);
}
public BatteryMeterView(Context context) {
@@ -227,6 +235,22 @@
mBoltPoints = loadBoltPoints(res);
}
+ public void setBatteryController(BatteryController batteryController) {
+ mBatteryController = batteryController;
+ mPowerSaveEnabled = mBatteryController.isPowerSave();
+ }
+
+ @Override
+ public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
+ // TODO: Use this callback instead of own broadcast receiver.
+ }
+
+ @Override
+ public void onPowerSaveChanged() {
+ mPowerSaveEnabled = mBatteryController.isPowerSave();
+ invalidate();
+ }
+
private static float[] loadBoltPoints(Resources res) {
final int[] pts = res.getIntArray(R.array.batterymeter_bolt_points);
int maxX = 0, maxY = 0;
@@ -251,6 +275,11 @@
}
private int getColorForLevel(int percent) {
+
+ // If we are in power save mode, always use the normal color.
+ if (mPowerSaveEnabled) {
+ return mColors[mColors.length-1];
+ }
int thresh, color = 0;
for (int i=0; i<mColors.length; i+=2) {
thresh = mColors[i];
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetailClipper.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetailClipper.java
index 9c1ff9d..eb4560d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetailClipper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetailClipper.java
@@ -46,7 +46,11 @@
r = (int) Math.max(r, Math.ceil(Math.sqrt(w * w + y * y)));
r = (int) Math.max(r, Math.ceil(Math.sqrt(w * w + h * h)));
r = (int) Math.max(r, Math.ceil(Math.sqrt(x * x + h * h)));
- mAnimator = ViewAnimationUtils.createCircularReveal(mDetail, x, y, 0, r);
+ if (in) {
+ mAnimator = ViewAnimationUtils.createCircularReveal(mDetail, x, y, 0, r);
+ } else {
+ mAnimator = ViewAnimationUtils.createCircularReveal(mDetail, x, y, r, 0);
+ }
mAnimator.setDuration((long)(mAnimator.getDuration() * 1.5));
if (listener != null) {
mAnimator.addListener(listener);
@@ -55,12 +59,11 @@
if (in) {
mBackground.startTransition((int)(mAnimator.getDuration() * 0.6));
mAnimator.addListener(mVisibleOnStart);
- mAnimator.start();
} else {
mDetail.postDelayed(mReverseBackground, (long)(mAnimator.getDuration() * 0.65));
mAnimator.addListener(mGoneOnEnd);
- mAnimator.reverse();
}
+ mAnimator.start();
}
private final Runnable mReverseBackground = new Runnable() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index bf01b7b..c1fd509 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -239,6 +239,11 @@
fireScanStateChanged(r.scanState);
}
}
+
+ @Override
+ public void onAnnouncementRequested(CharSequence announcement) {
+ announceForAccessibility(announcement);
+ }
};
r.tile.setCallback(callback);
final View.OnClickListener click = new View.OnClickListener() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index 409cc46..876652c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -60,6 +60,7 @@
private Callback mCallback;
protected final TState mState = newTileState();
private final TState mTmpState = newTileState();
+ private boolean mAnnounceNextStateChange;
abstract protected TState newTileState();
abstract protected void handleClick();
@@ -161,9 +162,25 @@
}
private void handleStateChanged() {
+ boolean delayAnnouncement = shouldAnnouncementBeDelayed();
if (mCallback != null) {
mCallback.onStateChanged(mState);
+ if (mAnnounceNextStateChange && !delayAnnouncement) {
+ String announcement = composeChangeAnnouncement();
+ if (announcement != null) {
+ mCallback.onAnnouncementRequested(announcement);
+ }
+ }
}
+ mAnnounceNextStateChange = mAnnounceNextStateChange && delayAnnouncement;
+ }
+
+ protected boolean shouldAnnouncementBeDelayed() {
+ return false;
+ }
+
+ protected String composeChangeAnnouncement() {
+ return null;
}
private void handleShowDetail(boolean show) {
@@ -217,6 +234,7 @@
handleSetCallback((QSTile.Callback)msg.obj);
} else if (msg.what == CLICK) {
name = "handleClick";
+ mAnnounceNextStateChange = true;
handleClick();
} else if (msg.what == SECONDARY_CLICK) {
name = "handleSecondaryClick";
@@ -255,6 +273,7 @@
void onShowDetail(boolean show);
void onToggleStateChanged(boolean state);
void onScanStateChanged(boolean state);
+ void onAnnouncementRequested(CharSequence announcement);
}
public interface Host {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index 5d1fa80..51401c8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -70,13 +70,20 @@
if (airplaneMode) {
state.iconId = R.drawable.ic_qs_airplane_on;
state.contentDescription = mContext.getString(
- R.string.accessibility_quick_settings_airplane,
- mContext.getString(R.string.accessibility_desc_on));
+ R.string.accessibility_quick_settings_airplane_on);
} else {
state.iconId = R.drawable.ic_qs_airplane_off;
state.contentDescription = mContext.getString(
- R.string.accessibility_quick_settings_airplane,
- mContext.getString(R.string.accessibility_desc_off));
+ R.string.accessibility_quick_settings_airplane_off);
+ }
+ }
+
+ @Override
+ protected String composeChangeAnnouncement() {
+ if (mState.value) {
+ return mContext.getString(R.string.accessibility_quick_settings_airplane_changed_on);
+ } else {
+ return mContext.getString(R.string.accessibility_quick_settings_airplane_changed_off);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 19b9ec1..63c880f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -88,21 +88,22 @@
final boolean connecting = mController.isBluetoothConnecting();
state.visible = supported;
state.value = enabled;
- final String stateContentDescription;
if (enabled) {
state.label = null;
if (connected) {
state.iconId = R.drawable.ic_qs_bluetooth_connected;
- stateContentDescription = mContext.getString(R.string.accessibility_desc_connected);
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_bluetooth_connected);
state.label = mController.getLastDeviceName();
} else if (connecting) {
state.iconId = R.drawable.ic_qs_bluetooth_connecting;
- stateContentDescription =
- mContext.getString(R.string.accessibility_desc_connecting);
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_bluetooth_connecting);
state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
} else {
state.iconId = R.drawable.ic_qs_bluetooth_on;
- stateContentDescription = mContext.getString(R.string.accessibility_desc_on);
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_bluetooth_on);
}
if (TextUtils.isEmpty(state.label)) {
state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
@@ -110,10 +111,10 @@
} else {
state.iconId = R.drawable.ic_qs_bluetooth_off;
state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
- stateContentDescription = mContext.getString(R.string.accessibility_desc_off);
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_bluetooth_off);
}
- state.contentDescription = mContext.getString(
- R.string.accessibility_quick_settings_bluetooth, stateContentDescription);
+
String bluetoothName = state.label;
if (connected) {
bluetoothName = state.dualLabelContentDescription = mContext.getString(
@@ -122,6 +123,15 @@
state.dualLabelContentDescription = bluetoothName;
}
+ @Override
+ protected String composeChangeAnnouncement() {
+ if (mState.value) {
+ return mContext.getString(R.string.accessibility_quick_settings_bluetooth_changed_on);
+ } else {
+ return mContext.getString(R.string.accessibility_quick_settings_bluetooth_changed_off);
+ }
+ }
+
private final BluetoothController.Callback mCallback = new BluetoothController.Callback() {
@Override
public void onBluetoothStateChange(boolean enabled, boolean connecting) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 6b3e871..6cd0f39 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -110,6 +110,15 @@
mDetailAdapter.updateItems(devices);
}
+ @Override
+ protected String composeChangeAnnouncement() {
+ if (!mState.value) {
+ // We only announce when it's turned off to avoid vocal overflow.
+ return mContext.getString(R.string.accessibility_casting_turned_off);
+ }
+ return null;
+ }
+
private String getDeviceName(CastDevice device) {
return device.name != null ? device.name
: mContext.getString(R.string.quick_settings_cast_device_default_name);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index edb5932..a62bbff 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -88,4 +88,15 @@
state.label = mContext.getString(R.string.quick_settings_inversion_label);
state.iconId = enabled ? R.drawable.ic_qs_inversion_on : R.drawable.ic_qs_inversion_off;
}
+
+ @Override
+ protected String composeChangeAnnouncement() {
+ if (mState.value) {
+ return mContext.getString(
+ R.string.accessibility_quick_settings_color_inversion_changed_on);
+ } else {
+ return mContext.getString(
+ R.string.accessibility_quick_settings_color_inversion_changed_off);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index 3ddf5e3..e6b7f02 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -94,6 +94,19 @@
state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label);
state.iconId = state.value
? R.drawable.ic_qs_flashlight_on : R.drawable.ic_qs_flashlight_off;
+ int onOrOffId = state.value
+ ? R.string.accessibility_quick_settings_flashlight_on
+ : R.string.accessibility_quick_settings_flashlight_off;
+ state.contentDescription = mContext.getString(onOrOffId);
+ }
+
+ @Override
+ protected String composeChangeAnnouncement() {
+ if (mState.value) {
+ return mContext.getString(R.string.accessibility_quick_settings_flashlight_changed_on);
+ } else {
+ return mContext.getString(R.string.accessibility_quick_settings_flashlight_changed_off);
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index 96333a3..9984fca 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -74,6 +74,15 @@
: R.drawable.ic_qs_hotspot_off;
}
+ @Override
+ protected String composeChangeAnnouncement() {
+ if (mState.value) {
+ return mContext.getString(R.string.accessibility_quick_settings_hotspot_changed_on);
+ } else {
+ return mContext.getString(R.string.accessibility_quick_settings_hotspot_changed_off);
+ }
+ }
+
private final class Callback implements HotspotController.Callback {
@Override
public void onHotspotChanged(boolean enabled) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index c4dd643..7ac6644 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -71,14 +71,21 @@
state.iconId = R.drawable.ic_qs_location_on;
state.label = mContext.getString(R.string.quick_settings_location_label);
state.contentDescription = mContext.getString(
- R.string.accessibility_quick_settings_location,
- mContext.getString(R.string.accessibility_desc_on));
+ R.string.accessibility_quick_settings_location_on);
} else {
state.iconId = R.drawable.ic_qs_location_off;
state.label = mContext.getString(R.string.quick_settings_location_label);
state.contentDescription = mContext.getString(
- R.string.accessibility_quick_settings_location,
- mContext.getString(R.string.accessibility_desc_off));
+ R.string.accessibility_quick_settings_location_off);
+ }
+ }
+
+ @Override
+ protected String composeChangeAnnouncement() {
+ if (mState.value) {
+ return mContext.getString(R.string.accessibility_quick_settings_location_changed_on);
+ } else {
+ return mContext.getString(R.string.accessibility_quick_settings_location_changed_off);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
index 21cf9ec..ae40a4d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
@@ -74,6 +74,38 @@
state.label = mContext.getString(R.string.quick_settings_rotation_unlocked_label);
state.icon = res.getDrawable(R.drawable.ic_qs_rotation_unlocked);
}
+ state.contentDescription = getAccessibilityString(
+ R.string.accessibility_rotation_lock_on_portrait,
+ R.string.accessibility_rotation_lock_on_landscape,
+ R.string.accessibility_rotation_lock_off);
+ }
+
+ /**
+ * Get the correct accessibility string based on the state
+ *
+ * @param idWhenPortrait The id which should be used when locked in portrait.
+ * @param idWhenLandscape The id which should be used when locked in landscape.
+ * @param idWhenOff The id which should be used when the rotation lock is off.
+ * @return
+ */
+ private String getAccessibilityString(int idWhenPortrait, int idWhenLandscape, int idWhenOff) {
+ int stringID;
+ if (mState.value) {
+ final boolean portrait = mContext.getResources().getConfiguration().orientation
+ != Configuration.ORIENTATION_LANDSCAPE;
+ stringID = portrait ? idWhenPortrait: idWhenLandscape;
+ } else {
+ stringID = idWhenOff;
+ }
+ return mContext.getString(stringID);
+ }
+
+ @Override
+ protected String composeChangeAnnouncement() {
+ return getAccessibilityString(
+ R.string.accessibility_rotation_lock_on_portrait_changed,
+ R.string.accessibility_rotation_lock_on_landscape_changed,
+ R.string.accessibility_rotation_lock_off_changed);
}
private final RotationLockControllerCallback mCallback = new RotationLockControllerCallback() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index a8bf026..b12c6c1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -40,6 +40,7 @@
private final NetworkController mController;
private final WifiDetailAdapter mDetailAdapter;
+ private final QSTile.SignalState mStateBeforeClick = newTileState();
public WifiTile(Host host) {
super(host);
@@ -80,6 +81,7 @@
@Override
protected void handleClick() {
+ mState.copyTo(mStateBeforeClick);
mController.setWifiEnabled(!mState.enabled);
}
@@ -140,6 +142,20 @@
state.dualLabelContentDescription = wifiName;
}
+ @Override
+ protected boolean shouldAnnouncementBeDelayed() {
+ return mStateBeforeClick.enabled == mState.enabled;
+ }
+
+ @Override
+ protected String composeChangeAnnouncement() {
+ if (mState.enabled) {
+ return mContext.getString(R.string.accessibility_quick_settings_wifi_changed_on);
+ } else {
+ return mContext.getString(R.string.accessibility_quick_settings_wifi_changed_off);
+ }
+ }
+
private static String removeDoubleQuotes(String string) {
if (string == null) return null;
final int length = string.length();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 3e2a398..44d8d23 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -26,6 +26,7 @@
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.os.AsyncTask;
+import android.os.Bundle;
import android.os.RemoteException;
import android.os.UserHandle;
import android.phone.PhoneManager;
@@ -36,7 +37,7 @@
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.TextView;
@@ -44,17 +45,23 @@
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.R;
-import com.android.systemui.statusbar.KeyguardIndicationController;
-import com.android.systemui.statusbar.policy.FlashlightController;
+import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyguardAffordanceView;
+import com.android.systemui.statusbar.KeyguardIndicationController;
+import com.android.systemui.statusbar.policy.AccessibilityController;
+import com.android.systemui.statusbar.policy.FlashlightController;
import com.android.systemui.statusbar.policy.PreviewInflater;
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
+import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
+
/**
* Implementation for the bottom area of the Keyguard, including camera/phone affordance and status
* text.
*/
public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickListener,
- UnlockMethodCache.OnUnlockMethodChangedListener {
+ UnlockMethodCache.OnUnlockMethodChangedListener,
+ AccessibilityController.AccessibilityStateChangedCallback, View.OnLongClickListener {
final static String TAG = "PhoneStatusBar/KeyguardBottomAreaView";
@@ -80,25 +87,63 @@
private FlashlightController mFlashlightController;
private PreviewInflater mPreviewInflater;
private KeyguardIndicationController mIndicationController;
- private boolean mFaceUnlockRunning;
+ private AccessibilityController mAccessibilityController;
+ private PhoneStatusBar mPhoneStatusBar;
+
+ private final TrustDrawable mTrustDrawable;
public KeyguardBottomAreaView(Context context) {
- super(context);
+ this(context, null);
}
public KeyguardBottomAreaView(Context context, AttributeSet attrs) {
- super(context, attrs);
+ this(context, attrs, 0);
}
public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
+ this(context, attrs, defStyleAttr, 0);
}
public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
+ mTrustDrawable = new TrustDrawable(mContext);
}
+ private AccessibilityDelegate mAccessibilityDelegate = new AccessibilityDelegate() {
+ @Override
+ public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(host, info);
+ String label = null;
+ if (host == mLockIcon) {
+ label = getResources().getString(R.string.unlock_label);
+ } else if (host == mCameraImageView) {
+ label = getResources().getString(R.string.camera_label);
+ } else if (host == mPhoneImageView) {
+ label = getResources().getString(R.string.phone_label);
+ }
+ info.addAction(new AccessibilityAction(ACTION_CLICK, label));
+ }
+
+ @Override
+ public boolean performAccessibilityAction(View host, int action, Bundle args) {
+ if (action == ACTION_CLICK) {
+ if (host == mLockIcon) {
+ mPhoneStatusBar.animateCollapsePanels(
+ CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
+ return true;
+ } else if (host == mCameraImageView) {
+ launchCamera();
+ return true;
+ } else if (host == mPhoneImageView) {
+ launchPhone();
+ return true;
+ }
+ }
+ return super.performAccessibilityAction(host, action, args);
+ }
+ };
+
@Override
protected void onFinishInflate() {
super.onFinishInflate();
@@ -109,7 +154,6 @@
mLockIcon = (KeyguardAffordanceView) findViewById(R.id.lock_icon);
mIndicationText = (TextView) findViewById(R.id.keyguard_indication_text);
watchForCameraPolicyChanges();
- watchForAccessibilityChanges();
updateCameraVisibility();
updatePhoneVisibility();
mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
@@ -120,6 +164,17 @@
mPreviewInflater = new PreviewInflater(mContext, new LockPatternUtils(mContext));
inflatePreviews();
mLockIcon.setOnClickListener(this);
+ mLockIcon.setBackground(mTrustDrawable);
+ mLockIcon.setOnLongClickListener(this);
+ mCameraImageView.setOnClickListener(this);
+ mPhoneImageView.setOnClickListener(this);
+ initAccessibility();
+ }
+
+ private void initAccessibility() {
+ mLockIcon.setAccessibilityDelegate(mAccessibilityDelegate);
+ mPhoneImageView.setAccessibilityDelegate(mAccessibilityDelegate);
+ mCameraImageView.setAccessibilityDelegate(mAccessibilityDelegate);
}
@Override
@@ -147,6 +202,15 @@
mFlashlightController = flashlightController;
}
+ public void setAccessibilityController(AccessibilityController accessibilityController) {
+ mAccessibilityController = accessibilityController;
+ accessibilityController.addStateChangedCallback(this);
+ }
+
+ public void setPhoneStatusBar(PhoneStatusBar phoneStatusBar) {
+ mPhoneStatusBar = phoneStatusBar;
+ }
+
private Intent getCameraIntent() {
KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
boolean currentUserHasTrust = updateMonitor.getUserHasTrust(
@@ -200,28 +264,24 @@
KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
}
- private void watchForAccessibilityChanges() {
- final AccessibilityManager am =
- (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
-
- // Set the initial state
- enableAccessibility(am.isTouchExplorationEnabled());
-
- // Watch for changes
- am.addTouchExplorationStateChangeListener(
- new AccessibilityManager.TouchExplorationStateChangeListener() {
- @Override
- public void onTouchExplorationStateChanged(boolean enabled) {
- enableAccessibility(enabled);
- }
- });
+ @Override
+ public void onStateChanged(boolean accessibilityEnabled, boolean touchExplorationEnabled) {
+ mCameraImageView.setClickable(touchExplorationEnabled);
+ mPhoneImageView.setClickable(touchExplorationEnabled);
+ mCameraImageView.setFocusable(accessibilityEnabled);
+ mPhoneImageView.setFocusable(accessibilityEnabled);
+ updateLockIconClickability();
}
- private void enableAccessibility(boolean touchExplorationEnabled) {
- mCameraImageView.setOnClickListener(touchExplorationEnabled ? this : null);
- mCameraImageView.setClickable(touchExplorationEnabled);
- mPhoneImageView.setOnClickListener(touchExplorationEnabled ? this : null);
- mPhoneImageView.setClickable(touchExplorationEnabled);
+ private void updateLockIconClickability() {
+ if (mAccessibilityController == null) {
+ return;
+ }
+ mLockIcon.setClickable(mUnlockMethodCache.isTrustManaged()
+ || mAccessibilityController.isTouchExplorationEnabled());
+ mLockIcon.setLongClickable(mAccessibilityController.isTouchExplorationEnabled()
+ && mUnlockMethodCache.isTrustManaged());
+ mLockIcon.setFocusable(mAccessibilityController.isAccessibilityEnabled());
}
@Override
@@ -231,12 +291,27 @@
} else if (v == mPhoneImageView) {
launchPhone();
} if (v == mLockIcon) {
- mIndicationController.showTransientIndication(
- R.string.keyguard_indication_trust_disabled);
- mLockPatternUtils.requireCredentialEntry(mLockPatternUtils.getCurrentUser());
+ if (!mAccessibilityController.isAccessibilityEnabled()) {
+ handleTrustCircleClick();
+ } else {
+ mPhoneStatusBar.animateCollapsePanels(
+ CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
+ }
}
}
+ @Override
+ public boolean onLongClick(View v) {
+ handleTrustCircleClick();
+ return true;
+ }
+
+ private void handleTrustCircleClick() {
+ mIndicationController.showTransientIndication(
+ R.string.keyguard_indication_trust_disabled);
+ mLockPatternUtils.requireCredentialEntry(mLockPatternUtils.getCurrentUser());
+ }
+
public void launchCamera() {
mFlashlightController.killFlashlight();
Intent intent = getCameraIntent();
@@ -267,27 +342,47 @@
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
+ if (isShown()) {
+ mTrustDrawable.start();
+ } else {
+ mTrustDrawable.stop();
+ }
if (changedView == this && visibility == VISIBLE) {
updateLockIcon();
updateCameraVisibility();
}
}
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mTrustDrawable.stop();
+ }
+
private void updateLockIcon() {
- if (getVisibility() != VISIBLE) {
+ boolean visible = isShown() && KeyguardUpdateMonitor.getInstance(mContext).isScreenOn();
+ if (visible) {
+ mTrustDrawable.start();
+ } else {
+ mTrustDrawable.stop();
+ }
+ if (!visible) {
return;
}
// TODO: Real icon for facelock.
- int iconRes = mFaceUnlockRunning ? R.drawable.ic_account_circle
+ int iconRes = mUnlockMethodCache.isFaceUnlockRunning() ? R.drawable.ic_account_circle
: mUnlockMethodCache.isMethodInsecure() ? R.drawable.ic_lock_open_24dp
: R.drawable.ic_lock_24dp;
mLockIcon.setImageResource(iconRes);
boolean trustManaged = mUnlockMethodCache.isTrustManaged();
- mLockIcon.setBackgroundResource(trustManaged && !mFaceUnlockRunning
- ? R.drawable.trust_circle : 0);
- mLockIcon.setClickable(trustManaged);
+ mTrustDrawable.setTrustManaged(trustManaged);
+
+ // TODO: Update content description depending on state
+ updateLockIconClickability();
}
+
+
public KeyguardAffordanceView getPhoneView() {
return mPhoneImageView;
}
@@ -355,8 +450,12 @@
}
@Override
- public void onFaceUnlockStateChanged(boolean running) {
- mFaceUnlockRunning = running;
+ public void onScreenTurnedOn() {
+ updateLockIcon();
+ }
+
+ @Override
+ public void onScreenTurnedOff(int why) {
updateLockIcon();
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index 5e5c3aa..650a14f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -30,6 +30,7 @@
import android.widget.RelativeLayout;
import android.widget.TextView;
+import com.android.systemui.BatteryMeterView;
import com.android.systemui.R;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
@@ -135,6 +136,7 @@
public void setBatteryController(BatteryController batteryController) {
mBatteryController = batteryController;
+ ((BatteryMeterView) findViewById(R.id.battery)).setBatteryController(batteryController);
}
public void setUserInfoController(UserInfoController userInfoController) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index decf231..b3042b9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -109,6 +109,7 @@
import com.android.internal.statusbar.StatusBarIcon;
import com.android.keyguard.KeyguardHostView.OnDismissAction;
import com.android.keyguard.ViewMediatorCallback;
+import com.android.systemui.BatteryMeterView;
import com.android.systemui.DemoMode;
import com.android.systemui.EventLogTags;
import com.android.systemui.R;
@@ -131,6 +132,7 @@
import com.android.systemui.statusbar.SpeedBumpView;
import com.android.systemui.statusbar.StatusBarIconView;
import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.policy.AccessibilityController;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
import com.android.systemui.statusbar.policy.BluetoothControllerImpl;
@@ -236,6 +238,7 @@
NextAlarmController mNextAlarmController;
KeyguardMonitor mKeyguardMonitor;
BrightnessMirrorController mBrightnessMirrorController;
+ AccessibilityController mAccessibilityController;
int mNaturalBarHeight = -1;
int mIconSize = -1;
@@ -804,6 +807,9 @@
mFlashlightController = new FlashlightController(mContext);
mKeyguardBottomArea.setFlashlightController(mFlashlightController);
+ mKeyguardBottomArea.setPhoneStatusBar(this);
+ mAccessibilityController = new AccessibilityController(mContext);
+ mKeyguardBottomArea.setAccessibilityController(mAccessibilityController);
mNextAlarmController = new NextAlarmController(mContext);
mKeyguardMonitor = new KeyguardMonitor();
mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor);
@@ -845,6 +851,8 @@
mUserInfoController.reloadUserInfo();
mHeader.setBatteryController(mBatteryController);
+ ((BatteryMeterView) mStatusBarView.findViewById(R.id.battery)).setBatteryController(
+ mBatteryController);
mKeyguardStatusBar.setBatteryController(mBatteryController);
mHeader.setNextAlarmController(mNextAlarmController);
@@ -1346,7 +1354,7 @@
updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
if (CLOSE_PANEL_WHEN_EMPTIED && !hasActiveNotifications()
- && !mNotificationPanel.isTracking()) {
+ && !mNotificationPanel.isTracking() && !mNotificationPanel.isQsExpanded()) {
if (mState == StatusBarState.SHADE) {
animateCollapsePanels();
} else if (mState == StatusBarState.SHADE_LOCKED) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index 8bc7dd4..807a37b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -714,6 +714,7 @@
final boolean showingDetail = detail != null;
transition(mClock, !showingDetail);
transition(mDateGroup, !showingDetail);
+ transition(mAlarmStatus, !showingDetail);
transition(mQsDetailHeader, showingDetail);
if (showingDetail) {
mQsDetailHeaderTitle.setText(detail.getTitle());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrustDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrustDrawable.java
new file mode 100644
index 0000000..dcda2c7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrustDrawable.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import com.android.systemui.R;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+
+public class TrustDrawable extends Drawable {
+
+ private static final long ENTERING_FROM_UNSET_START_DELAY = 200;
+ private static final long VISIBLE_DURATION = 1000;
+ private static final long EXIT_DURATION = 500;
+ private static final long ENTER_DURATION = 500;
+
+ private static final int ALPHA_VISIBLE_MIN = 0x26;
+ private static final int ALPHA_VISIBLE_MAX = 0x4c;
+
+ private static final int STATE_UNSET = -1;
+ private static final int STATE_GONE = 0;
+ private static final int STATE_ENTERING = 1;
+ private static final int STATE_VISIBLE = 2;
+ private static final int STATE_EXITING = 3;
+
+ private int mAlpha;
+ private boolean mAnimating;
+
+ private int mCurAlpha;
+ private float mCurInnerRadius;
+ private Animator mCurAnimator;
+ private int mState = STATE_UNSET;
+ private Paint mPaint;
+ private boolean mTrustManaged;
+
+ private final float mInnerRadiusVisibleMin;
+ private final float mInnerRadiusVisibleMax;
+ private final float mInnerRadiusExit;
+ private final float mInnerRadiusEnter;
+ private final float mThickness;
+
+ private final Animator mVisibleAnimator;
+
+ private final Interpolator mLinearOutSlowInInterpolator;
+ private final Interpolator mFastOutSlowInInterpolator;
+ private final Interpolator mAccelerateDecelerateInterpolator;
+
+ public TrustDrawable(Context context) {
+ Resources r = context.getResources();
+ mInnerRadiusVisibleMin = r.getDimension(R.dimen.trust_circle_inner_radius_visible_min);
+ mInnerRadiusVisibleMax = r.getDimension(R.dimen.trust_circle_inner_radius_visible_max);
+ mInnerRadiusExit = r.getDimension(R.dimen.trust_circle_inner_radius_exit);
+ mInnerRadiusEnter = r.getDimension(R.dimen.trust_circle_inner_radius_enter);
+ mThickness = r.getDimension(R.dimen.trust_circle_thickness);
+
+ mCurInnerRadius = mInnerRadiusEnter;
+
+ mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(
+ context, android.R.interpolator.linear_out_slow_in);
+ mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(
+ context, android.R.interpolator.fast_out_slow_in);
+ mAccelerateDecelerateInterpolator = new AccelerateDecelerateInterpolator();
+
+ mVisibleAnimator = makeVisibleAnimator();
+
+ mPaint = new Paint();
+ mPaint.setStyle(Paint.Style.STROKE);
+ mPaint.setColor(Color.WHITE);
+ mPaint.setAntiAlias(true);
+ mPaint.setStrokeWidth(mThickness);
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ int newAlpha = (mCurAlpha * mAlpha) / 256;
+ if (newAlpha == 0) {
+ return;
+ }
+ final Rect r = getBounds();
+ mPaint.setAlpha(newAlpha);
+ canvas.drawCircle(r.exactCenterX(), r.exactCenterY(), mCurInnerRadius, mPaint);
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ mAlpha = alpha;
+ }
+
+ @Override
+ public int getAlpha() {
+ return mAlpha;
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter cf) {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.TRANSLUCENT;
+ }
+
+ public void start() {
+ if (!mAnimating) {
+ mAnimating = true;
+ updateState(true);
+ }
+ }
+
+ public void stop() {
+ if (mAnimating) {
+ mAnimating = false;
+ if (mCurAnimator != null) {
+ mCurAnimator.cancel();
+ mCurAnimator = null;
+ }
+ mState = STATE_UNSET;
+ mCurAlpha = 0;
+ mCurInnerRadius = mInnerRadiusEnter;
+ }
+ }
+
+ public void setTrustManaged(boolean trustManaged) {
+ if (trustManaged == mTrustManaged && mState != STATE_UNSET) return;
+ mTrustManaged = trustManaged;
+ if (mAnimating) {
+ updateState(true);
+ }
+ }
+
+ private void updateState(boolean animate) {
+ int nextState = mState;
+ if (mState == STATE_UNSET) {
+ nextState = mTrustManaged ? STATE_ENTERING : STATE_GONE;
+ } else if (mState == STATE_GONE) {
+ if (mTrustManaged) nextState = STATE_ENTERING;
+ } else if (mState == STATE_ENTERING) {
+ if (!mTrustManaged) nextState = STATE_EXITING;
+ } else if (mState == STATE_VISIBLE) {
+ if (!mTrustManaged) nextState = STATE_EXITING;
+ } else if (mState == STATE_EXITING) {
+ if (mTrustManaged) nextState = STATE_ENTERING;
+ }
+ if (!animate) {
+ if (nextState == STATE_ENTERING) nextState = STATE_VISIBLE;
+ if (nextState == STATE_EXITING) nextState = STATE_GONE;
+ }
+
+ if (nextState != mState) {
+ if (mCurAnimator != null) {
+ mCurAnimator.cancel();
+ mCurAnimator = null;
+ }
+
+ if (nextState == STATE_GONE) {
+ mCurAlpha = 0;
+ mCurInnerRadius = mInnerRadiusEnter;
+ } else if (nextState == STATE_ENTERING) {
+ mCurAnimator = makeEnterAnimator(mCurInnerRadius, mCurAlpha);
+ if (mState == STATE_UNSET) {
+ mCurAnimator.setStartDelay(ENTERING_FROM_UNSET_START_DELAY);
+ }
+ } else if (nextState == STATE_VISIBLE) {
+ mCurAlpha = ALPHA_VISIBLE_MAX;
+ mCurInnerRadius = mInnerRadiusVisibleMax;
+ mCurAnimator = mVisibleAnimator;
+ } else if (nextState == STATE_EXITING) {
+ mCurAnimator = makeExitAnimator(mCurInnerRadius, mCurAlpha);
+ }
+
+ mState = nextState;
+ if (mCurAnimator != null) {
+ mCurAnimator.start();
+ } else {
+ invalidateSelf();
+ }
+ }
+ }
+
+ private Animator makeVisibleAnimator() {
+ return makeAnimators(mInnerRadiusVisibleMax, mInnerRadiusVisibleMin,
+ ALPHA_VISIBLE_MAX, ALPHA_VISIBLE_MIN, VISIBLE_DURATION,
+ mAccelerateDecelerateInterpolator,
+ true /* repeating */, false /* stateUpdateListener */);
+ }
+
+ private Animator makeEnterAnimator(float radius, int alpha) {
+ return makeAnimators(radius, mInnerRadiusVisibleMax,
+ alpha, ALPHA_VISIBLE_MAX, ENTER_DURATION, mLinearOutSlowInInterpolator,
+ false /* repeating */, true /* stateUpdateListener */);
+ }
+
+ private Animator makeExitAnimator(float radius, int alpha) {
+ return makeAnimators(radius, mInnerRadiusExit,
+ alpha, 0, EXIT_DURATION, mFastOutSlowInInterpolator,
+ false /* repeating */, true /* stateUpdateListener */);
+ }
+
+ private Animator makeAnimators(float startRadius, float endRadius,
+ int startAlpha, int endAlpha, long duration, Interpolator interpolator,
+ boolean repeating, boolean stateUpdateListener) {
+ ValueAnimator alphaAnimator = configureAnimator(
+ ValueAnimator.ofInt(startAlpha, endAlpha),
+ duration, mAlphaUpdateListener, interpolator, repeating);
+ ValueAnimator sizeAnimator = configureAnimator(
+ ValueAnimator.ofFloat(startRadius, endRadius),
+ duration, mRadiusUpdateListener, interpolator, repeating);
+
+ AnimatorSet set = new AnimatorSet();
+ set.playTogether(alphaAnimator, sizeAnimator);
+ if (stateUpdateListener) {
+ set.addListener(new StateUpdateAnimatorListener());
+ }
+ return set;
+ }
+
+ private ValueAnimator configureAnimator(ValueAnimator animator, long duration,
+ ValueAnimator.AnimatorUpdateListener updateListener, Interpolator interpolator,
+ boolean repeating) {
+ animator.setDuration(duration);
+ animator.addUpdateListener(updateListener);
+ animator.setInterpolator(interpolator);
+ if (repeating) {
+ animator.setRepeatCount(ValueAnimator.INFINITE);
+ animator.setRepeatMode(ValueAnimator.REVERSE);
+ }
+ return animator;
+ }
+
+ private final ValueAnimator.AnimatorUpdateListener mAlphaUpdateListener =
+ new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mCurAlpha = (int) animation.getAnimatedValue();
+ invalidateSelf();
+ }
+ };
+
+ private final ValueAnimator.AnimatorUpdateListener mRadiusUpdateListener =
+ new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mCurInnerRadius = (float) animation.getAnimatedValue();
+ invalidateSelf();
+ }
+ };
+
+ private class StateUpdateAnimatorListener extends AnimatorListenerAdapter {
+ boolean mCancelled;
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mCancelled = false;
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ mCancelled = true;
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (!mCancelled) {
+ updateState(false);
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
index 58196f7..e5eef9d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
@@ -38,6 +38,7 @@
private final ArrayList<OnUnlockMethodChangedListener> mListeners = new ArrayList<>();
private boolean mMethodInsecure;
private boolean mTrustManaged;
+ private boolean mFaceUnlockRunning;
private UnlockMethodCache(Context ctx) {
mLockPatternUtils = new LockPatternUtils(ctx);
@@ -73,10 +74,14 @@
boolean methodInsecure = !mLockPatternUtils.isSecure() ||
mKeyguardUpdateMonitor.getUserHasTrust(user);
boolean trustManaged = mKeyguardUpdateMonitor.getUserTrustIsManaged(user);
- boolean changed = methodInsecure != mMethodInsecure || trustManaged != mTrustManaged;
+ boolean faceUnlockRunning = mKeyguardUpdateMonitor.isFaceUnlockRunning(user)
+ && trustManaged;
+ boolean changed = methodInsecure != mMethodInsecure || trustManaged != mTrustManaged
+ || faceUnlockRunning != mFaceUnlockRunning;
if (changed || updateAlways) {
mMethodInsecure = methodInsecure;
mTrustManaged = trustManaged;
+ mFaceUnlockRunning = faceUnlockRunning;
notifyListeners(mMethodInsecure);
}
}
@@ -112,12 +117,21 @@
public void onFingerprintRecognized(int userId) {
updateMethodSecure(false /* updateAlways */);
}
+
+ @Override
+ public void onFaceUnlockStateChanged(boolean running, int userId) {
+ updateMethodSecure(false /* updateAlways */);
+ }
};
public boolean isTrustManaged() {
return mTrustManaged;
}
+ public boolean isFaceUnlockRunning() {
+ return mFaceUnlockRunning;
+ }
+
public static interface OnUnlockMethodChangedListener {
void onMethodSecureChanged(boolean methodSecure);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityController.java
new file mode 100644
index 0000000..89ed787
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityController.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.policy;
+
+import android.content.Context;
+import android.util.Log;
+import android.view.accessibility.AccessibilityManager;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+public class AccessibilityController implements
+ AccessibilityManager.AccessibilityStateChangeListener,
+ AccessibilityManager.TouchExplorationStateChangeListener {
+
+ private final ArrayList<AccessibilityStateChangedCallback> mChangeCallbacks = new ArrayList<>();
+
+ private boolean mAccessibilityEnabled;
+ private boolean mTouchExplorationEnabled;
+
+ public AccessibilityController(Context context) {
+ AccessibilityManager am =
+ (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
+ am.addTouchExplorationStateChangeListener(this);
+ am.addAccessibilityStateChangeListener(this);
+ mAccessibilityEnabled = am.isEnabled();
+ mTouchExplorationEnabled = am.isTouchExplorationEnabled();
+ }
+
+ public boolean isAccessibilityEnabled() {
+ return mAccessibilityEnabled;
+ }
+
+ public boolean isTouchExplorationEnabled() {
+ return mTouchExplorationEnabled;
+ }
+
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println("AccessibilityController state:");
+ pw.print(" mAccessibilityEnabled="); pw.println(mAccessibilityEnabled);
+ pw.print(" mTouchExplorationEnabled="); pw.println(mTouchExplorationEnabled);
+ }
+
+ public void addStateChangedCallback(AccessibilityStateChangedCallback cb) {
+ mChangeCallbacks.add(cb);
+ cb.onStateChanged(mAccessibilityEnabled, mTouchExplorationEnabled);
+ }
+
+ public void removeStateChangedCallback(AccessibilityStateChangedCallback cb) {
+ mChangeCallbacks.remove(cb);
+ }
+
+ private void fireChanged() {
+ final int N = mChangeCallbacks.size();
+ for (int i = 0; i < N; i++) {
+ mChangeCallbacks.get(i).onStateChanged(mAccessibilityEnabled, mTouchExplorationEnabled);
+ }
+ }
+
+ @Override
+ public void onAccessibilityStateChanged(boolean enabled) {
+ mAccessibilityEnabled = enabled;
+ fireChanged();
+ }
+
+ @Override
+ public void onTouchExplorationStateChanged(boolean enabled) {
+ mTouchExplorationEnabled = enabled;
+ fireChanged();
+ }
+
+ public interface AccessibilityStateChangedCallback {
+ void onStateChanged(boolean accessibilityEnabled, boolean touchExplorationEnabled);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
index 51876b8..8a14288 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
@@ -37,7 +37,7 @@
import android.media.ToneGenerator;
import android.media.VolumeProvider;
import android.media.session.MediaController;
-import android.media.session.MediaController.AudioInfo;
+import android.media.session.MediaController.PlaybackInfo;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
@@ -537,7 +537,7 @@
if (mStreamControls != null) {
StreamControl sc = mStreamControls.get(streamType);
if (sc != null && sc.controller != null) {
- AudioInfo ai = sc.controller.getAudioInfo();
+ PlaybackInfo ai = sc.controller.getPlaybackInfo();
return ai.getMaxVolume();
}
}
@@ -554,7 +554,7 @@
if (mStreamControls != null) {
StreamControl sc = mStreamControls.get(streamType);
if (sc != null && sc.controller != null) {
- AudioInfo ai = sc.controller.getAudioInfo();
+ PlaybackInfo ai = sc.controller.getPlaybackInfo();
return ai.getCurrentVolume();
}
}
@@ -990,7 +990,7 @@
// We still don't have one, ignore the command.
Log.w(mTag, "sent remote volume change without a controller!");
} else {
- AudioInfo vi = controller.getAudioInfo();
+ PlaybackInfo vi = controller.getPlaybackInfo();
index = vi.getCurrentVolume();
max = vi.getMaxVolume();
if ((vi.getVolumeControl() & VolumeProvider.VOLUME_CONTROL_FIXED) != 0) {
@@ -1362,7 +1362,7 @@
};
private final MediaController.Callback mMediaControllerCb = new MediaController.Callback() {
- public void onAudioInfoChanged(AudioInfo info) {
+ public void onAudioInfoChanged(PlaybackInfo info) {
onRemoteVolumeUpdateIfShown();
}
};
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 5900612..2e5d43f 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -867,6 +867,7 @@
// the timeout is suspended while a restore is in progress. Clean
// up now.
Slog.w(TAG, "Restore session timed out; aborting");
+ mActiveRestoreSession.markTimedOut();
post(mActiveRestoreSession.new EndRestoreRunnable(
BackupManagerService.this, mActiveRestoreSession));
}
@@ -8738,12 +8739,17 @@
private IBackupTransport mRestoreTransport = null;
RestoreSet[] mRestoreSets = null;
boolean mEnded = false;
+ boolean mTimedOut = false;
ActiveRestoreSession(String packageName, String transport) {
mPackageName = packageName;
mRestoreTransport = getTransport(transport);
}
+ public void markTimedOut() {
+ mTimedOut = true;
+ }
+
// --- Binder interface ---
public synchronized int getAvailableRestoreSets(IRestoreObserver observer) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
@@ -8756,6 +8762,11 @@
throw new IllegalStateException("Restore session already ended");
}
+ if (mTimedOut) {
+ Slog.i(TAG, "Session already timed out");
+ return -1;
+ }
+
long oldId = Binder.clearCallingIdentity();
try {
if (mRestoreTransport == null) {
@@ -8787,6 +8798,11 @@
throw new IllegalStateException("Restore session already ended");
}
+ if (mTimedOut) {
+ Slog.i(TAG, "Session already timed out");
+ return -1;
+ }
+
if (mRestoreTransport == null || mRestoreSets == null) {
Slog.e(TAG, "Ignoring restoreAll() with no restore set");
return -1;
@@ -8861,6 +8877,11 @@
throw new IllegalStateException("Restore session already ended");
}
+ if (mTimedOut) {
+ Slog.i(TAG, "Session already timed out");
+ return -1;
+ }
+
if (mRestoreTransport == null || mRestoreSets == null) {
Slog.e(TAG, "Ignoring restoreAll() with no restore set");
return -1;
@@ -8909,6 +8930,11 @@
throw new IllegalStateException("Restore session already ended");
}
+ if (mTimedOut) {
+ Slog.i(TAG, "Session already timed out");
+ return -1;
+ }
+
if (mPackageName != null) {
if (! mPackageName.equals(packageName)) {
Slog.e(TAG, "Ignoring attempt to restore pkg=" + packageName
@@ -9006,6 +9032,11 @@
public synchronized void endRestoreSession() {
if (DEBUG) Slog.d(TAG, "endRestoreSession");
+ if (mTimedOut) {
+ Slog.i(TAG, "Session already timed out");
+ return;
+ }
+
if (mEnded) {
throw new IllegalStateException("Restore session already ended");
}
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 07c9048..7b64139 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -121,6 +121,7 @@
private int mState;
private final BluetoothHandler mHandler;
private int mErrorRecoveryRetryCounter;
+ private final int mSystemUiUid;
private void registerForAirplaneMode(IntentFilter filter) {
final ContentResolver resolver = mContext.getContentResolver();
@@ -218,6 +219,15 @@
if (isBluetoothPersistedStateOn()) {
mEnableExternal = true;
}
+
+ int sysUiUid = -1;
+ try {
+ sysUiUid = mContext.getPackageManager().getPackageUid("com.android.systemui",
+ UserHandle.USER_OWNER);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.wtf(TAG, "Unable to resolve SystemUI's UID.", e);
+ }
+ mSystemUiUid = sysUiUid;
}
/**
@@ -1118,7 +1128,8 @@
try {
foregroundUser = ActivityManager.getCurrentUser();
valid = (callingUser == foregroundUser) ||
- callingAppId == Process.NFC_UID;
+ callingAppId == Process.NFC_UID ||
+ callingAppId == mSystemUiUid;
if (DBG) {
Log.d(TAG, "checkIfCallerIsForegroundUser: valid=" + valid
+ " callingUser=" + callingUser
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 05179a4..b1d84f58 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3463,7 +3463,7 @@
if (sourceRecord.app == null) {
throw new SecurityException("Called without a process attached to activity");
}
- if (sourceRecord.app.uid != Process.SYSTEM_UID) {
+ if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
// This is still okay, as long as this activity is running under the
// uid of the original calling activity.
if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 931f448..8aec392 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -3189,7 +3189,11 @@
void endLockTaskModeIfTaskEnding(TaskRecord task) {
if (mLockTaskModeTask != null && mLockTaskModeTask == task) {
+ final Message lockTaskMsg = Message.obtain();
+ lockTaskMsg.arg1 = mLockTaskModeTask.userId;
+ lockTaskMsg.what = LOCK_TASK_END_MSG;
mLockTaskModeTask = null;
+ mHandler.sendMessage(lockTaskMsg);
}
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 46cb6c3..2a1ceaa 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -87,7 +87,7 @@
private static final int SCREEN_DIM_MINIMUM_REDUCTION = 10;
private static final int COLOR_FADE_ON_ANIMATION_DURATION_MILLIS = 250;
- private static final int COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS = 600;
+ private static final int COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS = 400;
private static final int MSG_UPDATE_POWER_STATE = 1;
private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2;
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 84027e2..978a9f4 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -31,6 +31,7 @@
import android.media.session.ISessionController;
import android.media.session.ISessionControllerCallback;
import android.media.session.MediaController;
+import android.media.session.MediaController.PlaybackInfo;
import android.media.session.MediaSession;
import android.media.session.ParcelableVolumeInfo;
import android.media.session.PlaybackState;
@@ -111,7 +112,7 @@
private AudioAttributes mAudioAttrs;
private AudioManager mAudioManager;
private AudioManagerInternal mAudioManagerInternal;
- private int mVolumeType = MediaSession.PLAYBACK_TYPE_LOCAL;
+ private int mVolumeType = PlaybackInfo.PLAYBACK_TYPE_LOCAL;
private int mVolumeControlType = VolumeProvider.VOLUME_CONTROL_ABSOLUTE;
private int mMaxVolume = 0;
private int mCurrentVolume = 0;
@@ -237,7 +238,7 @@
} else if (direction < -1) {
direction = -1;
}
- if (mVolumeType == MediaSession.PLAYBACK_TYPE_LOCAL) {
+ if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) {
int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
mAudioManagerInternal.adjustStreamVolumeForUid(stream, direction, flags, packageName,
uid);
@@ -265,7 +266,7 @@
}
public void setVolumeTo(int value, int flags, String packageName, int uid) {
- if (mVolumeType == MediaSession.PLAYBACK_TYPE_LOCAL) {
+ if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) {
int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
mAudioManagerInternal.setStreamVolumeForUid(stream, value, flags, packageName, uid);
} else {
@@ -748,8 +749,8 @@
public void setPlaybackToLocal(AudioAttributes attributes) {
boolean typeChanged;
synchronized (mLock) {
- typeChanged = mVolumeType == MediaSession.PLAYBACK_TYPE_REMOTE;
- mVolumeType = MediaSession.PLAYBACK_TYPE_LOCAL;
+ typeChanged = mVolumeType == PlaybackInfo.PLAYBACK_TYPE_REMOTE;
+ mVolumeType = PlaybackInfo.PLAYBACK_TYPE_LOCAL;
if (attributes != null) {
mAudioAttrs = attributes;
} else {
@@ -765,8 +766,8 @@
public void setPlaybackToRemote(int control, int max) {
boolean typeChanged;
synchronized (mLock) {
- typeChanged = mVolumeType == MediaSession.PLAYBACK_TYPE_LOCAL;
- mVolumeType = MediaSession.PLAYBACK_TYPE_REMOTE;
+ typeChanged = mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL;
+ mVolumeType = PlaybackInfo.PLAYBACK_TYPE_REMOTE;
mVolumeControlType = control;
mMaxVolume = max;
}
@@ -998,7 +999,7 @@
int type;
int max;
int current;
- if (mVolumeType == MediaSession.PLAYBACK_TYPE_REMOTE) {
+ if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_REMOTE) {
type = mVolumeControlType;
max = mMaxVolume;
current = mOptimisticVolume != -1 ? mOptimisticVolume
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 1221aa4..0c6d46c 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -37,6 +37,7 @@
import android.media.session.ISession;
import android.media.session.ISessionCallback;
import android.media.session.ISessionManager;
+import android.media.session.MediaController.PlaybackInfo;
import android.media.session.MediaSession;
import android.net.Uri;
import android.os.Binder;
@@ -814,7 +815,7 @@
} else {
session.adjustVolume(direction, flags, getContext().getPackageName(),
UserHandle.myUserId());
- if (session.getPlaybackType() == MediaSession.PLAYBACK_TYPE_REMOTE
+ if (session.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_REMOTE
&& mRvc != null) {
try {
mRvc.remoteVolumeChanged(session.getControllerBinder(), flags);
diff --git a/services/core/java/com/android/server/media/MediaSessionStack.java b/services/core/java/com/android/server/media/MediaSessionStack.java
index fec11fba..a9bc818 100644
--- a/services/core/java/com/android/server/media/MediaSessionStack.java
+++ b/services/core/java/com/android/server/media/MediaSessionStack.java
@@ -16,6 +16,7 @@
package com.android.server.media;
+import android.media.session.MediaController.PlaybackInfo;
import android.media.session.PlaybackState;
import android.media.session.MediaSession;
import android.os.UserHandle;
@@ -209,7 +210,7 @@
int size = records.size();
for (int i = 0; i < size; i++) {
MediaSessionRecord record = records.get(i);
- if (record.getPlaybackType() == MediaSession.PLAYBACK_TYPE_REMOTE) {
+ if (record.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_REMOTE) {
return record;
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 7117933..45bd812 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1528,14 +1528,15 @@
}
checkCallerIsSystemOrSameApp(pkg);
final boolean isSystemNotification = isUidSystem(callingUid) || ("android".equals(pkg));
+ final boolean isNotificationFromListener = mListeners.isListenerPackage(pkg);
final int userId = ActivityManager.handleIncomingUser(callingPid,
callingUid, incomingUserId, true, false, "enqueueNotification", pkg);
final UserHandle user = new UserHandle(userId);
// Limit the number of notifications that any given package except the android
- // package can enqueue. Prevents DOS attacks and deals with leaks.
- if (!isSystemNotification) {
+ // package or a registered listener can enqueue. Prevents DOS attacks and deals with leaks.
+ if (!isSystemNotification && !isNotificationFromListener) {
synchronized (mNotificationList) {
int count = 0;
final int N = mNotificationList.size();
@@ -2720,6 +2721,21 @@
Log.e(TAG, "unable to notify listener (listener hints): " + listener, ex);
}
}
+
+ private boolean isListenerPackage(String packageName) {
+ if (packageName == null) {
+ return false;
+ }
+ // TODO: clean up locking object later
+ synchronized (mNotificationList) {
+ for (final ManagedServiceInfo serviceInfo : mServices) {
+ if (packageName.equals(serviceInfo.component.getPackageName())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
}
public static final class DumpFilter {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 0393518..03cb2e9 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -56,6 +56,7 @@
import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
+import android.os.Environment.UserEnvironment;
import android.os.FileUtils;
import android.os.Handler;
import android.os.HandlerThread;
@@ -485,7 +486,8 @@
// Brand new install, use best resolved location. This also verifies
// that target has enough free space for the install.
final int resolved = PackageHelper.resolveInstallLocation(mContext,
- params.installLocation, params.sizeBytes, params.installFlags);
+ params.appPackageName, params.installLocation, params.sizeBytes,
+ params.installFlags);
if (resolved == PackageHelper.RECOMMEND_INSTALL_INTERNAL) {
stageInternal = true;
} else if (resolved == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
@@ -568,7 +570,8 @@
private void checkExternalStorage(long sizeBytes) throws IOException {
if (sizeBytes <= 0) return;
- final File target = Environment.getExternalStorageDirectory();
+ final File target = new UserEnvironment(UserHandle.USER_OWNER)
+ .getExternalStorageDirectory();
final long targetBytes = sizeBytes + mStorage.getStorageLowBytes(target);
if (target.getUsableSpace() < targetBytes) {
@@ -696,7 +699,7 @@
mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "uninstall");
final PackageDeleteObserverAdapter adapter = new PackageDeleteObserverAdapter(mContext,
- statusReceiver);
+ statusReceiver, packageName);
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DELETE_PACKAGES)
== PackageManager.PERMISSION_GRANTED) {
// Sweet, call straight through!
@@ -773,15 +776,19 @@
static class PackageDeleteObserverAdapter extends PackageDeleteObserver {
private final Context mContext;
private final IntentSender mTarget;
+ private final String mPackageName;
- public PackageDeleteObserverAdapter(Context context, IntentSender target) {
+ public PackageDeleteObserverAdapter(Context context, IntentSender target,
+ String packageName) {
mContext = context;
mTarget = target;
+ mPackageName = packageName;
}
@Override
public void onUserActionRequired(Intent intent) {
final Intent fillIn = new Intent();
+ fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, mPackageName);
fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
PackageInstaller.STATUS_PENDING_USER_ACTION);
fillIn.putExtra(Intent.EXTRA_INTENT, intent);
@@ -794,6 +801,7 @@
@Override
public void onPackageDeleted(String basePackageName, int returnCode, String msg) {
final Intent fillIn = new Intent();
+ fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, mPackageName);
fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
PackageManager.deleteStatusToPublicStatus(returnCode));
fillIn.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE,
@@ -809,15 +817,18 @@
static class PackageInstallObserverAdapter extends PackageInstallObserver {
private final Context mContext;
private final IntentSender mTarget;
+ private final int mSessionId;
- public PackageInstallObserverAdapter(Context context, IntentSender target) {
+ public PackageInstallObserverAdapter(Context context, IntentSender target, int sessionId) {
mContext = context;
mTarget = target;
+ mSessionId = sessionId;
}
@Override
public void onUserActionRequired(Intent intent) {
final Intent fillIn = new Intent();
+ fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, mSessionId);
fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
PackageInstaller.STATUS_PENDING_USER_ACTION);
fillIn.putExtra(Intent.EXTRA_INTENT, intent);
@@ -831,6 +842,7 @@
public void onPackageInstalled(String basePackageName, int returnCode, String msg,
Bundle extras) {
final Intent fillIn = new Intent();
+ fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, mSessionId);
fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
PackageManager.installStatusToPublicStatus(returnCode));
fillIn.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE,
@@ -840,8 +852,7 @@
final String existing = extras.getString(
PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE);
if (!TextUtils.isEmpty(existing)) {
- fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAMES, new String[] {
- existing });
+ fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, existing);
}
}
try {
@@ -986,5 +997,12 @@
}
writeSessionsAsync();
}
+
+ public void onSessionSealed(PackageInstallerSession session) {
+ // It's very important that we block until we've recorded the
+ // session as being sealed, since we never want to allow mutation
+ // after sealing.
+ writeSessionsLocked();
+ }
}
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 0616460..38a2016 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -195,6 +195,11 @@
this.internalStageDir = internalStageDir;
this.externalStageCid = externalStageCid;
+ if ((internalStageDir == null) == (externalStageCid == null)) {
+ throw new IllegalArgumentException(
+ "Exactly one of internal or external stage must be set");
+ }
+
mSealed = sealed;
// Always derived at runtime
@@ -395,7 +400,7 @@
Preconditions.checkNotNull(statusReceiver);
final PackageInstallObserverAdapter adapter = new PackageInstallObserverAdapter(mContext,
- statusReceiver);
+ statusReceiver, sessionId);
mHandler.obtainMessage(MSG_COMMIT, adapter.getBinder()).sendToTarget();
}
@@ -414,8 +419,9 @@
}
mSealed = true;
- // TODO: persist disabled mutations before going forward, since
- // beyond this point we may have hardlinks to the valid install
+ // Persist the fact that we've sealed ourselves to prevent mutations
+ // of any hard links we create below.
+ mCallback.onSessionSealed(this);
}
final File stageDir;
@@ -476,9 +482,8 @@
}
};
- // TODO: send ASEC cid if that's where we staged things
- mPm.installStage(mPackageName, this.internalStageDir, null, localObserver, params,
- installerPackageName, installerUid, new UserHandle(userId));
+ mPm.installStage(mPackageName, this.internalStageDir, this.externalStageCid, localObserver,
+ params, installerPackageName, installerUid, new UserHandle(userId));
}
/**
@@ -486,6 +491,9 @@
* consistent package name, version code, and signing certificates.
* <p>
* Renames package files in stage to match split names defined inside.
+ * <p>
+ * Note that upgrade compatibility is still performed by
+ * {@link PackageManagerService}.
*/
private void validateInstallLocked(File stageDir) throws PackageManagerException {
mPackageName = null;
@@ -498,13 +506,17 @@
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "No packages staged");
}
- final ArraySet<String> seenSplits = new ArraySet<>();
-
// Verify that all staged packages are internally consistent
+ final ArraySet<String> seenSplits = new ArraySet<>();
for (File file : files) {
+
+ // Installers can't stage directories, so it's fine to ignore
+ // entries like "lost+found".
+ if (file.isDirectory()) continue;
+
final ApkLite info;
try {
- info = PackageParser.parseApkLite(file, PackageParser.PARSE_GET_SIGNATURES);
+ info = PackageParser.parseApkLite(file, PackageParser.PARSE_COLLECT_CERTIFICATES);
} catch (PackageParserException e) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
"Failed to parse " + file + ": " + e);
@@ -550,10 +562,6 @@
}
}
- // TODO: shift package signature verification to installer; we're
- // currently relying on PMS to do this.
- // TODO: teach about compatible upgrade keysets.
-
if (params.mode == SessionParams.MODE_FULL_INSTALL) {
// Full installs must include a base package
if (!seenSplits.contains(null)) {
@@ -577,7 +585,7 @@
final ApkLite info;
try {
info = PackageParser.parseApkLite(new File(app.getBaseCodePath()),
- PackageParser.PARSE_GET_SIGNATURES);
+ PackageParser.PARSE_COLLECT_CERTIFICATES);
} catch (PackageParserException e) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
"Failed to parse existing base " + app.getBaseCodePath() + ": " + e);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index f47e64f..aa49b27 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -48,11 +48,6 @@
import static android.os.Process.SYSTEM_UID;
import static android.system.OsConstants.O_CREAT;
import static android.system.OsConstants.O_RDWR;
-import static android.system.OsConstants.S_IRGRP;
-import static android.system.OsConstants.S_IROTH;
-import static android.system.OsConstants.S_IRWXU;
-import static android.system.OsConstants.S_IXGRP;
-import static android.system.OsConstants.S_IXOTH;
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER;
import static com.android.internal.util.ArrayUtils.appendInt;
@@ -70,7 +65,6 @@
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.IndentingPrintWriter;
-import com.android.internal.util.Preconditions;
import com.android.server.EventLogTags;
import com.android.server.IntentResolver;
import com.android.server.LocalServices;
@@ -255,10 +249,6 @@
// package apks to install directory.
private static final String INSTALL_PACKAGE_SUFFIX = "-";
- // Special value for {@code PackageParser.Package#cpuAbiOverride} to indicate
- // that the cpuAbiOverride must be clear.
- private static final String CLEAR_ABI_OVERRIDE = "-";
-
static final int SCAN_MONITOR = 1<<0;
static final int SCAN_NO_DEX = 1<<1;
static final int SCAN_FORCE_DEX = 1<<2;
@@ -5022,7 +5012,7 @@
private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
String cpuAbiOverride = null;
- if (CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
+ if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
cpuAbiOverride = null;
} else if (abiOverride != null) {
cpuAbiOverride = abiOverride;
@@ -5526,7 +5516,8 @@
// Warn if we've set an abiOverride for multi-lib packages..
// By definition, we need to copy both 32 and 64 bit libraries for
// such packages.
- if (pkg.cpuAbiOverride != null && !CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
+ if (pkg.cpuAbiOverride != null
+ && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
}
@@ -5536,7 +5527,7 @@
if (isAsec) {
abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
} else {
- abi32 = copyNativeLibrariesForInternalApp(handle,
+ abi32 = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle,
nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, useIsaSpecificSubdirs);
}
}
@@ -5548,7 +5539,7 @@
if (isAsec) {
abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
} else {
- abi64 = copyNativeLibrariesForInternalApp(handle,
+ abi64 = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle,
nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, useIsaSpecificSubdirs);
}
}
@@ -5587,8 +5578,8 @@
if (isAsec) {
copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
} else {
- copyRet = copyNativeLibrariesForInternalApp(handle, nativeLibraryRoot, abiList,
- useIsaSpecificSubdirs);
+ copyRet = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle,
+ nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
}
if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
@@ -6471,58 +6462,6 @@
}
}
- private static void createNativeLibrarySubdir(File path) throws IOException {
- if (!path.isDirectory()) {
- path.delete();
-
- if (!path.mkdir()) {
- throw new IOException("Cannot create " + path.getPath());
- }
-
- try {
- Os.chmod(path.getPath(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
- } catch (ErrnoException e) {
- throw new IOException("Cannot chmod native library directory "
- + path.getPath(), e);
- }
- } else if (!SELinux.restorecon(path)) {
- throw new IOException("Cannot set SELinux context for " + path.getPath());
- }
- }
-
- private static int copyNativeLibrariesForInternalApp(NativeLibraryHelper.Handle handle,
- final File nativeLibraryRoot, String[] abiList, boolean useIsaSubdir) throws IOException {
- createNativeLibrarySubdir(nativeLibraryRoot);
-
- /*
- * If this is an internal application or our nativeLibraryPath points to
- * the app-lib directory, unpack the libraries if necessary.
- */
- int abi = NativeLibraryHelper.findSupportedAbi(handle, abiList);
- if (abi >= 0) {
- /*
- * If we have a matching instruction set, construct a subdir under the native
- * library root that corresponds to this instruction set.
- */
- final String instructionSet = VMRuntime.getInstructionSet(abiList[abi]);
- final File subDir;
- if (useIsaSubdir) {
- final File isaSubdir = new File(nativeLibraryRoot, instructionSet);
- createNativeLibrarySubdir(isaSubdir);
- subDir = isaSubdir;
- } else {
- subDir = nativeLibraryRoot;
- }
-
- int copyRet = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle, subDir, abiList[abi]);
- if (copyRet != PackageManager.INSTALL_SUCCEEDED) {
- return copyRet;
- }
- }
-
- return abi;
- }
-
private void killApplication(String pkgName, int appId, String reason) {
// Request the ActivityManager to kill the process(only for existing packages)
// so that we do not end up in a confused state while the user is still using the older
@@ -8667,6 +8606,20 @@
*/
public void handleStartCopy() throws RemoteException {
int ret = PackageManager.INSTALL_SUCCEEDED;
+
+ // If we're already staged, we've firmly committed to an install location
+ if (originStaged) {
+ if (originFile != null) {
+ flags |= PackageManager.INSTALL_INTERNAL;
+ flags &= ~PackageManager.INSTALL_EXTERNAL;
+ } else if (originCid != null) {
+ flags |= PackageManager.INSTALL_EXTERNAL;
+ flags &= ~PackageManager.INSTALL_INTERNAL;
+ } else {
+ throw new IllegalStateException("Invalid stage location");
+ }
+ }
+
final boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0;
final boolean onInt = (flags & PackageManager.INSTALL_INTERNAL) != 0;
PackageInfoLite pkgLite = null;
@@ -8690,7 +8643,7 @@
* If we have too little free space, try to free cache
* before giving up.
*/
- if (pkgLite.recommendedInstallLocation
+ if (!originStaged && pkgLite.recommendedInstallLocation
== PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
// TODO: focus freeing disk space on the target device
final StorageManager storage = StorageManager.from(mContext);
@@ -9287,49 +9240,11 @@
NativeLibraryHelper.Handle handle = null;
try {
handle = NativeLibraryHelper.Handle.create(codeFile);
- if (multiArch) {
- // Warn if we've set an abiOverride for multi-lib packages..
- // By definition, we need to copy both 32 and 64 bit libraries for
- // such packages.
- if (abiOverride != null && !CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
- Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
- }
-
- int copyRet = PackageManager.NO_NATIVE_LIBRARIES;
- if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
- copyRet = copyNativeLibrariesForInternalApp(handle, libraryRoot,
- Build.SUPPORTED_32_BIT_ABIS, true /* use isa specific subdirs */);
- maybeThrowExceptionForMultiArchCopy("Failure copying 32 bit native libraries", copyRet);
- }
-
- if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
- copyRet = copyNativeLibrariesForInternalApp(handle, libraryRoot,
- Build.SUPPORTED_64_BIT_ABIS, true /* use isa specific subdirs */);
- maybeThrowExceptionForMultiArchCopy("Failure copying 64 bit native libraries", copyRet);
- }
- } else {
- final String cpuAbiOverride = deriveAbiOverride(this.abiOverride, null /* package setting */);
- String[] abiList = (cpuAbiOverride != null) ?
- new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
-
- if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
- NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
- abiList = Build.SUPPORTED_32_BIT_ABIS;
- }
-
- int copyRet = copyNativeLibrariesForInternalApp(handle, libraryRoot, abiList,
- true /* use isa specific subdirs */);
- if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
- Slog.w(TAG, "Failure copying native libraries [errorCode=" + copyRet + "]");
- return copyRet;
- }
- }
+ ret = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle, libraryRoot,
+ abiOverride, multiArch);
} catch (IOException e) {
Slog.e(TAG, "Copying native libraries failed", e);
ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
- } catch (PackageManagerException pme) {
- Slog.e(TAG, "Copying native libraries failed", pme);
- ret = pme.error;
} finally {
IoUtils.closeQuietly(handle);
}
@@ -9504,8 +9419,6 @@
* renaming logic.
*/
class AsecInstallArgs extends InstallArgs {
- // TODO: teach about handling cluster directories
-
static final String RES_FILE_NAME = "pkg.apk";
static final String PUBLIC_RES_FILE_NAME = "res.zip";
@@ -9528,12 +9441,17 @@
super(null, false, null, (isExternal ? INSTALL_EXTERNAL : 0)
| (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
instructionSets, null, isMultiArch);
+ // Hackily pretend we're still looking at a full code path
+ if (!fullCodePath.endsWith(RES_FILE_NAME)) {
+ fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
+ }
+
// Extract cid from fullCodePath
int eidx = fullCodePath.lastIndexOf("/");
String subStr1 = fullCodePath.substring(0, eidx);
int sidx = subStr1.lastIndexOf("/");
cid = subStr1.substring(sidx+1, eidx);
- setCachePath(subStr1);
+ setMountPath(subStr1);
}
AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked,
@@ -9542,7 +9460,7 @@
| (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
instructionSets, null, isMultiArch);
this.cid = cid;
- setCachePath(PackageHelper.getSdDir(cid));
+ setMountPath(PackageHelper.getSdDir(cid));
}
/** New install from existing */
@@ -9564,7 +9482,7 @@
final File target;
if (isExternal()) {
- target = Environment.getExternalStorageDirectory();
+ target = new UserEnvironment(UserHandle.USER_OWNER).getExternalStorageDirectory();
} else {
target = Environment.getDataDirectory();
}
@@ -9578,6 +9496,7 @@
}
int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
+ // TODO: if already staged, we only need to extract native code
if (temp) {
createCopyFile();
} else {
@@ -9588,12 +9507,12 @@
PackageHelper.destroySdDir(cid);
}
- final String newCachePath = imcs.copyPackageToContainer(
+ final String newMountPath = imcs.copyPackageToContainer(
originFile.getAbsolutePath(), cid, getEncryptKey(), isExternal(),
isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
- if (newCachePath != null) {
- setCachePath(newCachePath);
+ if (newMountPath != null) {
+ setMountPath(newMountPath);
return PackageManager.INSTALL_SUCCEEDED;
} else {
return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
@@ -9622,10 +9541,10 @@
} else {
boolean mounted = PackageHelper.isContainerMounted(cid);
if (!mounted) {
- String newCachePath = PackageHelper.mountSdDir(cid, getEncryptKey(),
+ String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
Process.SYSTEM_UID);
- if (newCachePath != null) {
- setCachePath(newCachePath);
+ if (newMountPath != null) {
+ setMountPath(newMountPath);
} else {
return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
}
@@ -9636,7 +9555,7 @@
boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
- String newCachePath = null;
+ String newMountPath = null;
if (PackageHelper.isContainerMounted(cid)) {
// Unmount the container
if (!PackageHelper.unMountSdDir(cid)) {
@@ -9661,46 +9580,59 @@
}
if (!PackageHelper.isContainerMounted(newCacheId)) {
Slog.w(TAG, "Mounting container " + newCacheId);
- newCachePath = PackageHelper.mountSdDir(newCacheId,
+ newMountPath = PackageHelper.mountSdDir(newCacheId,
getEncryptKey(), Process.SYSTEM_UID);
} else {
- newCachePath = PackageHelper.getSdDir(newCacheId);
+ newMountPath = PackageHelper.getSdDir(newCacheId);
}
- if (newCachePath == null) {
+ if (newMountPath == null) {
Slog.w(TAG, "Failed to get cache path for " + newCacheId);
return false;
}
Log.i(TAG, "Succesfully renamed " + cid +
" to " + newCacheId +
- " at new path: " + newCachePath);
+ " at new path: " + newMountPath);
cid = newCacheId;
- setCachePath(newCachePath);
- // TODO: extend to support split APKs
- pkg.codePath = getCodePath();
- pkg.baseCodePath = getCodePath();
- pkg.splitCodePaths = null;
+ final File beforeCodeFile = new File(packagePath);
+ setMountPath(newMountPath);
+ final File afterCodeFile = new File(packagePath);
- pkg.applicationInfo.setCodePath(getCodePath());
- pkg.applicationInfo.setBaseCodePath(getCodePath());
- pkg.applicationInfo.setSplitCodePaths(null);
- pkg.applicationInfo.setResourcePath(getResourcePath());
- pkg.applicationInfo.setBaseResourcePath(getResourcePath());
- pkg.applicationInfo.setSplitResourcePaths(null);
+ // Reflect the rename in scanned details
+ pkg.codePath = afterCodeFile.getAbsolutePath();
+ pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
+ pkg.baseCodePath);
+ pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
+ pkg.splitCodePaths);
+
+ // Reflect the rename in app info
+ pkg.applicationInfo.setCodePath(pkg.codePath);
+ pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
+ pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
+ pkg.applicationInfo.setResourcePath(pkg.codePath);
+ pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
+ pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
return true;
}
- private void setCachePath(String newCachePath) {
- File cachePath = new File(newCachePath);
- legacyNativeLibraryDir = new File(cachePath, LIB_DIR_NAME).getPath();
- packagePath = new File(cachePath, RES_FILE_NAME).getPath();
+ private void setMountPath(String mountPath) {
+ final File mountFile = new File(mountPath);
- if (isFwdLocked()) {
- resourcePath = new File(cachePath, PUBLIC_RES_FILE_NAME).getPath();
+ final File monolithicFile = new File(mountFile, RES_FILE_NAME);
+ if (monolithicFile.exists()) {
+ packagePath = monolithicFile.getAbsolutePath();
+ if (isFwdLocked()) {
+ resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
+ } else {
+ resourcePath = packagePath;
+ }
} else {
+ packagePath = mountFile.getAbsolutePath();
resourcePath = packagePath;
}
+
+ legacyNativeLibraryDir = new File(mountFile, LIB_DIR_NAME).getAbsolutePath();
}
int doPostInstall(int status, int uid) {
@@ -9739,23 +9671,43 @@
PackageHelper.destroySdDir(cid);
}
- void cleanUpResourcesLI() {
- String sourceFile = getCodePath();
- // Remove dex file
- if (instructionSets == null) {
- throw new IllegalStateException("instructionSet == null");
- }
- String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
- for (String dexCodeInstructionSet : dexCodeInstructionSets) {
- int retCode = mInstaller.rmdex(sourceFile, dexCodeInstructionSet);
- if (retCode < 0) {
- Slog.w(TAG, "Couldn't remove dex file for package: "
- + " at location "
- + sourceFile.toString() + ", retcode=" + retCode);
- // we don't consider this to be a failure of the core package deletion
+ private List<String> getAllCodePaths() {
+ final File codeFile = new File(getCodePath());
+ if (codeFile != null && codeFile.exists()) {
+ try {
+ final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
+ return pkg.getAllCodePaths();
+ } catch (PackageParserException e) {
+ // Ignored; we tried our best
}
}
+ return Collections.EMPTY_LIST;
+ }
+
+ void cleanUpResourcesLI() {
+ // Enumerate all code paths before deleting
+ cleanUpResourcesLI(getAllCodePaths());
+ }
+
+ private void cleanUpResourcesLI(List<String> allCodePaths) {
cleanUp();
+
+ if (!allCodePaths.isEmpty()) {
+ if (instructionSets == null) {
+ throw new IllegalStateException("instructionSet == null");
+ }
+ String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
+ for (String codePath : allCodePaths) {
+ for (String dexCodeInstructionSet : dexCodeInstructionSets) {
+ int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
+ if (retCode < 0) {
+ Slog.w(TAG, "Couldn't remove dex file for package: "
+ + " at location " + codePath + ", retcode=" + retCode);
+ // we don't consider this to be a failure of the core package deletion
+ }
+ }
+ }
+ }
}
boolean matchContainer(String app) {
@@ -9770,16 +9722,19 @@
}
boolean doPostDeleteLI(boolean delete) {
- boolean ret = false;
+ if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
+ final List<String> allCodePaths = getAllCodePaths();
boolean mounted = PackageHelper.isContainerMounted(cid);
if (mounted) {
// Unmount first
- ret = PackageHelper.unMountSdDir(cid);
+ if (PackageHelper.unMountSdDir(cid)) {
+ mounted = false;
+ }
}
- if (ret && delete) {
- cleanUpResourcesLI();
+ if (!mounted && delete) {
+ cleanUpResourcesLI(allCodePaths);
}
- return ret;
+ return !mounted;
}
@Override
@@ -10966,6 +10921,7 @@
outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
getAppDexInstructionSets(ps), isMultiArch(ps));
+ if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
}
return true;
}
@@ -12772,7 +12728,8 @@
getAppDexInstructionSets(ps), isForwardLocked(ps), isMultiArch(ps));
// The package status is changed only if the code path
// matches between settings and the container id.
- if (ps.codePathString != null && ps.codePathString.equals(args.getCodePath())) {
+ if (ps.codePathString != null
+ && ps.codePathString.startsWith(args.getCodePath())) {
if (DEBUG_SD_INSTALL) {
Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
+ " at code path: " + ps.codePathString);
@@ -12851,7 +12808,7 @@
continue;
}
// Check code path here.
- if (codePath == null || !codePath.equals(args.getCodePath())) {
+ if (codePath == null || !codePath.startsWith(args.getCodePath())) {
Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
+ " does not match one in settings " + codePath);
continue;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 2c3c510..02f8bd5 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -18,18 +18,6 @@
import static android.Manifest.permission.MANAGE_CA_CERTIFICATES;
-import android.app.admin.DevicePolicyManagerInternal;
-
-import com.android.internal.R;
-import com.android.internal.os.storage.ExternalStorageFormatter;
-import com.android.internal.util.FastXmlSerializer;
-import com.android.internal.util.JournaledFile;
-import com.android.internal.util.XmlUtils;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.org.conscrypt.TrustedCertificateStore;
-import com.android.server.LocalServices;
-import com.android.server.SystemService;
-
import android.app.Activity;
import android.app.ActivityManagerNative;
import android.app.AlarmManager;
@@ -41,6 +29,7 @@
import android.app.admin.DeviceAdminInfo;
import android.app.admin.DeviceAdminReceiver;
import android.app.admin.DevicePolicyManager;
+import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.IDevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -90,6 +79,16 @@
import android.util.Xml;
import android.view.IWindowManager;
+import com.android.internal.R;
+import com.android.internal.os.storage.ExternalStorageFormatter;
+import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.JournaledFile;
+import com.android.internal.util.XmlUtils;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.org.conscrypt.TrustedCertificateStore;
+import com.android.server.LocalServices;
+import com.android.server.SystemService;
+
import org.xmlpull.v1.XmlPullParser;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
@@ -147,6 +146,21 @@
private static final String ATTR_PERMISSION_PROVIDER = "permission-provider";
private static final String ATTR_SETUP_COMPLETE = "setup-complete";
+ private static final Set<String> DEVICE_OWNER_USER_RESTRICTIONS;
+ static {
+ DEVICE_OWNER_USER_RESTRICTIONS = new HashSet();
+ DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_USB_FILE_TRANSFER);
+ DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_CONFIG_TETHERING);
+ DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_FACTORY_RESET);
+ DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_ADD_USER);
+ DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_CONFIG_CELL_BROADCASTS);
+ DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
+ DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA);
+ 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);
+ }
+
final Context mContext;
final UserManager mUserManager;
final PowerManager.WakeLock mWakeLock;
@@ -4046,7 +4060,12 @@
if (who == null) {
throw new NullPointerException("ComponentName is null");
}
- getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+ ActiveAdmin activeAdmin =
+ getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+ boolean isDeviceOwner = isDeviceOwner(activeAdmin.info.getPackageName());
+ if (!isDeviceOwner && DEVICE_OWNER_USER_RESTRICTIONS.contains(key)) {
+ throw new SecurityException("Profile owners cannot set user restriction " + key);
+ }
long id = Binder.clearCallingIdentity();
try {
diff --git a/telecomm/java/android/telecomm/Call.java b/telecomm/java/android/telecomm/Call.java
index d90ec13..63f85e9 100644
--- a/telecomm/java/android/telecomm/Call.java
+++ b/telecomm/java/android/telecomm/Call.java
@@ -16,6 +16,7 @@
package android.telecomm;
+import android.annotation.SystemApi;
import android.app.PendingIntent;
import android.net.Uri;
import android.os.Bundle;
@@ -34,6 +35,7 @@
*
* {@hide}
*/
+@SystemApi
public final class Call {
/**
* The state of a {@code Call} when newly created.
diff --git a/telecomm/java/android/telecomm/CallState.java b/telecomm/java/android/telecomm/CallState.java
index 73edbe2..0770e26 100644
--- a/telecomm/java/android/telecomm/CallState.java
+++ b/telecomm/java/android/telecomm/CallState.java
@@ -16,6 +16,8 @@
package android.telecomm;
+import android.annotation.SystemApi;
+
/**
* Defines call-state constants of the different states in which a call can exist. Although states
* have the notion of normal transitions, due to the volatile nature of telephony systems, code
@@ -24,6 +26,7 @@
*
* {@hide}
*/
+@SystemApi
public final class CallState {
private CallState() {}
diff --git a/telecomm/java/android/telecomm/Connection.java b/telecomm/java/android/telecomm/Connection.java
index c1d5715..c307a25 100644
--- a/telecomm/java/android/telecomm/Connection.java
+++ b/telecomm/java/android/telecomm/Connection.java
@@ -65,8 +65,6 @@
// Flag controlling whether PII is emitted into the logs
private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
- private static Connection sNullConnection;
-
/** @hide */
public abstract static class Listener {
public void onStateChanged(Connection c, int state) {}
@@ -476,9 +474,8 @@
private boolean mAudioModeIsVoip;
private StatusHints mStatusHints;
private int mVideoState;
- private int mFailureCode;
- private String mFailureMessage;
- private boolean mIsCanceled;
+ private int mDisconnectCause;
+ private String mDisconnectMessage;
private Conference mConference;
private ConnectionService mConnectionService;
@@ -604,17 +601,17 @@
}
/**
- * @return The failure code ({@see DisconnectCause}) associated with this failed connection.
+ * @return The {@link DisconnectCause} for this connection.
*/
- public final int getFailureCode() {
- return mFailureCode;
+ public final int getDisconnectCause() {
+ return mDisconnectCause;
}
/**
- * @return The reason for the connection failure. This will not be displayed to the user.
+ * @return The disconnect message for this connection.
*/
- public final String getFailureMessage() {
- return mFailureMessage;
+ public final String getDisconnectMessage() {
+ return mDisconnectMessage;
}
/**
@@ -778,6 +775,8 @@
* @param message Optional call-service-provided message about the disconnect.
*/
public final void setDisconnected(int cause, String message) {
+ mDisconnectCause = cause;
+ mDisconnectMessage = message;
setState(STATE_DISCONNECTED);
Log.d(this, "Disconnected with cause %d message %s", cause, message);
for (Listener l : mListeners) {
@@ -1060,13 +1059,6 @@
return builder.toString();
}
- static synchronized Connection getNullConnection() {
- if (sNullConnection == null) {
- sNullConnection = new Connection() {};
- }
- return sNullConnection;
- }
-
private void setState(int state) {
if (mState == STATE_DISCONNECTED && mState != state) {
Log.d(this, "Connection already DISCONNECTED; cannot transition out of this state.");
@@ -1082,31 +1074,29 @@
}
}
- static class FailureSignalingConnection extends Connection {
- public FailureSignalingConnection(int code, String message) {
- setDisconnected(code, message);
+ private static class FailureSignalingConnection extends Connection {
+ public FailureSignalingConnection(int cause, String message) {
+ setDisconnected(cause, message);
}
}
/**
* Return a {@code Connection} which represents a failed connection attempt. The returned
- * {@code Connection} will have a {@link #getFailureCode()} and {@link #getFailureMessage()}
- * as specified, a {@link #getState()} of {@link #STATE_DISCONNECTED}.
+ * {@code Connection} will have a {@link #getDisconnectCause()} and
+ * {@link #getDisconnectMessage()} as specified, and a {@link #getState()} of
+ * {@link #STATE_DISCONNECTED}.
* <p>
* The returned {@code Connection} can be assumed to {@link #destroy()} itself when appropriate,
* so users of this method need not maintain a reference to its return value to destroy it.
*
- * @param code The failure code ({@see DisconnectCause}).
+ * @param cause The disconnect cause, ({@see DisconnectCause}).
* @param message A reason for why the connection failed (not intended to be shown to the user).
* @return A {@code Connection} which indicates failure.
*/
- public static Connection createFailedConnection(final int code, final String message) {
- return new FailureSignalingConnection(code, message);
+ public static Connection createFailedConnection(int cause, String message) {
+ return new FailureSignalingConnection(cause, message);
}
- private static final Connection CANCELED_CONNECTION =
- new FailureSignalingConnection(DisconnectCause.OUTGOING_CANCELED, null);
-
/**
* Return a {@code Connection} which represents a canceled connection attempt. The returned
* {@code Connection} will have state {@link #STATE_DISCONNECTED}, and cannot be moved out of
@@ -1119,7 +1109,7 @@
* @return A {@code Connection} which indicates that the underlying call should be canceled.
*/
public static Connection createCanceledConnection() {
- return CANCELED_CONNECTION;
+ return new FailureSignalingConnection(DisconnectCause.OUTGOING_CANCELED, null);
}
private final void fireOnConferenceableConnectionsChanged() {
diff --git a/telecomm/java/android/telecomm/ConnectionService.java b/telecomm/java/android/telecomm/ConnectionService.java
index 03b6c7b..c805978 100644
--- a/telecomm/java/android/telecomm/ConnectionService.java
+++ b/telecomm/java/android/telecomm/ConnectionService.java
@@ -73,6 +73,8 @@
private static final int MSG_ON_PHONE_ACCOUNT_CLICKED = 15;
private static final int MSG_REMOVE_CONNECTION_SERVICE_ADAPTER = 16;
+ private static Connection sNullConnection;
+
private final Map<String, Connection> mConnectionById = new HashMap<>();
private final Map<Connection, String> mIdByConnection = new HashMap<>();
private final Map<String, Conference> mConferenceById = new HashMap<>();
@@ -498,36 +500,29 @@
final String callId,
final ConnectionRequest request,
boolean isIncoming) {
- Log.d(this, "call %s", request);
+ Log.d(this, "createConnection, callManagerAccount: %s, callId: %s, request: %s, " +
+ "isIncoming: %b", callManagerAccount, callId, request, isIncoming);
- Connection createdConnection = isIncoming
+ Connection connection = isIncoming
? onCreateIncomingConnection(callManagerAccount, request)
: onCreateOutgoingConnection(callManagerAccount, request);
-
- if (createdConnection == null) {
- Log.d(this, "adapter handleCreateConnectionComplete CANCELED %s", callId);
- // Tell telecomm to try a different service.
- createdConnection = Connection.createCanceledConnection();
+ Log.d(this, "createConnection, connection: %s", connection);
+ if (connection == null) {
+ connection = Connection.createFailedConnection(DisconnectCause.OUTGOING_FAILURE, null);
}
- connectionCreated(callId, request, createdConnection);
- }
- private void connectionCreated(
- String callId,
- ConnectionRequest request,
- Connection connection) {
- if (!(connection instanceof Connection.FailureSignalingConnection)) {
+ if (connection.getState() != Connection.STATE_DISCONNECTED) {
addConnection(callId, connection);
}
Uri handle = connection.getHandle();
String number = handle == null ? "null" : handle.getSchemeSpecificPart();
- Log.v(this, "connectionCreated, parcelableconnection: %s, %d, %s",
+ Log.v(this, "createConnection, number: %s, state: %s, capabilities: %s",
Connection.toLogSafePhoneNumber(number),
- connection.getState(),
+ Connection.stateToString(connection.getState()),
PhoneCapabilities.toString(connection.getCallCapabilities()));
- Log.d(this, "adapter handleCreateConnectionSuccessful %s", callId);
+ Log.d(this, "createConnection, calling handleCreateConnectionSuccessful %s", callId);
mAdapter.handleCreateConnectionComplete(
callId,
request,
@@ -545,8 +540,8 @@
connection.isRequestingRingback(),
connection.getAudioModeIsVoip(),
connection.getStatusHints(),
- connection.getFailureCode(),
- connection.getFailureMessage()));
+ connection.getDisconnectCause(),
+ connection.getDisconnectMessage()));
}
private void abort(String callId) {
@@ -598,13 +593,13 @@
Log.d(this, "conference %s, %s", callId1, callId2);
Connection connection1 = findConnectionForAction(callId1, "conference");
- if (connection1 == Connection.getNullConnection()) {
+ if (connection1 == getNullConnection()) {
Log.w(this, "Connection1 missing in conference request %s.", callId1);
return;
}
Connection connection2 = findConnectionForAction(callId2, "conference");
- if (connection2 == Connection.getNullConnection()) {
+ if (connection2 == getNullConnection()) {
Log.w(this, "Connection2 missing in conference request %s.", callId2);
return;
}
@@ -616,7 +611,7 @@
Log.d(this, "splitFromConference(%s)", callId);
Connection connection = findConnectionForAction(callId, "splitFromConference");
- if (connection == Connection.getNullConnection()) {
+ if (connection == getNullConnection()) {
Log.w(this, "Connection missing in conference request %s.", callId);
return;
}
@@ -881,6 +876,13 @@
return mConnectionById.get(callId);
}
Log.w(this, "%s - Cannot find Connection %s", action, callId);
- return Connection.getNullConnection();
+ return getNullConnection();
+ }
+
+ static synchronized Connection getNullConnection() {
+ if (sNullConnection == null) {
+ sNullConnection = new Connection() {};
+ }
+ return sNullConnection;
}
}
diff --git a/telecomm/java/android/telecomm/InCallService.java b/telecomm/java/android/telecomm/InCallService.java
index 5795e0e..794ec41 100644
--- a/telecomm/java/android/telecomm/InCallService.java
+++ b/telecomm/java/android/telecomm/InCallService.java
@@ -16,6 +16,7 @@
package android.telecomm;
+import android.annotation.SystemApi;
import android.annotation.SdkConstant;
import android.app.PendingIntent;
import android.app.Service;
@@ -39,6 +40,7 @@
*
* {@hide}
*/
+@SystemApi
public abstract class InCallService extends Service {
/**
diff --git a/telecomm/java/android/telecomm/ParcelableConnection.java b/telecomm/java/android/telecomm/ParcelableConnection.java
index 30ff5be..812ee55 100644
--- a/telecomm/java/android/telecomm/ParcelableConnection.java
+++ b/telecomm/java/android/telecomm/ParcelableConnection.java
@@ -41,8 +41,8 @@
private boolean mRequestingRingback;
private boolean mAudioModeIsVoip;
private StatusHints mStatusHints;
- private int mFailureCode;
- private String mFailureMessage;
+ private int mDisconnectCause;
+ private String mDisconnectMessage;
/** @hide */
public ParcelableConnection(
@@ -58,8 +58,8 @@
boolean requestingRingback,
boolean audioModeIsVoip,
StatusHints statusHints,
- int failureCode,
- String failureMessage) {
+ int disconnectCause,
+ String disconnectMessage) {
mPhoneAccount = phoneAccount;
mState = state;
mCapabilities = capabilities;
@@ -72,8 +72,8 @@
mRequestingRingback = requestingRingback;
mAudioModeIsVoip = audioModeIsVoip;
mStatusHints = statusHints;
- mFailureCode = failureCode;
- mFailureMessage = failureMessage;
+ mDisconnectCause = disconnectCause;
+ mDisconnectMessage = disconnectMessage;
}
public PhoneAccountHandle getPhoneAccount() {
@@ -125,12 +125,12 @@
return mStatusHints;
}
- public final int getFailureCode() {
- return mFailureCode;
+ public final int getDisconnectCause() {
+ return mDisconnectCause;
}
- public final String getFailureMessage() {
- return mFailureMessage;
+ public final String getDisconnectMessage() {
+ return mDisconnectMessage;
}
@Override
@@ -212,7 +212,7 @@
destination.writeByte((byte) (mRequestingRingback ? 1 : 0));
destination.writeByte((byte) (mAudioModeIsVoip ? 1 : 0));
destination.writeParcelable(mStatusHints, 0);
- destination.writeInt(mFailureCode);
- destination.writeString(mFailureMessage);
+ destination.writeInt(mDisconnectCause);
+ destination.writeString(mDisconnectMessage);
}
}
diff --git a/telecomm/java/android/telecomm/Phone.java b/telecomm/java/android/telecomm/Phone.java
index 03a8676..e125342 100644
--- a/telecomm/java/android/telecomm/Phone.java
+++ b/telecomm/java/android/telecomm/Phone.java
@@ -16,6 +16,7 @@
package android.telecomm;
+import android.annotation.SystemApi;
import android.app.PendingIntent;
import android.util.ArrayMap;
@@ -31,6 +32,7 @@
*
* {@hide}
*/
+@SystemApi
public final class Phone {
public abstract static class Listener {
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index a561dc2..a01a6b6 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -18,8 +18,8 @@
import android.net.wifi.passpoint.WifiPasspointInfo;
import android.net.wifi.passpoint.WifiPasspointManager;
-import android.os.Parcelable;
import android.os.Parcel;
+import android.os.Parcelable;
/**
* Describes information about a detected access point. In addition
@@ -48,7 +48,10 @@
*/
public String capabilities;
/**
- * The detected signal level in dBm.
+ * The detected signal level in dBm, also known as the RSSI.
+ *
+ * <p>Use {@link android.net.wifi.WifiManager#calculateSignalLevel} to convert this number into
+ * an absolute signal level which can be displayed to a user.
*/
public int level;
/**
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index e808136..44a7108 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -323,7 +323,11 @@
/**
* Returns the received signal strength indicator of the current 802.11
* network, in dBm.
- * @return the RSSI, in the range -127 to 200
+ *
+ * <p>Use {@link android.net.wifi.WifiManager#calculateSignalLevel} to convert this number into
+ * an absolute signal level which can be displayed to a user.
+ *
+ * @return the RSSI.
*/
public int getRssi() {
return mRssi;
diff --git a/wifi/java/android/net/wifi/passpoint/IWifiPasspointManager.aidl b/wifi/java/android/net/wifi/passpoint/IWifiPasspointManager.aidl
index 50bec33..54237c4 100644
--- a/wifi/java/android/net/wifi/passpoint/IWifiPasspointManager.aidl
+++ b/wifi/java/android/net/wifi/passpoint/IWifiPasspointManager.aidl
@@ -31,15 +31,5 @@
Messenger getMessenger();
int getPasspointState();
-
- List<WifiPasspointPolicy> requestCredentialMatch(in List<ScanResult> requested);
-
- List<WifiPasspointCredential> getCredentials();
-
- boolean addCredential(in WifiPasspointCredential cred);
-
- boolean updateCredential(in WifiPasspointCredential cred);
-
- boolean removeCredential(in WifiPasspointCredential cred);
}