summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/nfc/cardemulation/CardEmulation.java109
-rw-r--r--core/java/android/nfc/cardemulation/HostApduService.java141
-rw-r--r--core/java/android/nfc/cardemulation/OffHostApduService.java129
-rw-r--r--core/java/android/nfc/tech/NfcBarcode.java14
-rw-r--r--core/java/android/view/View.java30
-rw-r--r--core/res/res/values-mcc208-mnc01/config.xml39
-rw-r--r--core/res/res/values-mcc214-mnc03/config.xml39
-rw-r--r--core/res/res/values-mcc214-mnc07/config.xml39
-rw-r--r--core/res/res/values-mcc222-mnc01/config.xml38
-rw-r--r--core/res/res/values-mcc234-mnc33/config.xml16
-rw-r--r--core/res/res/values-mcc268-mnc03/config.xml (renamed from core/res/res/values-mcc454-mnc00/config.xml)4
-rw-r--r--core/res/res/values-mcc334-mnc050/config.xml (renamed from core/res/res/values-mcc454-mnc03/config.xml)2
-rw-r--r--core/res/res/values-mcc340-mnc01/config.xml2
-rw-r--r--core/res/res/values/config.xml3
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--packages/DocumentsUI/res/values-sw720dp/styles.xml1
-rw-r--r--packages/Keyguard/res/values-mcc262-mnc08/bools.xml21
-rw-r--r--packages/Keyguard/res/values-mcc262-mnc11/bools.xml21
-rw-r--r--packages/PrintSpooler/res/drawable-hdpi/ic_menu_print.pngbin0 -> 1133 bytes
-rw-r--r--packages/PrintSpooler/res/drawable-mdpi/ic_menu_print.pngbin0 -> 930 bytes
-rw-r--r--packages/PrintSpooler/res/drawable-xhdpi/ic_menu_print.pngbin0 -> 1387 bytes
-rw-r--r--packages/PrintSpooler/res/layout/print_job_config_activity_content_editing.xml2
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java19
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/SelectPrinterFragment.java1
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java11
-rw-r--r--packages/WallpaperCropper/src/com/android/photos/views/TiledImageView.java2
-rw-r--r--packages/WallpaperCropper/src/com/android/wallpapercropper/CropView.java107
-rw-r--r--packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java184
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindowManager.java23
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java16
-rw-r--r--telephony/java/android/telephony/CellSignalStrengthCdma.java21
-rw-r--r--telephony/java/android/telephony/CellSignalStrengthLte.java12
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java43
33 files changed, 712 insertions, 378 deletions
diff --git a/core/java/android/nfc/cardemulation/CardEmulation.java b/core/java/android/nfc/cardemulation/CardEmulation.java
index 3cd7863ff424..58d9616c72c4 100644
--- a/core/java/android/nfc/cardemulation/CardEmulation.java
+++ b/core/java/android/nfc/cardemulation/CardEmulation.java
@@ -33,6 +33,18 @@ import android.util.Log;
import java.util.HashMap;
import java.util.List;
+/**
+ * This class can be used to query the state of
+ * NFC card emulation services.
+ *
+ * For a general introduction into NFC card emulation,
+ * please read the <a href="{@docRoot}guide/topics/nfc/ce.html">
+ * NFC card emulation developer guide</a>.</p>
+ *
+ * <p class="note">Use of this class requires the
+ * {@link PackageManager#FEATURE_NFC_HOST_CARD_EMULATION} to be present
+ * on the device.
+ */
public final class CardEmulation {
static final String TAG = "CardEmulation";
@@ -50,32 +62,28 @@ public final class CardEmulation {
"android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT";
/**
- * The category extra for {@link #ACTION_CHANGE_DEFAULT}
+ * The category extra for {@link #ACTION_CHANGE_DEFAULT}.
*
* @see #ACTION_CHANGE_DEFAULT
*/
public static final String EXTRA_CATEGORY = "category";
/**
- * The ComponentName object passed in as a parcelable
- * extra for {@link #ACTION_CHANGE_DEFAULT}
+ * The service {@link ComponentName} object passed in as an
+ * extra for {@link #ACTION_CHANGE_DEFAULT}.
*
* @see #ACTION_CHANGE_DEFAULT
*/
public static final String EXTRA_SERVICE_COMPONENT = "component";
/**
- * The payment category can be used to indicate that an AID
- * represents a payment application.
+ * Category used for NFC payment services.
*/
public static final String CATEGORY_PAYMENT = "payment";
/**
- * If an AID group does not contain a category, or the
- * specified category is not defined by the platform version
- * that is parsing the AID group, all AIDs in the group will
- * automatically be categorized under the {@link #CATEGORY_OTHER}
- * category.
+ * Category that can be used for all other card emulation
+ * services.
*/
public static final String CATEGORY_OTHER = "other";
@@ -83,49 +91,23 @@ public final class CardEmulation {
* Return value for {@link #getSelectionModeForCategory(String)}.
*
* <p>In this mode, the user has set a default service for this
- * AID category. If a remote reader selects any of the AIDs
+ * category.
+ *
+ * <p>When using ISO-DEP card emulation with {@link HostApduService}
+ * or {@link OffHostApduService}, if a remote NFC device selects
+ * any of the Application IDs (AIDs)
* that the default service has registered in this category,
* that service will automatically be bound to to handle
* the transaction.
- *
- * <p>There are still cases where a service that is
- * not the default for a category can selected:
- * <p>
- * If a remote reader selects an AID in this category
- * that is not handled by the default service, and there is a set
- * of other services {S} that do handle this AID, the
- * user is asked if he wants to use any of the services in
- * {S} instead.
- * <p>
- * As a special case, if the size of {S} is one, containing a single service X,
- * and all AIDs X has registered in this category are not
- * registered by any other service, then X will be
- * selected automatically without asking the user.
- * <p>Example:
- * <ul>
- * <li>Service A registers AIDs "1", "2" and "3" in the category
- * <li>Service B registers AIDs "3" and "4" in the category
- * <li>Service C registers AIDs "5" and "6" in the category
- * </ul>
- * In this case, the following will happen when service A
- * is the default:
- * <ul>
- * <li>Reader selects AID "1", "2" or "3": service A is invoked automatically
- * <li>Reader selects AID "4": the user is asked to confirm he
- * wants to use service B, because its AIDs overlap with service A.
- * <li>Reader selects AID "5" or "6": service C is invoked automatically,
- * because all AIDs it has asked for are only registered by C,
- * and there is no overlap.
- * </ul>
- *
*/
public static final int SELECTION_MODE_PREFER_DEFAULT = 0;
/**
* Return value for {@link #getSelectionModeForCategory(String)}.
*
- * <p>In this mode, whenever an AID of this category is selected,
- * the user is asked which service he wants to use to handle
+ * <p>In this mode, when using ISO-DEP card emulation with {@link HostApduService}
+ * or {@link OffHostApduService}, whenever an Application ID (AID) of this category
+ * is selected, the user is asked which service he wants to use to handle
* the transaction, even if there is only one matching service.
*/
public static final int SELECTION_MODE_ALWAYS_ASK = 1;
@@ -133,13 +115,16 @@ public final class CardEmulation {
/**
* Return value for {@link #getSelectionModeForCategory(String)}.
*
- * <p>In this mode, the user will only be asked to select a service
- * if the selected AID has been registered by multiple applications.
+ * <p>In this mode, when using ISO-DEP card emulation with {@link HostApduService}
+ * or {@link OffHostApduService}, the user will only be asked to select a service
+ * if the Application ID (AID) selected by the reader has been registered by multiple
+ * services. If there is only one service that has registered for the AID,
+ * that service will be invoked directly.
*/
public static final int SELECTION_MODE_ASK_IF_CONFLICT = 2;
static boolean sIsInitialized = false;
- static HashMap<Context, CardEmulation> sCardEmus = new HashMap();
+ static HashMap<Context, CardEmulation> sCardEmus = new HashMap<Context, CardEmulation>();
static INfcCardEmulation sService;
final Context mContext;
@@ -149,6 +134,12 @@ public final class CardEmulation {
sService = service;
}
+ /**
+ * Helper to get an instance of this class.
+ *
+ * @param adapter A reference to an NfcAdapter object.
+ * @return
+ */
public static synchronized CardEmulation getInstance(NfcAdapter adapter) {
if (adapter == null) throw new NullPointerException("NfcAdapter is null");
Context context = adapter.getContext();
@@ -188,12 +179,19 @@ public final class CardEmulation {
* the default service to handle a card emulation category.
*
* <p>Note that if {@link #getSelectionModeForCategory(String)}
- * returns {@link #SELECTION_MODE_ALWAYS_ASK}, this method will always
- * return false.
+ * returns {@link #SELECTION_MODE_ALWAYS_ASK} or {@link #SELECTION_MODE_ASK_IF_CONFLICT},
+ * this method will always return false. That is because in these
+ * selection modes a default can't be set at the category level. For categories where
+ * the selection mode is {@link #SELECTION_MODE_ALWAYS_ASK} or
+ * {@link #SELECTION_MODE_ASK_IF_CONFLICT}, use
+ * {@link #isDefaultServiceForAid(ComponentName, String)} to determine whether a service
+ * is the default for a specific AID.
*
* @param service The ComponentName of the service
* @param category The category
* @return whether service is currently the default service for the category.
+ *
+ * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
*/
public boolean isDefaultServiceForCategory(ComponentName service, String category) {
try {
@@ -222,7 +220,9 @@ public final class CardEmulation {
*
* @param service The ComponentName of the service
* @param aid The ISO7816-4 Application ID
- * @return
+ * @return whether the service is the default handler for the specified AID
+ *
+ * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
*/
public boolean isDefaultServiceForAid(ComponentName service, String aid) {
try {
@@ -244,16 +244,16 @@ public final class CardEmulation {
}
/**
- * Returns the application selection mode for the passed in category.
+ * Returns the service selection mode for the passed in category.
* Valid return values are:
* <p>{@link #SELECTION_MODE_PREFER_DEFAULT} the user has requested a default
- * application for this category, which will be preferred.
+ * service for this category, which will be preferred.
* <p>{@link #SELECTION_MODE_ALWAYS_ASK} the user has requested to be asked
- * every time what app he would like to use in this category.
+ * every time what service he would like to use in this category.
* <p>{@link #SELECTION_MODE_ASK_IF_CONFLICT} the user will only be asked
* to pick a service if there is a conflict.
* @param category The category, for example {@link #CATEGORY_PAYMENT}
- * @return
+ * @return the selection mode for the passed in category
*/
public int getSelectionModeForCategory(String category) {
if (CATEGORY_PAYMENT.equals(category)) {
@@ -314,6 +314,7 @@ public final class CardEmulation {
}
}
}
+
/**
* @hide
*/
diff --git a/core/java/android/nfc/cardemulation/HostApduService.java b/core/java/android/nfc/cardemulation/HostApduService.java
index e2c3ca6c5735..ad34e61db910 100644
--- a/core/java/android/nfc/cardemulation/HostApduService.java
+++ b/core/java/android/nfc/cardemulation/HostApduService.java
@@ -4,6 +4,7 @@ import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.app.Service;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -13,30 +14,136 @@ import android.os.RemoteException;
import android.util.Log;
/**
- * <p>A convenience class that can be extended to implement
- * a service that processes ISO7816-4 commands on top of
- * the ISO14443-4 / IsoDep protocol (T=CL).
+ * <p>HostApduService is a convenience {@link Service} class that can be
+ * extended to emulate an NFC card inside an Android
+ * service component.
*
- * <p>To tell the platform which ISO7816 application ID (AIDs)
- * are implemented by this service, a {@link #SERVICE_META_DATA}
+ * <div class="special reference">
+ * <h3>Developer Guide</h3>
+ * For a general introduction into the topic of card emulation,
+ * please read the <a href="{@docRoot}guide/topics/nfc/ce.html">
+ * NFC card emulation developer guide.</a></p>
+ * </div>
+ *
+ * <h3>NFC Protocols</h3>
+ * <p>Cards emulated by this class are based on the NFC-Forum ISO-DEP
+ * protocol (based on ISO/IEC 14443-4) and support processing
+ * command Application Protocol Data Units (APDUs) as
+ * defined in the ISO/IEC 7816-4 specification.
+ *
+ * <h3>Service selection</h3>
+ * <p>When a remote NFC device wants to talk to your
+ * service, it sends a so-called
+ * "SELECT AID" APDU as defined in the ISO/IEC 7816-4 specification.
+ * The AID is an application identifier defined in ISO/IEC 7816-4.
+ *
+ * <p>The registration procedure for AIDs is defined in the
+ * ISO/IEC 7816-5 specification. If you don't want to register an
+ * AID, you are free to use AIDs in the proprietary range:
+ * bits 8-5 of the first byte must each be set to '1'. For example,
+ * "0xF00102030405" is a proprietary AID. If you do use proprietary
+ * AIDs, it is recommended to choose an AID of at least 6 bytes,
+ * to reduce the risk of collisions with other applications that
+ * might be using proprietary AIDs as well.
+ *
+ * <h3>AID groups</h3>
+ * <p>In some cases, a service may need to register multiple AIDs
+ * to implement a certain application, and it needs to be sure
+ * that it is the default handler for all of these AIDs (as opposed
+ * to some AIDs in the group going to another service).
+ *
+ * <p>An AID group is a list of AIDs that should be considered as
+ * belonging together by the OS. For all AIDs in an AID group, the
+ * OS will guarantee one of the following:
+ * <ul>
+ * <li>All AIDs in the group are routed to this service
+ * <li>No AIDs in the group are routed to this service
+ * </ul>
+ * In other words, there is no in-between state, where some AIDs
+ * in the group can be routed to this service, and some to another.
+ * <h3>AID groups and categories</h3>
+ * <p>Each AID group can be associated with a category. This allows
+ * the Android OS to classify services, and it allows the user to
+ * set defaults at the category level instead of the AID level.
+ *
+ * <p>You can use
+ * {@link CardEmulation#isDefaultServiceForCategory(android.content.ComponentName, String)}
+ * to determine if your service is the default handler for a category.
+ *
+ * <p>In this version of the platform, the only known categories
+ * are {@link CardEmulation#CATEGORY_PAYMENT} and {@link CardEmulation#CATEGORY_OTHER}.
+ * AID groups without a category, or with a category that is not recognized
+ * by the current platform version, will automatically be
+ * grouped into the {@link CardEmulation#CATEGORY_OTHER} category.
+ * <h3>Service AID registration</h3>
+ * <p>To tell the platform which AIDs groups
+ * are requested by this service, a {@link #SERVICE_META_DATA}
* entry must be included in the declaration of the service. An
- * example of such a service declaration is shown below:
- * <pre> &lt;service android:name=".MyHostApduService"&gt;
+ * example of a HostApduService manifest declaration is shown below:
+ * <pre> &lt;service android:name=".MyHostApduService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE"&gt;
* &lt;intent-filter&gt;
- * &lt;action android:name="android.nfc.HostApduService"/&gt;
+ * &lt;action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/&gt;
* &lt;/intent-filter&gt;
- * &lt;meta-data android:name="android.nfc.HostApduService" android:resource="@xml/apduservice.xml"/&gt;
+ * &lt;meta-data android:name="android.nfc.cardemulation.host_apdu_ervice" android:resource="@xml/apduservice"/&gt;
* &lt;/service&gt;</pre>
- * <p>For more details refer to {@link #SERVICE_META_DATA},
- * <code>&lt;{@link android.R.styleable#HostApduService host-apdu-service}&gt;</code>,
- * <code>&lt;{@link android.R.styleable#AidGroup aid-group}&gt;</code> and
- * <code>&lt;{@link android.R.styleable#AidFilter aid-filter}&gt;</code>.
- * <p class="note">The Android platform currently only supports a single
- * logical channel.
+ *
+ * This meta-data tag points to an apduservice.xml file.
+ * An example of this file with a single AID group declaration is shown below:
+ * <pre>
+ * &lt;host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
+ * android:description="@string/servicedesc" android:requireDeviceUnlock="false"&gt;
+ * &lt;aid-group android:description="@string/aiddescription" android:category="other">
+ * &lt;aid-filter android:name="F0010203040506"/&gt;
+ * &lt;aid-filter android:name="F0394148148100"/&gt;
+ * &lt;/aid-group&gt;
+ * &lt;/host-apdu-service&gt;
+ * </pre>
+ *
+ * <p>The {@link android.R.styleable#HostApduService &lt;host-apdu-service&gt;} is required
+ * to contain a
+ * {@link android.R.styleable#HostApduService_description &lt;android:description&gt;}
+ * attribute that contains a user-friendly description of the service that may be shown in UI.
+ * The
+ * {@link android.R.styleable#HostApduService_requireDeviceUnlock &lt;requireDeviceUnlock&gt;}
+ * attribute can be used to specify that the device must be unlocked before this service
+ * can be invoked to handle APDUs.
+ * <p>The {@link android.R.styleable#HostApduService &lt;host-apdu-service&gt;} must
+ * contain one or more {@link android.R.styleable#AidGroup &lt;aid-group&gt;} tags.
+ * Each {@link android.R.styleable#AidGroup &lt;aid-group&gt;} must contain one or
+ * more {@link android.R.styleable#AidFilter &lt;aid-filter&gt;} tags, each of which
+ * contains a single AID. The AID must be specified in hexadecimal format, and contain
+ * an even number of characters.
+ * <h3>AID conflict resolution</h3>
+ * Multiple HostApduServices may be installed on a single device, and the same AID
+ * can be registered by more than one service. The Android platform resolves AID
+ * conflicts depending on which category an AID belongs to. Each category may
+ * have a different conflict resolution policy. For example, for some categories
+ * the user may be able to select a default service in the Android settings UI.
+ * For other categories, to policy may be to always ask the user which service
+ * is to be invoked in case of conflict.
+ *
+ * To query the conflict resolution policy for a certain category, see
+ * {@link CardEmulation#getSelectionModeForCategory(String)}.
+ *
+ * <h3>Data exchange</h3>
+ * <p>Once the platform has resolved a "SELECT AID" command APDU to a specific
+ * service component, the "SELECT AID" command APDU and all subsequent
+ * command APDUs will be sent to that service through
+ * {@link #processCommandApdu(byte[], Bundle)}, until either:
+ * <ul>
+ * <li>The NFC link is broken</li>
+ * <li>A "SELECT AID" APDU is received which resolves to another service</li>
+ * </ul>
+ * These two scenarios are indicated by a call to {@link #onDeactivated(int)}.
+ *
+ * <p class="note">Use of this class requires the
+ * {@link PackageManager#FEATURE_NFC_HOST_CARD_EMULATION} to be present
+ * on the device.
+ *
*/
public abstract class HostApduService extends Service {
/**
- * The {@link Intent} that must be declared as handled by the service.
+ * The {@link Intent} action that must be declared as handled by the service.
*/
@SdkConstant(SdkConstantType.SERVICE_ACTION)
public static final String SERVICE_INTERFACE =
@@ -260,7 +367,7 @@ public abstract class HostApduService extends Service {
* If you cannot return a response APDU immediately, return null
* and use the {@link #sendResponseApdu(byte[])} method later.
*
- * @param commandApdu The APDU that received from the remote device
+ * @param commandApdu The APDU that was received from the remote device
* @param extras A bundle containing extra data. May be null.
* @return a byte-array containing the response APDU, or null if no
* response APDU can be sent at this point.
diff --git a/core/java/android/nfc/cardemulation/OffHostApduService.java b/core/java/android/nfc/cardemulation/OffHostApduService.java
index 15f63f9fed53..0d01762ae8e2 100644
--- a/core/java/android/nfc/cardemulation/OffHostApduService.java
+++ b/core/java/android/nfc/cardemulation/OffHostApduService.java
@@ -4,41 +4,126 @@ import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.app.Service;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.os.IBinder;
/**
- * <p>A convenience class that can be extended to implement
- * a service that registers ISO7814-4 AIDs that reside off-host,
- * for example on an embedded secure element or UICC.
+ * <p>OffHostApduService is a convenience {@link Service} class that can be
+ * extended to describe one or more NFC applications that are residing
+ * off-host, for example on an embedded secure element or a UICC.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guide</h3>
+ * For a general introduction into the topic of card emulation,
+ * please read the <a href="{@docRoot}guide/topics/nfc/ce.html">
+ * NFC card emulation developer guide.</a></p>
+ * </div>
+ *
+ * <h3>NFC Protocols</h3>
+ * <p>Off-host applications represented by this class are based on the NFC-Forum ISO-DEP
+ * protocol (based on ISO/IEC 14443-4) and support processing
+ * command Application Protocol Data Units (APDUs) as
+ * defined in the ISO/IEC 7816-4 specification.
+ *
+ * <h3>Service selection</h3>
+ * <p>When a remote NFC device wants to talk to your
+ * off-host NFC application, it sends a so-called
+ * "SELECT AID" APDU as defined in the ISO/IEC 7816-4 specification.
+ * The AID is an application identifier defined in ISO/IEC 7816-4.
+ *
+ * <p>The registration procedure for AIDs is defined in the
+ * ISO/IEC 7816-5 specification. If you don't want to register an
+ * AID, you are free to use AIDs in the proprietary range:
+ * bits 8-5 of the first byte must each be set to '1'. For example,
+ * "0xF00102030405" is a proprietary AID. If you do use proprietary
+ * AIDs, it is recommended to choose an AID of at least 6 bytes,
+ * to reduce the risk of collisions with other applications that
+ * might be using proprietary AIDs as well.
+ *
+ * <h3>AID groups</h3>
+ * <p>In some cases, an off-host environment may need to register multiple AIDs
+ * to implement a certain application, and it needs to be sure
+ * that it is the default handler for all of these AIDs (as opposed
+ * to some AIDs in the group going to another service).
+ *
+ * <p>An AID group is a list of AIDs that should be considered as
+ * belonging together by the OS. For all AIDs in an AID group, the
+ * OS will guarantee one of the following:
+ * <ul>
+ * <li>All AIDs in the group are routed to the off-host execution environment
+ * <li>No AIDs in the group are routed to the off-host execution environment
+ * </ul>
+ * In other words, there is no in-between state, where some AIDs
+ * in the group can be routed to this off-host execution environment,
+ * and some to another or a host-based {@link HostApduService}.
+ * <h3>AID groups and categories</h3>
+ * <p>Each AID group can be associated with a category. This allows
+ * the Android OS to classify services, and it allows the user to
+ * set defaults at the category level instead of the AID level.
+ *
+ * <p>You can use
+ * {@link CardEmulation#isDefaultServiceForCategory(android.content.ComponentName, String)}
+ * to determine if your off-host service is the default handler for a category.
+ *
+ * <p>In this version of the platform, the only known categories
+ * are {@link CardEmulation#CATEGORY_PAYMENT} and {@link CardEmulation#CATEGORY_OTHER}.
+ * AID groups without a category, or with a category that is not recognized
+ * by the current platform version, will automatically be
+ * grouped into the {@link CardEmulation#CATEGORY_OTHER} category.
+ *
+ * <h3>Service AID registration</h3>
+ * <p>To tell the platform which AIDs
+ * reside off-host and are managed by this service, a {@link #SERVICE_META_DATA}
+ * entry must be included in the declaration of the service. An
+ * example of a OffHostApduService manifest declaration is shown below:
+ * <pre> &lt;service android:name=".MyOffHostApduService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE"&gt;
+ * &lt;intent-filter&gt;
+ * &lt;action android:name="android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE"/&gt;
+ * &lt;/intent-filter&gt;
+ * &lt;meta-data android:name="android.nfc.cardemulation.off_host_apdu_ervice" android:resource="@xml/apduservice"/&gt;
+ * &lt;/service&gt;</pre>
+ *
+ * This meta-data tag points to an apduservice.xml file.
+ * An example of this file with a single AID group declaration is shown below:
+ * <pre>
+ * &lt;offhost-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
+ * android:description="@string/servicedesc"&gt;
+ * &lt;aid-group android:description="@string/subscription" android:category="other">
+ * &lt;aid-filter android:name="F0010203040506"/&gt;
+ * &lt;aid-filter android:name="F0394148148100"/&gt;
+ * &lt;/aid-group&gt;
+ * &lt;/offhost-apdu-service&gt;
+ * </pre>
+ *
+ * <p>The {@link android.R.styleable#OffHostApduService &lt;offhost-apdu-service&gt;} is required
+ * to contain a
+ * {@link android.R.styleable#OffHostApduService_description &lt;android:description&gt;}
+ * attribute that contains a user-friendly description of the service that may be shown in UI.
+ *
+ * <p>The {@link android.R.styleable#OffHostApduService &lt;offhost-apdu-service&gt;} must
+ * contain one or more {@link android.R.styleable#AidGroup &lt;aid-group&gt;} tags.
+ * Each {@link android.R.styleable#AidGroup &lt;aid-group&gt;} must contain one or
+ * more {@link android.R.styleable#AidFilter &lt;aid-filter&gt;} tags, each of which
+ * contains a single AID. The AID must be specified in hexadecimal format, and contain
+ * an even number of characters.
*
* <p>This registration will allow the service to be included
- * as an option for handling these AIDs on non-host execution
- * environments. The Operating System will take care of correctly
- * routing the AIDs, based on which service the user has selected
- * to be the handler for an AID.
+ * as an option for being the default handler for categories.
+ * The Android OS will take care of correctly
+ * routing the AIDs to the off-host execution environment,
+ * based on which service the user has selected to be the handler for a certain category.
*
* <p>The service may define additional actions outside of the
* Android namespace that provide further interaction with
* the off-host execution environment.
*
- * <p>To tell the platform which ISO7816 application ID (AIDs)
- * are present and handled by the app containing this service,
- * a {@link #SERVICE_META_DATA} entry must be included in the declaration
- * of the service. An example of such a service declaration is shown below:
- * <pre> &lt;service android:name=".MyOffHostApduService"&gt;
- * &lt;intent-filter&gt;
- * &lt;action android:name="android.nfc.OffHostApduService"/&gt;
- * &lt;/intent-filter&gt;
- * &lt;meta-data android:name="android.nfc.OffHostApduService" android:resource="@xml/apduservice.xml"/&gt;
- * &lt;/service&gt;</pre>
- * <p>For more details refer to {@link #SERVICE_META_DATA},
- * <code>&lt;{@link android.R.styleable#OffHostApduService offhost-apdu-service}&gt;</code>,
- * <code>&lt;{@link android.R.styleable#AidGroup aid-group}&gt;</code> and
- * <code>&lt;{@link android.R.styleable#AidFilter aid-filter}&gt;</code>.
+ * <p class="note">Use of this class requires the
+ * {@link PackageManager#FEATURE_NFC_HOST_CARD_EMULATION} to be present
+ * on the device.
*/
public abstract class OffHostApduService extends Service {
/**
- * The {@link Intent} that must be declared as handled by the service.
+ * The {@link Intent} action that must be declared as handled by the service.
*/
@SdkConstant(SdkConstantType.SERVICE_ACTION)
public static final String SERVICE_INTERFACE =
diff --git a/core/java/android/nfc/tech/NfcBarcode.java b/core/java/android/nfc/tech/NfcBarcode.java
index 76627deb4e10..8901f287c47a 100644
--- a/core/java/android/nfc/tech/NfcBarcode.java
+++ b/core/java/android/nfc/tech/NfcBarcode.java
@@ -102,15 +102,21 @@ public final class NfcBarcode extends BasicTagTechnology {
* </ul>
* <p>The following 12 bytes are payload:<ul>
* <li> In case of a URL payload, the payload is encoded in US-ASCII,
- * following the limitations defined in RF3987,
- * {@see http://www.ietf.org/rfc/rfc3987.txt}</li>
- * <li> In case of GS1 EPC daya, {@see http://www.gs1.org/gsmp/kc/epcglobal/tds/}
- * for more details.</li></ul>
+ * following the limitations defined in RFC3987.
+ * {@see <a href="http://www.ietf.org/rfc/rfc3987.txt">RFC 3987</a>}</li>
+ * <li> In case of GS1 EPC data, see <a href="http://www.gs1.org/gsmp/kc/epcglobal/tds/">
+ * GS1 Electronic Product Code (EPC) Tag Data Standard (TDS)</a> for more details.
+ * </li>
+ * </ul>
* <p>The last 2 bytes comprise the CRC.
* </ul>
* <p>Does not cause any RF activity and does not block.
*
* @return a byte array containing the barcode
+ * @see <a href="http://www.kovio.com/docs/kovionfcbarcode.pdf">
+ * Kovio 128-bit NFC barcode datasheet</a>
+ * @see <a href="http://kovio.com/docs/kovio-128-nfc-barcode-data-format.pdf">
+ * Kovio 128-bit NFC barcode data format</a>
*/
public byte[] getBarcode() {
switch (mType) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 9c388ddeaafe..e2d98edafc49 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -18,6 +18,7 @@ package android.view;
import android.content.ClipData;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -691,9 +692,23 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public static final int NO_ID = -1;
+ /**
+ * Signals that compatibility booleans have been initialized according to
+ * target SDK versions.
+ */
+ private static boolean sCompatibilityDone = false;
+
+ /**
+ * Use the old (broken) way of building MeasureSpecs.
+ */
private static boolean sUseBrokenMakeMeasureSpec = false;
/**
+ * Ignore any optimizations using the measure cache.
+ */
+ private static boolean sIgnoreMeasureCache = false;
+
+ /**
* This view does not want keystrokes. Use with TAKES_FOCUS_MASK when
* calling setFlags.
*/
@@ -3426,10 +3441,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mUserPaddingStart = UNDEFINED_PADDING;
mUserPaddingEnd = UNDEFINED_PADDING;
- if (!sUseBrokenMakeMeasureSpec && context != null &&
- context.getApplicationInfo().targetSdkVersion <= JELLY_BEAN_MR1) {
+ if (!sCompatibilityDone && context != null) {
+ final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
+
// Older apps may need this compatibility hack for measurement.
- sUseBrokenMakeMeasureSpec = true;
+ sUseBrokenMakeMeasureSpec = targetSdkVersion <= JELLY_BEAN_MR1;
+
+ // Older apps expect onMeasure() to always be called on a layout pass, regardless
+ // of whether a layout was requested on that View.
+ sIgnoreMeasureCache = targetSdkVersion < KITKAT;
+
+ sCompatibilityDone = true;
}
}
@@ -16431,7 +16453,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
int cacheIndex = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT ? -1 :
mMeasureCache.indexOfKey(key);
- if (cacheIndex < 0) {
+ if (cacheIndex < 0 || sIgnoreMeasureCache) {
// measure ourselves, this should set the measured dimension flag back
onMeasure(widthMeasureSpec, heightMeasureSpec);
mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
diff --git a/core/res/res/values-mcc208-mnc01/config.xml b/core/res/res/values-mcc208-mnc01/config.xml
deleted file mode 100644
index 3b84ff231e68..000000000000
--- a/core/res/res/values-mcc208-mnc01/config.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2009, 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.
-*/
--->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. Do not translate. -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
- <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
- <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
- <integer-array translatable="false" name="config_tether_upstream_types">
- <item>1</item>
- <item>4</item>
- <item>7</item>
- <item>9</item>
- </integer-array>
-
- <!-- String containing the apn value for tethering. May be overriden by secure settings
- TETHER_DUN_APN. Value is a comma separated series of strings:
- "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
- note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
- <string translatable="false" name="config_tether_apndata">Orange Internet,orange.fr,,,orange,orange,,,,,208,01,1,DUN</string>
-
-</resources>
diff --git a/core/res/res/values-mcc214-mnc03/config.xml b/core/res/res/values-mcc214-mnc03/config.xml
deleted file mode 100644
index 4a51a2ffd03e..000000000000
--- a/core/res/res/values-mcc214-mnc03/config.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2009, 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.
-*/
--->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. Do not translate. -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
- <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
- <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
- <integer-array translatable="false" name="config_tether_upstream_types">
- <item>1</item>
- <item>4</item>
- <item>7</item>
- <item>9</item>
- </integer-array>
-
- <!-- String containing the apn value for tethering. May be overriden by secure settings
- TETHER_DUN_APN. Value is a comma separated series of strings:
- "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
- note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
- <string translatable="false" name="config_tether_apndata">Orange Internet PC,internet,,,orange,orange,,,,,214,03,1,DUN</string>
-
-</resources>
diff --git a/core/res/res/values-mcc214-mnc07/config.xml b/core/res/res/values-mcc214-mnc07/config.xml
deleted file mode 100644
index b49ad74c36c6..000000000000
--- a/core/res/res/values-mcc214-mnc07/config.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2009, 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.
-*/
--->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. Do not translate. -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
- <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
- <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
- <integer-array translatable="false" name="config_tether_upstream_types">
- <item>1</item>
- <item>4</item>
- <item>7</item>
- <item>9</item>
- </integer-array>
-
- <!-- String containing the apn value for tethering. May be overriden by secure settings
- TETHER_DUN_APN. Value is a comma separated series of strings:
- "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
- note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
- <string translatable="false" name="config_tether_apndata">Conexión Compartida,movistar.es,,,MOVISTAR,MOVISTAR,,,,,214,07,1,DUN</string>
-
-</resources>
diff --git a/core/res/res/values-mcc222-mnc01/config.xml b/core/res/res/values-mcc222-mnc01/config.xml
deleted file mode 100644
index 6bb1196b5775..000000000000
--- a/core/res/res/values-mcc222-mnc01/config.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2009, 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.
-*/
--->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. Do not translate. -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
- <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
- <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
- <integer-array translatable="false" name="config_tether_upstream_types">
- <item>1</item>
- <item>4</item>
- <item>7</item>
- <item>9</item>
- </integer-array>
-
- <!-- String containing the apn value for tethering. May be overriden by secure settings
- TETHER_DUN_APN. Value is a comma separated series of strings:
- "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
- note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
- <string translatable="false" name="config_tether_apndata">TIM WEB,ibox.tim.it,,,,,,,,,222,01,,DUN</string>
-</resources>
diff --git a/core/res/res/values-mcc234-mnc33/config.xml b/core/res/res/values-mcc234-mnc33/config.xml
index 175f76e0473a..776b5702a0d0 100644
--- a/core/res/res/values-mcc234-mnc33/config.xml
+++ b/core/res/res/values-mcc234-mnc33/config.xml
@@ -20,22 +20,6 @@
<!-- These resources are around just to allow their values to be customized
for different hardware and product builds. Do not translate. -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
- <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
- <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
- <integer-array translatable="false" name="config_tether_upstream_types">
- <item>1</item>
- <item>4</item>
- <item>7</item>
- <item>9</item>
- </integer-array>
-
- <!-- String containing the apn value for tethering. May be overriden by secure settings
- TETHER_DUN_APN. Value is a comma separated series of strings:
- "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
- note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
- <string translatable="false" name="config_tether_apndata">Consumer Broadband,consumerbroadband,,,,,,,,,234,33,,DUN</string>
-
<!-- Don't use roaming icon for considered operators -->
<string-array translatable="false" name="config_operatorConsideredNonRoaming">
<item>23430</item>
diff --git a/core/res/res/values-mcc454-mnc00/config.xml b/core/res/res/values-mcc268-mnc03/config.xml
index c92b9c71da2b..0d5fe5717d2d 100644
--- a/core/res/res/values-mcc454-mnc00/config.xml
+++ b/core/res/res/values-mcc268-mnc03/config.xml
@@ -34,7 +34,7 @@
<!-- String containing the apn value for tethering. May be overriden by secure settings
TETHER_DUN_APN. Value is a comma separated series of strings:
"name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
- note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
- <string translatable="false" name="config_tether_apndata">1O1O tethering,lte.internet,,,,,,,,,454,00,3,DUN</string>
+ note that empty fields can be ommitted: "name,apn,,,,,,,,,310,270,,DUN" -->
+ <string translatable="false" name="config_tether_apndata">Optimus HotSpot,modem,,,,,,,,,268,03,,DUN</string>
</resources>
diff --git a/core/res/res/values-mcc454-mnc03/config.xml b/core/res/res/values-mcc334-mnc050/config.xml
index c7dc960ae854..00c415551f8b 100644
--- a/core/res/res/values-mcc454-mnc03/config.xml
+++ b/core/res/res/values-mcc334-mnc050/config.xml
@@ -35,6 +35,6 @@
TETHER_DUN_APN. Value is a comma separated series of strings:
"name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
- <string translatable="false" name="config_tether_apndata">3 Share,share.lte.three.com.hk,,,,,,,,,454,03,1,DUN</string>
+ <string translatable="false" name="config_tether_apndata">Modem,modem.iusacellgsm.mx,,,iusacellgsm,iusacellgsm,,,,,334,050,1,DUN</string>
</resources>
diff --git a/core/res/res/values-mcc340-mnc01/config.xml b/core/res/res/values-mcc340-mnc01/config.xml
index fb71f3bc894b..bbab4ad35bfa 100644
--- a/core/res/res/values-mcc340-mnc01/config.xml
+++ b/core/res/res/values-mcc340-mnc01/config.xml
@@ -34,5 +34,5 @@
TETHER_DUN_APN. Value is a comma separated series of strings:
"name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
- <string translatable="false" name="config_tether_apndata">Orangeweb,orangeweb,,,,,,orange,orange,,340,01,1,DUN</string>
+ <string translatable="false" name="config_tether_apndata">Orangeweb,orangeweb,,,orange,orange,,,,,340,01,1,DUN</string>
</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 196be743da15..42ea384bcdbb 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -588,6 +588,9 @@
<!-- Disable lockscreen translucent decor by default -->
<bool name="config_enableLockScreenTranslucentDecor">false</bool>
+ <!-- Enable translucent decor by default -->
+ <bool name="config_enableTranslucentDecor">true</bool>
+
<!-- Enable puk unlockscreen by default.
If unlock screen is disabled, the puk should be unlocked through Emergency Dialer -->
<bool name="config_enable_puk_unlock_screen">true</bool>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 0b050c76af88..611c08558008 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1295,6 +1295,7 @@
<java-symbol type="bool" name="config_enableLockBeforeUnlockScreen" />
<java-symbol type="bool" name="config_enableLockScreenRotation" />
<java-symbol type="bool" name="config_enableLockScreenTranslucentDecor" />
+ <java-symbol type="bool" name="config_enableTranslucentDecor" />
<java-symbol type="bool" name="config_lidControlsSleep" />
<java-symbol type="bool" name="config_reverseDefaultRotation" />
<java-symbol type="bool" name="config_showNavigationBar" />
diff --git a/packages/DocumentsUI/res/values-sw720dp/styles.xml b/packages/DocumentsUI/res/values-sw720dp/styles.xml
index a581e08bad41..19d2ebebaa97 100644
--- a/packages/DocumentsUI/res/values-sw720dp/styles.xml
+++ b/packages/DocumentsUI/res/values-sw720dp/styles.xml
@@ -20,5 +20,6 @@
<item name="android:windowBackground">@*android:drawable/dialog_full_holo_light</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowIsTranslucent">true</item>
+ <item name="android:windowAnimationStyle">@*android:style/Animation.Holo.Dialog</item>
</style>
</resources>
diff --git a/packages/Keyguard/res/values-mcc262-mnc08/bools.xml b/packages/Keyguard/res/values-mcc262-mnc08/bools.xml
new file mode 100644
index 000000000000..6cd4c55ca940
--- /dev/null
+++ b/packages/Keyguard/res/values-mcc262-mnc08/bools.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Carriers in this locale are sensitive to capitalization of carrier text.
+ This makes the entire interface consistent by switching back to normal case. -->
+ <bool name="kg_use_all_caps">false</bool>
+</resources>
diff --git a/packages/Keyguard/res/values-mcc262-mnc11/bools.xml b/packages/Keyguard/res/values-mcc262-mnc11/bools.xml
new file mode 100644
index 000000000000..6cd4c55ca940
--- /dev/null
+++ b/packages/Keyguard/res/values-mcc262-mnc11/bools.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Carriers in this locale are sensitive to capitalization of carrier text.
+ This makes the entire interface consistent by switching back to normal case. -->
+ <bool name="kg_use_all_caps">false</bool>
+</resources>
diff --git a/packages/PrintSpooler/res/drawable-hdpi/ic_menu_print.png b/packages/PrintSpooler/res/drawable-hdpi/ic_menu_print.png
new file mode 100644
index 000000000000..09ab1a2bae1d
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-hdpi/ic_menu_print.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-mdpi/ic_menu_print.png b/packages/PrintSpooler/res/drawable-mdpi/ic_menu_print.png
new file mode 100644
index 000000000000..637d94ecfb0e
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-mdpi/ic_menu_print.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-xhdpi/ic_menu_print.png b/packages/PrintSpooler/res/drawable-xhdpi/ic_menu_print.png
new file mode 100644
index 000000000000..4d4b3cc1a119
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-xhdpi/ic_menu_print.png
Binary files differ
diff --git a/packages/PrintSpooler/res/layout/print_job_config_activity_content_editing.xml b/packages/PrintSpooler/res/layout/print_job_config_activity_content_editing.xml
index 83019b9ef79a..02740a308fa5 100644
--- a/packages/PrintSpooler/res/layout/print_job_config_activity_content_editing.xml
+++ b/packages/PrintSpooler/res/layout/print_job_config_activity_content_editing.xml
@@ -107,7 +107,7 @@
android:layout_marginStart="36dip"
android:textAppearance="@style/PrintOptionTitleTextAppearance"
android:labelFor="@+id/range_options_spinner"
- android:text="@string/label_pages">
+ android:text="@string/page_count_unknown">
</TextView>
<Spinner
diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
index 22a9950d0313..3a23b3ec5516 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
@@ -1248,13 +1248,20 @@ public class PrintJobConfigActivity extends Activity {
continue;
}
+ // If nothing changed - done.
+ if (mCurrentPrinter.equals(printer)) {
+ return;
+ }
+
// If the current printer became available and has no
// capabilities, we refresh it.
if (mCurrentPrinter.getStatus() == PrinterInfo.STATUS_UNAVAILABLE
&& printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE
- && printer.getCapabilities() == null
- && !mCapabilitiesTimeout.isPosted()) {
- mCapabilitiesTimeout.post();
+ && printer.getCapabilities() == null) {
+ if (!mCapabilitiesTimeout.isPosted()) {
+ mCapabilitiesTimeout.post();
+ }
+ mCurrentPrinter.copyFrom(printer);
refreshCurrentPrinter();
return;
}
@@ -1268,10 +1275,10 @@ public class PrintJobConfigActivity extends Activity {
&& printer.getCapabilities() == null)) {
if (!mCapabilitiesTimeout.isPosted()) {
mCapabilitiesTimeout.post();
- mCurrentPrinter.copyFrom(printer);
- updateUi();
- return;
}
+ mCurrentPrinter.copyFrom(printer);
+ updateUi();
+ return;
}
// We just refreshed the current printer.
diff --git a/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterFragment.java b/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterFragment.java
index d68893236ca8..be94ba4c9418 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterFragment.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterFragment.java
@@ -93,6 +93,7 @@ public final class SelectPrinterFragment extends ListFragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
+ getActivity().getActionBar().setIcon(R.drawable.ic_menu_print);
}
@Override
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index bc02b0db1e43..158227fe78af 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -47,6 +47,7 @@ import android.os.Bundle;
import android.os.DropBoxManager;
import android.os.FileObserver;
import android.os.ParcelFileDescriptor;
+import android.os.Process;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
@@ -62,6 +63,8 @@ public class SettingsProvider extends ContentProvider {
private static final String TAG = "SettingsProvider";
private static final boolean LOCAL_LOGV = false;
+ private static final boolean USER_CHECK_THROWS = true;
+
private static final String TABLE_SYSTEM = "system";
private static final String TABLE_SECURE = "secure";
private static final String TABLE_GLOBAL = "global";
@@ -522,6 +525,14 @@ public class SettingsProvider extends ContentProvider {
// Lazy initialize the database helper and caches for this user, if necessary
private DatabaseHelper getOrEstablishDatabase(int callingUser) {
+ if (callingUser >= Process.SYSTEM_UID) {
+ if (USER_CHECK_THROWS) {
+ throw new IllegalArgumentException("Uid rather than user handle: " + callingUser);
+ } else {
+ Slog.wtf(TAG, "establish db for uid rather than user: " + callingUser);
+ }
+ }
+
long oldId = Binder.clearCallingIdentity();
try {
DatabaseHelper dbHelper = mOpenHelpers.get(callingUser);
diff --git a/packages/WallpaperCropper/src/com/android/photos/views/TiledImageView.java b/packages/WallpaperCropper/src/com/android/photos/views/TiledImageView.java
index 36cb4384d78c..af4199c91eea 100644
--- a/packages/WallpaperCropper/src/com/android/photos/views/TiledImageView.java
+++ b/packages/WallpaperCropper/src/com/android/photos/views/TiledImageView.java
@@ -63,7 +63,7 @@ public class TiledImageView extends FrameLayout {
// Guarded by locks
public float scale;
public int centerX, centerY;
- int rotation;
+ public int rotation;
public TileSource source;
Runnable isReadyCallback;
diff --git a/packages/WallpaperCropper/src/com/android/wallpapercropper/CropView.java b/packages/WallpaperCropper/src/com/android/wallpapercropper/CropView.java
index b4e715ca24d5..14f7c1d1f7cf 100644
--- a/packages/WallpaperCropper/src/com/android/wallpapercropper/CropView.java
+++ b/packages/WallpaperCropper/src/com/android/wallpapercropper/CropView.java
@@ -17,9 +17,11 @@
package com.android.wallpapercropper;
import android.content.Context;
+import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.RectF;
import android.util.AttributeSet;
+import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.ScaleGestureDetector.OnScaleGestureListener;
@@ -36,10 +38,18 @@ public class CropView extends TiledImageView implements OnScaleGestureListener {
private long mTouchDownTime;
private float mFirstX, mFirstY;
private float mLastX, mLastY;
+ private float mCenterX, mCenterY;
private float mMinScale;
private boolean mTouchEnabled = true;
private RectF mTempEdges = new RectF();
+ private float[] mTempPoint = new float[] { 0, 0 };
+ private float[] mTempCoef = new float[] { 0, 0 };
+ private float[] mTempAdjustment = new float[] { 0, 0 };
+ private float[] mTempImageDims = new float[] { 0, 0 };
+ private float[] mTempRendererCenter = new float[] { 0, 0 };
TouchCallback mTouchCallback;
+ Matrix mRotateMatrix;
+ Matrix mInverseRotateMatrix;
public interface TouchCallback {
void onTouchDown();
@@ -54,17 +64,43 @@ public class CropView extends TiledImageView implements OnScaleGestureListener {
public CropView(Context context, AttributeSet attrs) {
super(context, attrs);
mScaleGestureDetector = new ScaleGestureDetector(context, this);
+ mRotateMatrix = new Matrix();
+ mInverseRotateMatrix = new Matrix();
+ }
+
+ private float[] getImageDims() {
+ final float imageWidth = mRenderer.source.getImageWidth();
+ final float imageHeight = mRenderer.source.getImageHeight();
+ float[] imageDims = mTempImageDims;
+ imageDims[0] = imageWidth;
+ imageDims[1] = imageHeight;
+ mRotateMatrix.mapPoints(imageDims);
+ imageDims[0] = Math.abs(imageDims[0]);
+ imageDims[1] = Math.abs(imageDims[1]);
+ return imageDims;
}
private void getEdgesHelper(RectF edgesOut) {
final float width = getWidth();
final float height = getHeight();
- final float imageWidth = mRenderer.source.getImageWidth();
- final float imageHeight = mRenderer.source.getImageHeight();
+ final float[] imageDims = getImageDims();
+ final float imageWidth = imageDims[0];
+ final float imageHeight = imageDims[1];
+
+ float initialCenterX = mRenderer.source.getImageWidth() / 2f;
+ float initialCenterY = mRenderer.source.getImageHeight() / 2f;
+
+ float[] rendererCenter = mTempRendererCenter;
+ rendererCenter[0] = mCenterX - initialCenterX;
+ rendererCenter[1] = mCenterY - initialCenterY;
+ mRotateMatrix.mapPoints(rendererCenter);
+ rendererCenter[0] += imageWidth / 2;
+ rendererCenter[1] += imageHeight / 2;
+
final float scale = mRenderer.scale;
- float centerX = (width / 2f - mRenderer.centerX + (imageWidth - width) / 2f)
+ float centerX = (width / 2f - rendererCenter[0] + (imageWidth - width) / 2f)
* scale + width / 2f;
- float centerY = (height / 2f - mRenderer.centerY + (imageHeight - height) / 2f)
+ float centerY = (height / 2f - rendererCenter[1] + (imageHeight - height) / 2f)
* scale + height / 2f;
float leftEdge = centerX - imageWidth / 2f * scale;
float rightEdge = centerX + imageWidth / 2f * scale;
@@ -77,6 +113,10 @@ public class CropView extends TiledImageView implements OnScaleGestureListener {
edgesOut.bottom = bottomEdge;
}
+ public int getImageRotation() {
+ return mRenderer.rotation;
+ }
+
public RectF getCrop() {
final RectF edges = mTempEdges;
getEdgesHelper(edges);
@@ -96,6 +136,12 @@ public class CropView extends TiledImageView implements OnScaleGestureListener {
public void setTileSource(TileSource source, Runnable isReadyCallback) {
super.setTileSource(source, isReadyCallback);
+ mCenterX = mRenderer.centerX;
+ mCenterY = mRenderer.centerY;
+ mRotateMatrix.reset();
+ mRotateMatrix.setRotate(mRenderer.rotation);
+ mInverseRotateMatrix.reset();
+ mInverseRotateMatrix.setRotate(-mRenderer.rotation);
updateMinScale(getWidth(), getHeight(), source, true);
}
@@ -115,8 +161,10 @@ public class CropView extends TiledImageView implements OnScaleGestureListener {
mRenderer.scale = 1;
}
if (source != null) {
- mMinScale = Math.max(w / (float) source.getImageWidth(),
- h / (float) source.getImageHeight());
+ final float[] imageDims = getImageDims();
+ final float imageWidth = imageDims[0];
+ final float imageHeight = imageDims[1];
+ mMinScale = Math.max(w / imageWidth, h / imageHeight);
mRenderer.scale = Math.max(mMinScale, mRenderer.scale);
}
}
@@ -154,7 +202,13 @@ public class CropView extends TiledImageView implements OnScaleGestureListener {
final RectF edges = mTempEdges;
getEdgesHelper(edges);
final float scale = mRenderer.scale;
- mRenderer.centerX += Math.ceil(edges.left / scale);
+ mCenterX += Math.ceil(edges.left / scale);
+ updateCenter();
+ }
+
+ private void updateCenter() {
+ mRenderer.centerX = Math.round(mCenterX);
+ mRenderer.centerY = Math.round(mCenterY);
}
public void setTouchEnabled(boolean enabled) {
@@ -200,7 +254,7 @@ public class CropView extends TiledImageView implements OnScaleGestureListener {
if (mTouchCallback != null) {
// only do this if it's a small movement
if (squaredDist < slop &&
- now < mTouchDownTime + ViewConfiguration.getTapTimeout()) {
+ now < mTouchDownTime + ViewConfiguration.getTapTimeout()) {
mTouchCallback.onTap();
}
mTouchCallback.onTouchUp();
@@ -215,8 +269,13 @@ public class CropView extends TiledImageView implements OnScaleGestureListener {
mScaleGestureDetector.onTouchEvent(event);
switch (action) {
case MotionEvent.ACTION_MOVE:
- mRenderer.centerX += (mLastX - x) / mRenderer.scale;
- mRenderer.centerY += (mLastY - y) / mRenderer.scale;
+ float[] point = mTempPoint;
+ point[0] = (mLastX - x) / mRenderer.scale;
+ point[1] = (mLastY - y) / mRenderer.scale;
+ mInverseRotateMatrix.mapPoints(point);
+ mCenterX += point[0];
+ mCenterY += point[1];
+ updateCenter();
invalidate();
break;
}
@@ -226,18 +285,32 @@ public class CropView extends TiledImageView implements OnScaleGestureListener {
final RectF edges = mTempEdges;
getEdgesHelper(edges);
final float scale = mRenderer.scale;
+
+ float[] coef = mTempCoef;
+ coef[0] = 1;
+ coef[1] = 1;
+ mRotateMatrix.mapPoints(coef);
+ float[] adjustment = mTempAdjustment;
+ mTempAdjustment[0] = 0;
+ mTempAdjustment[1] = 0;
if (edges.left > 0) {
- mRenderer.centerX += Math.ceil(edges.left / scale);
- }
- if (edges.right < getWidth()) {
- mRenderer.centerX += (edges.right - getWidth()) / scale;
+ adjustment[0] = edges.left / scale;
+ } else if (edges.right < getWidth()) {
+ adjustment[0] = (edges.right - getWidth()) / scale;
}
if (edges.top > 0) {
- mRenderer.centerY += Math.ceil(edges.top / scale);
+ adjustment[1] = FloatMath.ceil(edges.top / scale);
+ } else if (edges.bottom < getHeight()) {
+ adjustment[1] = (edges.bottom - getHeight()) / scale;
}
- if (edges.bottom < getHeight()) {
- mRenderer.centerY += (edges.bottom - getHeight()) / scale;
+ for (int dim = 0; dim <= 1; dim++) {
+ if (coef[dim] > 0) adjustment[dim] = FloatMath.ceil(adjustment[dim]);
}
+
+ mInverseRotateMatrix.mapPoints(adjustment);
+ mCenterX += adjustment[0];
+ mCenterY += adjustment[1];
+ updateCenter();
}
}
diff --git a/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java b/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
index 710e8e470d4d..1209e56c193c 100644
--- a/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
+++ b/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
@@ -37,12 +37,14 @@ import android.graphics.RectF;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.util.FloatMath;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.exif.ExifInterface;
import com.android.photos.BitmapRegionTileSource;
import java.io.BufferedInputStream;
@@ -85,10 +87,17 @@ public class WallpaperCropActivity extends Activity {
mCropView = (CropView) findViewById(R.id.cropView);
- Intent cropIntent = this.getIntent();
+ Intent cropIntent = getIntent();
final Uri imageUri = cropIntent.getData();
- mCropView.setTileSource(new BitmapRegionTileSource(this, imageUri, 1024, 0), null);
+ if (imageUri == null) {
+ Log.e(LOGTAG, "No URI passed in intent, exiting WallpaperCropActivity");
+ finish();
+ return;
+ }
+
+ int rotation = getRotationFromExif(this, imageUri);
+ mCropView.setTileSource(new BitmapRegionTileSource(this, imageUri, 1024, rotation), null);
mCropView.setTouchEnabled(true);
// Action bar
// Show the custom action bar view
@@ -102,8 +111,6 @@ public class WallpaperCropActivity extends Activity {
cropImageAndSetWallpaper(imageUri, null, finishActivityWhenDone);
}
});
- getWindow().addPrivateFlags(
- WindowManager.LayoutParams.PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR);
}
public boolean enableRotation() {
@@ -170,9 +177,47 @@ public class WallpaperCropActivity extends Activity {
return new Point(defaultWidth, defaultHeight);
}
+ public static int getRotationFromExif(String path) {
+ return getRotationFromExifHelper(path, null, 0, null, null);
+ }
+
+ public static int getRotationFromExif(Context context, Uri uri) {
+ return getRotationFromExifHelper(null, null, 0, context, uri);
+ }
+
+ public static int getRotationFromExif(Resources res, int resId) {
+ return getRotationFromExifHelper(null, res, resId, null, null);
+ }
+
+ private static int getRotationFromExifHelper(
+ String path, Resources res, int resId, Context context, Uri uri) {
+ ExifInterface ei = new ExifInterface();
+ try {
+ if (path != null) {
+ ei.readExif(path);
+ } else if (uri != null) {
+ InputStream is = context.getContentResolver().openInputStream(uri);
+ BufferedInputStream bis = new BufferedInputStream(is);
+ ei.readExif(bis);
+ } else {
+ InputStream is = res.openRawResource(resId);
+ BufferedInputStream bis = new BufferedInputStream(is);
+ ei.readExif(bis);
+ }
+ Integer ori = ei.getTagIntValue(ExifInterface.TAG_ORIENTATION);
+ if (ori != null) {
+ return ExifInterface.getRotationForOrientationValue(ori.shortValue());
+ }
+ } catch (IOException e) {
+ Log.w(LOGTAG, "Getting exif data failed", e);
+ }
+ return 0;
+ }
+
protected void setWallpaper(String filePath, final boolean finishActivityWhenDone) {
- BitmapCropTask cropTask = new BitmapCropTask(this,
- filePath, null, 0, 0, true, false, null);
+ int rotation = getRotationFromExif(filePath);
+ BitmapCropTask cropTask = new BitmapCropTask(
+ this, filePath, null, rotation, 0, 0, true, false, null);
final Point bounds = cropTask.getImageBounds();
Runnable onEndCrop = new Runnable() {
public void run() {
@@ -192,6 +237,7 @@ public class WallpaperCropActivity extends Activity {
Resources res, int resId, final boolean finishActivityWhenDone) {
// crop this image and scale it down to the default wallpaper size for
// this device
+ int rotation = getRotationFromExif(res, resId);
Point inSize = mCropView.getSourceDimensions();
Point outSize = getDefaultWallpaperSize(getResources(),
getWindowManager());
@@ -209,8 +255,7 @@ public class WallpaperCropActivity extends Activity {
}
};
BitmapCropTask cropTask = new BitmapCropTask(this, res, resId,
- crop, outSize.x, outSize.y,
- true, false, onEndCrop);
+ crop, rotation, outSize.x, outSize.y, true, false, onEndCrop);
cropTask.execute();
}
@@ -222,8 +267,6 @@ public class WallpaperCropActivity extends Activity {
protected void cropImageAndSetWallpaper(Uri uri,
OnBitmapCroppedHandler onBitmapCroppedHandler, final boolean finishActivityWhenDone) {
// Get the crop
- Point inSize = mCropView.getSourceDimensions();
-
boolean ltr = mCropView.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
Point minDims = new Point();
@@ -262,12 +305,21 @@ public class WallpaperCropActivity extends Activity {
}
// Get the crop
RectF cropRect = mCropView.getCrop();
+ int cropRotation = mCropView.getImageRotation();
float cropScale = mCropView.getWidth() / (float) cropRect.width();
+ Point inSize = mCropView.getSourceDimensions();
+ Matrix rotateMatrix = new Matrix();
+ rotateMatrix.setRotate(cropRotation);
+ float[] rotatedInSize = new float[] { inSize.x, inSize.y };
+ rotateMatrix.mapPoints(rotatedInSize);
+ rotatedInSize[0] = Math.abs(rotatedInSize[0]);
+ rotatedInSize[1] = Math.abs(rotatedInSize[1]);
+
// ADJUST CROP WIDTH
// Extend the crop all the way to the right, for parallax
// (or all the way to the left, in RTL)
- float extraSpace = ltr ? inSize.x - cropRect.right : cropRect.left;
+ float extraSpace = ltr ? rotatedInSize[0] - cropRect.right : cropRect.left;
// Cap the amount of extra width
float maxExtraSpace = defaultWallpaperWidth / cropScale - cropRect.width();
extraSpace = Math.min(extraSpace, maxExtraSpace);
@@ -285,7 +337,7 @@ public class WallpaperCropActivity extends Activity {
float extraPortraitHeight =
portraitHeight / cropScale - cropRect.height();
float expandHeight =
- Math.min(Math.min(inSize.y - cropRect.bottom, cropRect.top),
+ Math.min(Math.min(rotatedInSize[1] - cropRect.bottom, cropRect.top),
extraPortraitHeight / 2);
cropRect.top -= expandHeight;
cropRect.bottom += expandHeight;
@@ -303,7 +355,7 @@ public class WallpaperCropActivity extends Activity {
}
};
BitmapCropTask cropTask = new BitmapCropTask(this, uri,
- cropRect, outWidth, outHeight, true, false, onEndCrop);
+ cropRect, cropRotation, outWidth, outHeight, true, false, onEndCrop);
if (onBitmapCroppedHandler != null) {
cropTask.setOnBitmapCropped(onBitmapCroppedHandler);
}
@@ -323,7 +375,7 @@ public class WallpaperCropActivity extends Activity {
InputStream mInStream;
RectF mCropBounds = null;
int mOutWidth, mOutHeight;
- int mRotation = 0; // for now
+ int mRotation;
String mOutputFormat = "jpg"; // for now
boolean mSetWallpaper;
boolean mSaveCroppedBitmap;
@@ -334,40 +386,45 @@ public class WallpaperCropActivity extends Activity {
boolean mNoCrop;
public BitmapCropTask(Context c, String filePath,
- RectF cropBounds, int outWidth, int outHeight,
+ RectF cropBounds, int rotation, int outWidth, int outHeight,
boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
mContext = c;
mInFilePath = filePath;
- init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
+ init(cropBounds, rotation,
+ outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
}
public BitmapCropTask(byte[] imageBytes,
- RectF cropBounds, int outWidth, int outHeight,
+ RectF cropBounds, int rotation, int outWidth, int outHeight,
boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
mInImageBytes = imageBytes;
- init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
+ init(cropBounds, rotation,
+ outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
}
public BitmapCropTask(Context c, Uri inUri,
- RectF cropBounds, int outWidth, int outHeight,
+ RectF cropBounds, int rotation, int outWidth, int outHeight,
boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
mContext = c;
mInUri = inUri;
- init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
+ init(cropBounds, rotation,
+ outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
}
public BitmapCropTask(Context c, Resources res, int inResId,
- RectF cropBounds, int outWidth, int outHeight,
+ RectF cropBounds, int rotation, int outWidth, int outHeight,
boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
mContext = c;
mInResId = inResId;
mResources = res;
- init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
+ init(cropBounds, rotation,
+ outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
}
- private void init(RectF cropBounds, int outWidth, int outHeight,
+ private void init(RectF cropBounds, int rotation, int outWidth, int outHeight,
boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
mCropBounds = cropBounds;
+ mRotation = rotation;
mOutWidth = outWidth;
mOutHeight = outHeight;
mSetWallpaper = setWallpaper;
@@ -454,6 +511,29 @@ public class WallpaperCropActivity extends Activity {
if (mInStream != null) {
// Find crop bounds (scaled to original image size)
Rect roundedTrueCrop = new Rect();
+ Matrix rotateMatrix = new Matrix();
+ Matrix inverseRotateMatrix = new Matrix();
+ if (mRotation > 0) {
+ rotateMatrix.setRotate(mRotation);
+ inverseRotateMatrix.setRotate(-mRotation);
+
+ mCropBounds.roundOut(roundedTrueCrop);
+ mCropBounds = new RectF(roundedTrueCrop);
+
+ Point bounds = getImageBounds();
+
+ float[] rotatedBounds = new float[] { bounds.x, bounds.y };
+ rotateMatrix.mapPoints(rotatedBounds);
+ rotatedBounds[0] = Math.abs(rotatedBounds[0]);
+ rotatedBounds[1] = Math.abs(rotatedBounds[1]);
+
+ mCropBounds.offset(-rotatedBounds[0]/2, -rotatedBounds[1]/2);
+ inverseRotateMatrix.mapRect(mCropBounds);
+ mCropBounds.offset(bounds.x/2, bounds.y/2);
+
+ regenerateInputStream();
+ }
+
mCropBounds.roundOut(roundedTrueCrop);
if (roundedTrueCrop.width() <= 0 || roundedTrueCrop.height() <= 0) {
@@ -497,6 +577,12 @@ public class WallpaperCropActivity extends Activity {
fullSize = BitmapFactory.decodeStream(mInStream, null, options);
}
if (fullSize != null) {
+ mCropBounds.left /= scaleDownSampleSize;
+ mCropBounds.top /= scaleDownSampleSize;
+ mCropBounds.bottom /= scaleDownSampleSize;
+ mCropBounds.right /= scaleDownSampleSize;
+ mCropBounds.roundOut(roundedTrueCrop);
+
crop = Bitmap.createBitmap(fullSize, roundedTrueCrop.left,
roundedTrueCrop.top, roundedTrueCrop.width(),
roundedTrueCrop.height());
@@ -508,16 +594,40 @@ public class WallpaperCropActivity extends Activity {
failure = true;
return false;
}
- if (mOutWidth > 0 && mOutHeight > 0) {
- Matrix m = new Matrix();
- RectF cropRect = new RectF(0, 0, crop.getWidth(), crop.getHeight());
- if (mRotation > 0) {
- m.setRotate(mRotation);
- m.mapRect(cropRect);
+ if (mOutWidth > 0 && mOutHeight > 0 || mRotation > 0) {
+ float[] dimsAfter = new float[] { crop.getWidth(), crop.getHeight() };
+ rotateMatrix.mapPoints(dimsAfter);
+ dimsAfter[0] = Math.abs(dimsAfter[0]);
+ dimsAfter[1] = Math.abs(dimsAfter[1]);
+
+ if (!(mOutWidth > 0 && mOutHeight > 0)) {
+ mOutWidth = Math.round(dimsAfter[0]);
+ mOutHeight = Math.round(dimsAfter[1]);
}
+
+ RectF cropRect = new RectF(0, 0, dimsAfter[0], dimsAfter[1]);
RectF returnRect = new RectF(0, 0, mOutWidth, mOutHeight);
- m.setRectToRect(cropRect, returnRect, Matrix.ScaleToFit.FILL);
- m.preRotate(mRotation);
+
+ Matrix m = new Matrix();
+ if (mRotation == 0) {
+ m.setRectToRect(cropRect, returnRect, Matrix.ScaleToFit.FILL);
+ } else {
+ Matrix m1 = new Matrix();
+ m1.setTranslate(-crop.getWidth() / 2f, -crop.getHeight() / 2f);
+ Matrix m2 = new Matrix();
+ m2.setRotate(mRotation);
+ Matrix m3 = new Matrix();
+ m3.setTranslate(dimsAfter[0] / 2f, dimsAfter[1] / 2f);
+ Matrix m4 = new Matrix();
+ m4.setRectToRect(cropRect, returnRect, Matrix.ScaleToFit.FILL);
+
+ Matrix c1 = new Matrix();
+ c1.setConcat(m2, m1);
+ Matrix c2 = new Matrix();
+ c2.setConcat(m4, m3);
+ m.setConcat(c2, c1);
+ }
+
Bitmap tmp = Bitmap.createBitmap((int) returnRect.width(),
(int) returnRect.height(), Bitmap.Config.ARGB_8888);
if (tmp != null) {
@@ -527,14 +637,6 @@ public class WallpaperCropActivity extends Activity {
c.drawBitmap(crop, m, p);
crop = tmp;
}
- } else if (mRotation > 0) {
- Matrix m = new Matrix();
- m.setRotate(mRotation);
- Bitmap tmp = Bitmap.createBitmap(crop, 0, 0, crop.getWidth(),
- crop.getHeight(), m, true);
- if (tmp != null) {
- crop = tmp;
- }
}
if (mSaveCroppedBitmap) {
@@ -603,8 +705,7 @@ public class WallpaperCropActivity extends Activity {
final SharedPreferences sharedPrefs,
WindowManager windowManager,
final WallpaperManager wallpaperManager) {
- final Point defaultWallpaperSize =
- WallpaperCropActivity.getDefaultWallpaperSize(res, windowManager);
+ final Point defaultWallpaperSize = getDefaultWallpaperSize(res, windowManager);
new Thread("suggestWallpaperDimension") {
public void run() {
@@ -616,7 +717,6 @@ public class WallpaperCropActivity extends Activity {
}.start();
}
-
protected static RectF getMaxCropRect(
int inWidth, int inHeight, int outWidth, int outHeight, boolean leftAligned) {
RectF cropRect = new RectF();
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 5ac3ed0b690d..1c43014e54c8 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -297,6 +297,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
boolean mHasSoftInput = false;
boolean mTouchExplorationEnabled = false;
+ boolean mTranslucentDecorEnabled = true;
int mPointerLocationMode = 0; // guarded by mLock
@@ -901,6 +902,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
com.android.internal.R.integer.config_lidNavigationAccessibility);
mLidControlsSleep = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_lidControlsSleep);
+ mTranslucentDecorEnabled = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_enableTranslucentDecor);
readConfigurationDependentBehaviors();
// register for dock events
@@ -2703,7 +2706,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
boolean immersiveSticky = (sysui & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0;
boolean navAllowedHidden = immersive || immersiveSticky;
navTranslucent &= !immersiveSticky; // transient trumps translucent
- navTranslucent &= isTranslucentNavigationAllowed();
+ navTranslucent &= areTranslucentBarsAllowed();
// When the navigation bar isn't visible, we put up a fake
// input window to catch all touch events. This way we can
@@ -2824,6 +2827,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
boolean statusBarTransient = (sysui & View.STATUS_BAR_TRANSIENT) != 0;
boolean statusBarTranslucent = (sysui & View.STATUS_BAR_TRANSLUCENT) != 0;
+ statusBarTranslucent &= areTranslucentBarsAllowed();
// If the status bar is hidden, we don't want to cause
// windows behind it to scroll.
@@ -3565,7 +3569,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
public boolean allowAppAnimationsLw() {
- if (mKeyguard != null && mKeyguard.isVisibleLw() || mShowingDream) {
+ if (mKeyguard != null && mKeyguard.isVisibleLw() && !mKeyguard.isAnimatingLw()
+ || mShowingDream) {
// If keyguard or dreams is currently visible, no reason to animate behind it.
return false;
}
@@ -5116,8 +5121,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
vis = (vis & ~flags) | (oldVis & flags);
}
- if (!isTranslucentNavigationAllowed()) {
- vis &= ~View.NAVIGATION_BAR_TRANSLUCENT;
+ if (!areTranslucentBarsAllowed()) {
+ vis &= ~(View.NAVIGATION_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSLUCENT);
}
// update status bar
@@ -5182,11 +5187,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
/**
- * @return whether the navigation bar can be made translucent, e.g. touch
- * exploration is not enabled
+ * @return whether the navigation or status bar can be made translucent
+ *
+ * This should return true unless touch exploration is not enabled or
+ * R.boolean.config_enableTranslucentDecor is false.
*/
- private boolean isTranslucentNavigationAllowed() {
- return !mTouchExplorationEnabled;
+ private boolean areTranslucentBarsAllowed() {
+ return mTranslucentDecorEnabled && !mTouchExplorationEnabled;
}
// Use this instead of checking config_showNavigationBar so that it can be consistently
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 0908563c957c..00a653bba18d 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -187,7 +187,7 @@ public class WindowManagerService extends IWindowManager.Stub
static final boolean DEBUG_SURFACE_TRACE = false;
static final boolean DEBUG_WINDOW_TRACE = false;
static final boolean DEBUG_TASK_MOVEMENT = false;
- static final boolean DEBUG_STACK = true;
+ static final boolean DEBUG_STACK = false;
static final boolean SHOW_SURFACE_ALLOC = false;
static final boolean SHOW_TRANSACTIONS = false;
static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
@@ -1852,13 +1852,21 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- // Now stick it in.
+ // Now stick it in. For apps over wallpaper keep the wallpaper at the bottommost
+ // layer. For keyguard over wallpaper put the wallpaper under the keyguard.
+ int insertionIndex = 0;
+ if (visible && foundW != null) {
+ final int type = foundW.mAttrs.type;
+ if (type == TYPE_KEYGUARD || type == TYPE_KEYGUARD_SCRIM) {
+ insertionIndex = windows.indexOf(foundW);
+ }
+ }
if (DEBUG_WALLPAPER_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
Slog.v(TAG, "Moving wallpaper " + wallpaper
- + " from " + oldIndex + " to " + 0);
+ + " from " + oldIndex + " to " + insertionIndex);
}
- windows.add(0, wallpaper);
+ windows.add(insertionIndex, wallpaper);
mWindowsChanged = true;
changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
}
diff --git a/telephony/java/android/telephony/CellSignalStrengthCdma.java b/telephony/java/android/telephony/CellSignalStrengthCdma.java
index 190fea2b13ab..c94509459e34 100644
--- a/telephony/java/android/telephony/CellSignalStrengthCdma.java
+++ b/telephony/java/android/telephony/CellSignalStrengthCdma.java
@@ -331,10 +331,12 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements
@Override
public void writeToParcel(Parcel dest, int flags) {
if (DBG) log("writeToParcel(Parcel, int): " + toString());
- dest.writeInt(mCdmaDbm);
- dest.writeInt(mCdmaEcio);
- dest.writeInt(mEvdoDbm);
- dest.writeInt(mEvdoEcio);
+ // Need to multiply CdmaDbm, CdmaEcio, EvdoDbm and EvdoEcio by -1
+ // to ensure consistency when reading values written here
+ dest.writeInt(mCdmaDbm * -1);
+ dest.writeInt(mCdmaEcio * -1);
+ dest.writeInt(mEvdoDbm * -1);
+ dest.writeInt(mEvdoEcio * -1);
dest.writeInt(mEvdoSnr);
}
@@ -343,10 +345,13 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements
* where the TYPE_LTE token is already been processed.
*/
private CellSignalStrengthCdma(Parcel in) {
- mCdmaDbm = in.readInt();
- mCdmaEcio = in.readInt();
- mEvdoDbm = in.readInt();
- mEvdoEcio = in.readInt();
+ // CdmaDbm, CdmaEcio, EvdoDbm and EvdoEcio are written into
+ // the parcel as positive values.
+ // Need to convert into negative values
+ mCdmaDbm = in.readInt() * -1;
+ mCdmaEcio = in.readInt() * -1;
+ mEvdoDbm = in.readInt() * -1;
+ mEvdoEcio = in.readInt() * -1;
mEvdoSnr = in.readInt();
if (DBG) log("CellSignalStrengthCdma(Parcel): " + toString());
}
diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java
index b456bb35b2d2..5a1559aa7e65 100644
--- a/telephony/java/android/telephony/CellSignalStrengthLte.java
+++ b/telephony/java/android/telephony/CellSignalStrengthLte.java
@@ -247,8 +247,10 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P
public void writeToParcel(Parcel dest, int flags) {
if (DBG) log("writeToParcel(Parcel, int): " + toString());
dest.writeInt(mSignalStrength);
- dest.writeInt(mRsrp);
- dest.writeInt(mRsrq);
+ // Need to multiply rsrp and rsrq by -1
+ // to ensure consistency when reading values written here
+ dest.writeInt(mRsrp * -1);
+ dest.writeInt(mRsrq * -1);
dest.writeInt(mRssnr);
dest.writeInt(mCqi);
dest.writeInt(mTimingAdvance);
@@ -260,8 +262,10 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P
*/
private CellSignalStrengthLte(Parcel in) {
mSignalStrength = in.readInt();
- mRsrp = in.readInt();
- mRsrq = in.readInt();
+ // rsrp and rsrq are written into the parcel as positive values.
+ // Need to convert into negative values
+ mRsrp = in.readInt() * -1;
+ mRsrq = in.readInt() * -1;
mRssnr = in.readInt();
mCqi = in.readInt();
mTimingAdvance = in.readInt();
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index ea0d220deb9d..8f17e7279924 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -127,19 +127,40 @@ public class TelephonyManager {
/**
* The Phone app sends this intent when a user opts to respond-via-message during an incoming
- * call. By default, the MMS app consumes this message and sends a text message to the caller. A
- * third party app can provide this functionality in lieu of MMS app by consuming this Intent
- * and sending the message using their own messaging system. The intent contains a URI
- * describing the recipient, and an EXTRA containing the message itself.
+ * call. By default, the device's default SMS app consumes this message and sends a text message
+ * to the caller. A third party app can also provide this functionality by consuming this Intent
+ * with a {@link android.app.Service} and sending the message using its own messaging system.
+ * <p>The intent contains a URI (available from {@link android.content.Intent#getData})
+ * describing the recipient, using either the {@code sms:}, {@code smsto:}, {@code mms:},
+ * or {@code mmsto:} URI schema. Each of these URI schema carry the recipient information the
+ * same way: the path part of the URI contains the recipient's phone number or a comma-separated
+ * set of phone numbers if there are multiple recipients. For example, {@code
+ * smsto:2065551234}.</p>
+ *
+ * <p>The intent may also contain extras for the message text (in {@link
+ * android.content.Intent#EXTRA_TEXT}) and a message subject
+ * (in {@link android.content.Intent#EXTRA_SUBJECT}).</p>
+ *
* <p class="note"><strong>Note:</strong>
- * The intent-filter which consumes this Intent needs to be in a service which requires the
+ * The intent-filter that consumes this Intent needs to be in a {@link android.app.Service}
+ * that requires the
* permission {@link android.Manifest.permission#SEND_RESPOND_VIA_MESSAGE}.</p>
- *
- * <p>
- * {@link android.content.Intent#getData} is a URI describing the recipient of the message.
- * <p>
- * The {@link android.content.Intent#EXTRA_TEXT} extra contains the message
- * to send.
+ * <p>For example, the service that receives this intent can be declared in the manifest file
+ * with an intent filter like this:</p>
+ * <pre>
+ * &lt;!-- Service that delivers SMS messages received from the phone "quick response" -->
+ * &lt;service android:name=".HeadlessSmsSendService"
+ * android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
+ * android:exported="true" >
+ * &lt;intent-filter>
+ * &lt;action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
+ * &lt;category android:name="android.intent.category.DEFAULT" />
+ * &lt;data android:scheme="sms" />
+ * &lt;data android:scheme="smsto" />
+ * &lt;data android:scheme="mms" />
+ * &lt;data android:scheme="mmsto" />
+ * &lt;/intent-filter>
+ * &lt;/service></pre>
* <p>
* Output: nothing.
*/