auto import from //branches/cupcake/...@127436
diff --git a/api/current.xml b/api/current.xml
index e183217..935454a 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -3738,6 +3738,17 @@
visibility="public"
>
</field>
+<field name="initialLayout"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843351"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="innerRadiusRatio"
type="int"
transient="false"
@@ -7555,6 +7566,17 @@
visibility="public"
>
</field>
+<field name="updatePeriodMillis"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843350"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="useLevel"
type="int"
transient="false"
@@ -13212,6 +13234,17 @@
<parameter name="event" type="android.view.MotionEvent">
</parameter>
</method>
+<method name="onUserLeaving"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+</method>
<method name="onWindowAttributesChanged"
return="void"
abstract="false"
@@ -17295,6 +17328,19 @@
<parameter name="activity" type="android.app.Activity">
</parameter>
</method>
+<method name="callActivityOnUserLeaving"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="activity" type="android.app.Activity">
+</parameter>
+</method>
<method name="callApplicationOnCreate"
return="void"
abstract="false"
@@ -27528,6 +27574,17 @@
visibility="public"
>
</field>
+<field name="FLAG_ACTIVITY_NO_USER_ACTION"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="262144"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="FLAG_ACTIVITY_PREVIOUS_IS_TOP"
type="int"
transient="false"
@@ -41330,6 +41387,19 @@
<parameter name="isMutable" type="boolean">
</parameter>
</method>
+<method name="copyPixelsFromBuffer"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="src" type="java.nio.Buffer">
+</parameter>
+</method>
<method name="copyPixelsToBuffer"
return="void"
abstract="false"
@@ -129780,6 +129850,17 @@
deprecated="not deprecated"
visibility="public"
>
+<method name="beginBatchEdit"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="clearMetaKeyStates"
return="boolean"
abstract="true"
@@ -129836,6 +129917,17 @@
<parameter name="rightLength" type="int">
</parameter>
</method>
+<method name="endBatchEdit"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="finishComposingText"
return="boolean"
abstract="true"
@@ -130002,6 +130094,17 @@
<parameter name="base" type="android.view.inputmethod.InputConnection">
</parameter>
</constructor>
+<method name="beginBatchEdit"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="clearMetaKeyStates"
return="boolean"
abstract="false"
@@ -130058,6 +130161,17 @@
<parameter name="rightLength" type="int">
</parameter>
</method>
+<method name="endBatchEdit"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="finishComposingText"
return="boolean"
abstract="false"
@@ -145853,6 +145967,21 @@
<parameter name="running" type="boolean">
</parameter>
</method>
+<method name="setImageViewBitmap"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="viewId" type="int">
+</parameter>
+<parameter name="bitmap" type="android.graphics.Bitmap">
+</parameter>
+</method>
<method name="setImageViewResource"
return="void"
abstract="false"
@@ -145883,6 +146012,21 @@
<parameter name="uri" type="android.net.Uri">
</parameter>
</method>
+<method name="setOnClickPendingIntent"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="viewId" type="int">
+</parameter>
+<parameter name="pendingIntent" type="android.app.PendingIntent">
+</parameter>
+</method>
<method name="setProgressBar"
return="void"
abstract="false"
@@ -149295,6 +149439,17 @@
visibility="public"
>
</method>
+<method name="onBeginBatchEdit"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="onCommitCompletion"
return="void"
abstract="false"
@@ -149308,6 +149463,17 @@
<parameter name="text" type="android.view.inputmethod.CompletionInfo">
</parameter>
</method>
+<method name="onEndBatchEdit"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="onPreDraw"
return="boolean"
abstract="false"
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index ab7d67a..a3651b2 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -118,12 +118,12 @@
if (avail < 0) return -1;
LOGI("free_cache(%d) avail %d\n", free_size, avail);
- if (avail > free_size) return 0;
+ if (avail >= free_size) return 0;
d = opendir(PKG_DIR_PREFIX);
if (d == NULL) {
LOGE("cannot open %s\n", PKG_DIR_PREFIX);
- return 0;
+ return -1;
}
dfd = dirfd(d);
@@ -144,7 +144,7 @@
close(subfd);
avail = disk_free();
- if (avail > free_size) {
+ if (avail >= free_size) {
closedir(d);
return 0;
}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index c98cf1b..4dc4b6a 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1132,6 +1132,17 @@
}
/**
+ * Called as part of the activity lifecycle when an activity is about to go
+ * into the background as the result of user choice. For example, when the
+ * user presses the Home key, {@link #onUserLeaving} will be called, but
+ * when an incoming phone call causes the in-call Activity to be automatically
+ * brought to the foreground, {@link #onUserLeaving} will not be called on
+ * the activity being interrupted.
+ */
+ protected void onUserLeaving() {
+ }
+
+ /**
* Generate a new thumbnail for this activity. This method is called before
* pausing the activity, and should draw into <var>outBitmap</var> the
* imagery for the desired thumbnail in the dimensions of that bitmap. It
@@ -3470,6 +3481,10 @@
onPause();
}
+ final void performUserLeaving() {
+ onUserLeaving();
+ }
+
final void performStop() {
if (!mStopped) {
if (mWindow != null) {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index a98e295..e4c1057 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1207,10 +1207,12 @@
private static final String TWO_COUNT_COLUMNS = "%17s %8d %17s %8d";
public final void schedulePauseActivity(IBinder token, boolean finished,
- int configChanges) {
+ boolean userLeaving, int configChanges) {
queueOrSendMessage(
finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
- token, configChanges);
+ token,
+ (userLeaving ? 1 : 0),
+ configChanges);
}
public final void scheduleStopActivity(IBinder token, boolean showWindow,
@@ -1588,10 +1590,10 @@
handleRelaunchActivity(r, msg.arg1);
} break;
case PAUSE_ACTIVITY:
- handlePauseActivity((IBinder)msg.obj, false, msg.arg2);
+ handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
break;
case PAUSE_ACTIVITY_FINISHING:
- handlePauseActivity((IBinder)msg.obj, true, msg.arg2);
+ handlePauseActivity((IBinder)msg.obj, true, msg.arg1 != 0, msg.arg2);
break;
case STOP_ACTIVITY_SHOW:
handleStopActivity((IBinder)msg.obj, true, msg.arg2);
@@ -2647,9 +2649,14 @@
}
private final void handlePauseActivity(IBinder token, boolean finished,
- int configChanges) {
+ boolean userLeaving, int configChanges) {
ActivityRecord r = mActivities.get(token);
if (r != null) {
+ //Log.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
+ if (userLeaving) {
+ performUserLeavingActivity(r);
+ }
+
r.activity.mConfigChangeFlags |= configChanges;
Bundle state = performPauseActivity(token, finished, true);
@@ -2661,6 +2668,10 @@
}
}
+ final void performUserLeavingActivity(ActivityRecord r) {
+ mInstrumentation.callActivityOnUserLeaving(r.activity);
+ }
+
final Bundle performPauseActivity(IBinder token, boolean finished,
boolean saveState) {
ActivityRecord r = mActivities.get(token);
diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java
index 0e41ae6..4236a00 100644
--- a/core/java/android/app/ApplicationContext.java
+++ b/core/java/android/app/ApplicationContext.java
@@ -315,8 +315,13 @@
backup.renameTo(f);
}
+ // Debugging
+ if (f.exists() && !f.canRead()) {
+ Log.w(TAG, "Attempt to read preferences file " + f + " without permission");
+ }
+
Map map = null;
- if (f.exists()) {
+ if (f.exists() && f.canRead()) {
try {
str = new FileInputStream(f);
map = XmlUtils.readMapXml(str);
@@ -2264,14 +2269,23 @@
}
}
@Override
- public void freeApplicationCache(long idealStorageSize,
- IPackageDataObserver observer) {
+ public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
try {
- mPM.freeApplicationCache(idealStorageSize, observer);
+ mPM.freeStorageAndNotify(idealStorageSize, observer);
} catch (RemoteException e) {
// Should never happen!
}
}
+
+ @Override
+ public void freeStorage(long idealStorageSize, PendingIntent opFinishedIntent) {
+ try {
+ mPM.freeStorage(idealStorageSize, opFinishedIntent);
+ } catch (RemoteException e) {
+ // Should never happen!
+ }
+ }
+
@Override
public void getPackageSizeInfo(String packageName,
IPackageStatsObserver observer) {
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 54237ae..d2cf55a 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -69,8 +69,9 @@
data.enforceInterface(IApplicationThread.descriptor);
IBinder b = data.readStrongBinder();
boolean finished = data.readInt() != 0;
+ boolean userLeaving = data.readInt() != 0;
int configChanges = data.readInt();
- schedulePauseActivity(b, finished, configChanges);
+ schedulePauseActivity(b, finished, userLeaving, configChanges);
return true;
}
@@ -344,11 +345,12 @@
}
public final void schedulePauseActivity(IBinder token, boolean finished,
- int configChanges) throws RemoteException {
+ boolean userLeaving, int configChanges) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(token);
data.writeInt(finished ? 1 : 0);
+ data.writeInt(userLeaving ? 1 :0);
data.writeInt(configChanges);
mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index a351581..47476b5 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -40,7 +40,7 @@
* {@hide}
*/
public interface IApplicationThread extends IInterface {
- void schedulePauseActivity(IBinder token, boolean finished,
+ void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving,
int configChanges) throws RemoteException;
void scheduleStopActivity(IBinder token, boolean showWindow,
int configChanges) throws RemoteException;
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 17618ff..f96d787 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1266,6 +1266,16 @@
activity.performPause();
}
+ /**
+ * Perform calling of an activity's {@link Activity#onUserLeaving} method.
+ * The default implementation simply calls through to that method.
+ *
+ * @param activity The activity being notified that the user has navigated away
+ */
+ public void callActivityOnUserLeaving(Activity activity) {
+ activity.performUserLeaving();
+ }
+
/*
* Starts allocation counting. This triggers a gc and resets the counts.
*/
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 5af08f7..2e2a1a1 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -222,17 +222,27 @@
// configure the autocomplete aspects of the input box
mSearchTextField.setOnItemClickListener(this);
mSearchTextField.setOnItemSelectedListener(this);
-
- // attach the suggestions adapter
- mSuggestionsAdapter = new SuggestionsAdapter(getContext(), mSearchable);
- mSearchTextField.setAdapter(mSuggestionsAdapter);
- // finally, load the user's initial text (which may trigger suggestions)
- mSuggestionsAdapter.setNonUserQuery(false);
+ // This conversion is necessary to force a preload of the EditText and thus force
+ // suggestions to be presented (even for an empty query)
if (initialQuery == null) {
initialQuery = ""; // This forces the preload to happen, triggering suggestions
}
- mSearchTextField.setText(initialQuery);
+
+ // attach the suggestions adapter, if suggestions are available
+ // The existence of a suggestions authority is the proxy for "suggestions available here"
+ if (mSearchable.getSuggestAuthority() == null) {
+ mSuggestionsAdapter = null;
+ mSearchTextField.setAdapter(mSuggestionsAdapter);
+ mSearchTextField.setText(initialQuery);
+ } else {
+ mSuggestionsAdapter = new SuggestionsAdapter(getContext(), mSearchable);
+ mSearchTextField.setAdapter(mSuggestionsAdapter);
+
+ // finally, load the user's initial text (which may trigger suggestions)
+ mSuggestionsAdapter.setNonUserQuery(false);
+ mSearchTextField.setText(initialQuery);
+ }
if (selectInitialQuery) {
mSearchTextField.selectAll();
@@ -344,7 +354,9 @@
return;
}
- mSuggestionsAdapter.setNonUserQuery(true);
+ if (mSuggestionsAdapter != null) {
+ mSuggestionsAdapter.setNonUserQuery(true);
+ }
mSearchTextField.setText(displayQuery);
// TODO because the new query is (not) processed in another thread, we can't just
// take away this flag (yet). The better solution here is going to require a new API
@@ -539,7 +551,7 @@
}
updateWidgetState();
// Only do suggestions if actually typed by user
- if (!mSuggestionsAdapter.getNonUserQuery()) {
+ if ((mSuggestionsAdapter != null) && !mSuggestionsAdapter.getNonUserQuery()) {
mPreviousSuggestionQuery = s.toString();
mUserQuery = mSearchTextField.getText().toString();
mUserQuerySelStart = mSearchTextField.getSelectionStart();
@@ -822,6 +834,10 @@
* React to the user typing an action key while in the suggestions list
*/
private boolean doSuggestionsKey(View v, int keyCode, KeyEvent event) {
+ // Exit early in case of race condition
+ if (mSuggestionsAdapter == null) {
+ return false;
+ }
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (DBG_LOG_TIMING == 1) {
dbgLogTiming("doSuggestionsKey()");
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index d1f71c5..d613e1c 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -39,6 +39,28 @@
public static final int RESULT_FAILURE = -1;
public static final int RESULT_SUCCESS = 0;
+ /** We do not have a link key for the remote device, and are therefore not
+ * bonded */
+ public static final int BOND_NOT_BONDED = 0;
+ /** We have a link key for the remote device, and are probably bonded. */
+ public static final int BOND_BONDED = 1;
+ /** We are currently attempting bonding */
+ public static final int BOND_BONDING = 2;
+
+ //TODO: Unify these result codes in BluetoothResult or BluetoothError
+ /** A bond attempt failed because pins did not match, or remote device did
+ * not respond to pin request in time */
+ public static final int UNBOND_REASON_AUTH_FAILED = 1;
+ /** A bond attempt failed because the other side explicilty rejected
+ * bonding */
+ public static final int UNBOND_REASON_AUTH_REJECTED = 2;
+ /** A bond attempt failed because we cancelled the bonding process */
+ public static final int UNBOND_REASON_CANCELLED = 3;
+ /** A bond attempt failed because we could not contact the remote device */
+ public static final int UNBOND_REASON_AUTH_REMOTE_DEVICE_DOWN = 4;
+ /** An existing bond was explicitly revoked */
+ public static final int UNBOND_REASON_REMOVED = 5;
+
private static final String TAG = "BluetoothDevice";
private final IBluetoothDevice mService;
@@ -325,42 +347,36 @@
/**
* Create a bonding with a remote bluetooth device.
*
- * This is an asynchronous call. BluetoothIntent.BONDING_CREATED_ACTION
- * will be broadcast if and when the remote device is successfully bonded.
+ * This is an asynchronous call. The result of this bonding attempt can be
+ * observed through BluetoothIntent.BOND_STATE_CHANGED_ACTION intents.
*
* @param address the remote device Bluetooth address.
- * @return false if we cannot create a bonding to that device, true if
- * there were no problems beginning the bonding process.
+ * @return false If there was an immediate problem creating the bonding,
+ * true otherwise.
*/
- public boolean createBonding(String address) {
- return createBonding(address, null);
- }
-
- /**
- * Create a bonding with a remote bluetooth device.
- *
- * This is an asynchronous call. onCreateBondingResult() of your callback
- * will be called when the call is complete, with either RESULT_SUCCESS or
- * RESULT_FAILURE.
- *
- * In addition to the callback, BluetoothIntent.BONDING_CREATED_ACTION will
- * be broadcast if the remote device is successfully bonded.
- *
- * @param address The remote device Bluetooth address.
- * @param callback Your callback, null is ok.
- * @return true if your callback was successfully registered, or false if
- * there was an error, implying your callback will never be called.
- */
- public boolean createBonding(String address, IBluetoothDeviceCallback callback) {
+ public boolean createBond(String address) {
try {
- return mService.createBonding(address, callback);
+ return mService.createBond(address);
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false;
}
- public boolean cancelBondingProcess(String address) {
+ /**
+ * Cancel an in-progress bonding request started with createBond.
+ */
+ public boolean cancelBondProcess(String address) {
try {
- return mService.cancelBondingProcess(address);
+ return mService.cancelBondProcess(address);
+ } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return false;
+ }
+
+ /**
+ * Remove an already exisiting bonding (delete the link key).
+ */
+ public boolean removeBond(String address) {
+ try {
+ return mService.removeBond(address);
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false;
}
@@ -382,48 +398,34 @@
*
* This function does not check if the remote device is in range.
*
+ * Remote devices that have an in-progress bonding attempt are not
+ * returned.
+ *
* @return bluetooth hardware addresses of remote devices that are
* bonded. Array size is 0 if no devices are bonded. Null on error.
*/
- public String[] listBondings() {
+ public String[] listBonds() {
try {
- return mService.listBondings();
+ return mService.listBonds();
} catch (RemoteException e) {Log.e(TAG, "", e);}
return null;
}
/**
- * Check if a remote device is bonded (paired) to the local device.
+ * Get the bonding state of a remote device.
*
- * Bonding (pairing) is the process by which the user enters a pin code for
- * the device, which generates a shared link key, allowing for
- * authentication and encryption of future connections. In Android we
- * require bonding before RFCOMM or SCO connections can be made to a remote
- * device.
- *
- * This function checks if we have a link key with the remote device. It
- * does not cause any RF transmission, and does not check if the remote
- * device still has it's link key with us. If the other side no longer has
- * a link key then the RFCOMM or SCO connection attempt will result in an
- * error.
- *
- * This function does not check if the remote device is in range.
+ * Result is one of:
+ * BluetoothError.*
+ * BOND_*
*
* @param address Bluetooth hardware address of the remote device to check.
- * @return true if bonded, false otherwise and on error.
+ * @return Result code
*/
- public boolean hasBonding(String address) {
+ public int getBondState(String address) {
try {
- return mService.hasBonding(address);
+ return mService.getBondState(address);
} catch (RemoteException e) {Log.e(TAG, "", e);}
- return false;
- }
-
- public boolean removeBonding(String address) {
- try {
- return mService.removeBonding(address);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return false;
+ return BluetoothError.ERROR_IPC;
}
public String getRemoteName(String address) {
diff --git a/core/java/android/bluetooth/BluetoothIntent.java b/core/java/android/bluetooth/BluetoothIntent.java
index 8e22791..57c46f9 100644
--- a/core/java/android/bluetooth/BluetoothIntent.java
+++ b/core/java/android/bluetooth/BluetoothIntent.java
@@ -45,6 +45,12 @@
"android.bluetooth.intent.HEADSET_STATE";
public static final String HEADSET_PREVIOUS_STATE =
"android.bluetooth.intent.HEADSET_PREVIOUS_STATE";
+ public static final String BOND_STATE =
+ "android.bluetooth.intent.BOND_STATE";
+ public static final String BOND_PREVIOUS_STATE =
+ "android.bluetooth.intent.BOND_PREVIOUS_STATE";
+ public static final String REASON =
+ "android.bluetooth.intent.REASON";
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ENABLED_ACTION =
@@ -105,12 +111,17 @@
public static final String REMOTE_ALIAS_CLEARED_ACTION =
"android.bluetooth.intent.action.REMOTE_ALIAS_CLEARED";
+ /**
+ * Broadcast when the bond state of a remote device changes.
+ * Has string extra ADDRESS and int extras BOND_STATE and
+ * BOND_PREVIOUS_STATE.
+ * If BOND_STATE is BluetoothDevice.BOND_NOT_BONDED then will
+ * also have an int extra REASON with a value of:
+ * BluetoothDevice.BOND_RESULT_*
+ * */
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String BONDING_CREATED_ACTION =
- "android.bluetooth.intent.action.BONDING_CREATED";
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String BONDING_REMOVED_ACTION =
- "android.bluetooth.intent.action.BONDING_REMOVED";
+ public static final String BOND_STATE_CHANGED_ACTION =
+ "android.bluetooth.intent.action.BOND_STATE_CHANGED_ACTION";
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String HEADSET_STATE_CHANGED_ACTION =
diff --git a/core/java/android/bluetooth/IBluetoothDevice.aidl b/core/java/android/bluetooth/IBluetoothDevice.aidl
index e7cc8ed..59f679f 100644
--- a/core/java/android/bluetooth/IBluetoothDevice.aidl
+++ b/core/java/android/bluetooth/IBluetoothDevice.aidl
@@ -57,11 +57,11 @@
boolean isAclConnected(in String address);
boolean disconnectRemoteDeviceAcl(in String address);
- boolean createBonding(in String address, in IBluetoothDeviceCallback callback);
- boolean cancelBondingProcess(in String address);
- String[] listBondings();
- boolean hasBonding(in String address);
- boolean removeBonding(in String address);
+ boolean createBond(in String address);
+ boolean cancelBondProcess(in String address);
+ boolean removeBond(in String address);
+ String[] listBonds();
+ int getBondState(in String address);
String getRemoteName(in String address);
String getRemoteAlias(in String address);
diff --git a/core/java/android/bluetooth/IBluetoothDeviceCallback.aidl b/core/java/android/bluetooth/IBluetoothDeviceCallback.aidl
index 86f44dd..d25bd56 100644
--- a/core/java/android/bluetooth/IBluetoothDeviceCallback.aidl
+++ b/core/java/android/bluetooth/IBluetoothDeviceCallback.aidl
@@ -21,7 +21,6 @@
*/
oneway interface IBluetoothDeviceCallback
{
- void onCreateBondingResult(in String address, int result);
void onGetRemoteServiceChannelResult(in String address, int channel);
void onEnableResult(int result);
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 4a92b4c..e2d3576 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1225,6 +1225,22 @@
public static final String ACTION_MEDIA_UNMOUNTED = "android.intent.action.MEDIA_UNMOUNTED";
/**
+ * Broadcast Action: External media is present, and being disk-checked
+ * The path to the mount point for the checking media is contained in the Intent.mData field.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_MEDIA_CHECKING = "android.intent.action.MEDIA_CHECKING";
+
+ /**
+ * Broadcast Action: External media is present, but is using an incompatible fs (or is blank)
+ * The path to the mount point for the checking media is contained in the Intent.mData field.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_MEDIA_NOFS = "android.intent.action.MEDIA_NOFS";
+
+ /**
* Broadcast Action: External media is present and mounted at its mount point.
* The path to the mount point for the removed media is contained in the Intent.mData field.
* The Intent contains an extra with name "read-only" and Boolean value to indicate if the
@@ -1838,6 +1854,23 @@
* to mail.
*/
public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 0x00080000;
+ /**
+ * If set, this flag will prevent the normal {@link android.app.Activity#onUserLeaving}
+ * callback from occurring on the current frontmost activity before it is
+ * paused as the newly-started activity is brought to the front.
+ *
+ * <p>Typically, an activity can rely on that callback to indicate that an
+ * explicit user action has caused their activity to be moved out of the
+ * foreground. The callback marks an appropriate point in the activity's
+ * lifecycle for it to dismiss any notifications that it intends to display
+ * "until the user has seen them," such as a blinking LED.
+ *
+ * <p>If an activity is ever started via any non-user-driven events such as
+ * phone-call receipt or an alarm handler, this flag should be passed to {@link
+ * Context#startActivity Context.startActivity}, ensuring that the pausing
+ * activity does not think the user has acknowledged its notification.
+ */
+ public static final int FLAG_ACTIVITY_NO_USER_ACTION = 0x00040000;
/**
* If set, when sending a broadcast only registered receivers will be
@@ -3836,6 +3869,7 @@
* @see #FLAG_ACTIVITY_MULTIPLE_TASK
* @see #FLAG_ACTIVITY_NEW_TASK
* @see #FLAG_ACTIVITY_NO_HISTORY
+ * @see #FLAG_ACTIVITY_NO_USER_ACTION
* @see #FLAG_ACTIVITY_PREVIOUS_IS_TOP
* @see #FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
* @see #FLAG_ACTIVITY_SINGLE_TOP
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index fdb2a2f..ea86188 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -34,6 +34,7 @@
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.net.Uri;
+import android.app.PendingIntent;
/**
* See {@link PackageManager} for documentation on most of the APIs
@@ -184,22 +185,51 @@
int getApplicationEnabledSetting(in String packageName);
/**
- * Free storage by deleting LRU sorted list of cache files across all applications.
- * If the currently available free storage on the device is greater than or equal to the
- * requested free storage, no cache files are cleared. If the currently available storage on the
- * device is less than the requested free storage, some or all of the cache files across
- * all applications are deleted(based on last accessed time) to increase the free storage
- * space on the device to the requested value. There is no gurantee that clearing all
- * the cache files from all applications will clear up enough storage to achieve the desired
- * value.
- * @param freeStorageSize The number of bytes of storage to be
- * freed by the system. Say if freeStorageSize is XX,
- * and the current free storage is YY,
- * if XX is less than YY, just return. if not free XX-YY number of
- * bytes if possible.
- * @param observer callback used to notify when the operation is completed
+ * Free storage by deleting LRU sorted list of cache files across
+ * all applications. If the currently available free storage
+ * on the device is greater than or equal to the requested
+ * free storage, no cache files are cleared. If the currently
+ * available storage on the device is less than the requested
+ * free storage, some or all of the cache files across
+ * all applications are deleted (based on last accessed time)
+ * to increase the free storage space on the device to
+ * the requested value. There is no guarantee that clearing all
+ * the cache files from all applications will clear up
+ * enough storage to achieve the desired value.
+ * @param freeStorageSize The number of bytes of storage to be
+ * freed by the system. Say if freeStorageSize is XX,
+ * and the current free storage is YY,
+ * if XX is less than YY, just return. if not free XX-YY number
+ * of bytes if possible.
+ * @param observer call back used to notify when
+ * the operation is completed
*/
- void freeApplicationCache(in long freeStorageSize, IPackageDataObserver observer);
+ void freeStorageAndNotify(in long freeStorageSize,
+ IPackageDataObserver observer);
+
+ /**
+ * Free storage by deleting LRU sorted list of cache files across
+ * all applications. If the currently available free storage
+ * on the device is greater than or equal to the requested
+ * free storage, no cache files are cleared. If the currently
+ * available storage on the device is less than the requested
+ * free storage, some or all of the cache files across
+ * all applications are deleted (based on last accessed time)
+ * to increase the free storage space on the device to
+ * the requested value. There is no guarantee that clearing all
+ * the cache files from all applications will clear up
+ * enough storage to achieve the desired value.
+ * @param freeStorageSize The number of bytes of storage to be
+ * freed by the system. Say if freeStorageSize is XX,
+ * and the current free storage is YY,
+ * if XX is less than YY, just return. if not free XX-YY number
+ * of bytes if possible.
+ * @param opFinishedIntent PendingIntent call back used to
+ * notify when the operation is completed.May be null
+ * to indicate that no call back is desired.
+ */
+ void freeStorage(in long freeStorageSize,
+ in PendingIntent opFinishedIntent);
/**
* Delete all the cache files in an applications cache directory
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index a544550..4b902e9 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -17,6 +17,7 @@
package android.content.pm;
+import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -1357,28 +1358,53 @@
IPackageDataObserver observer);
/**
- * Free storage by deleting LRU sorted list of cache files across all applications.
- * If the currently available free storage on the device is greater than or equal to the
- * requested free storage, no cache files are cleared. If the currently available storage on the
- * device is less than the requested free storage, some or all of the cache files across
- * all applications are deleted(based on last accessed time) to increase the free storage
- * space on the device to the requested value. There is no gurantee that clearing all
- * the cache files from all applications will clear up enough storage to achieve the desired
- * value.
+ * Free storage by deleting LRU sorted list of cache files across
+ * all applications. If the currently available free storage
+ * on the device is greater than or equal to the requested
+ * free storage, no cache files are cleared. If the currently
+ * available storage on the device is less than the requested
+ * free storage, some or all of the cache files across
+ * all applications are deleted (based on last accessed time)
+ * to increase the free storage space on the device to
+ * the requested value. There is no guarantee that clearing all
+ * the cache files from all applications will clear up
+ * enough storage to achieve the desired value.
* @param freeStorageSize The number of bytes of storage to be
* freed by the system. Say if freeStorageSize is XX,
* and the current free storage is YY,
- * if XX is less than YY, just return. if not free XX-YY number of
- * bytes if possible.
- * @param observer callback used to notify when the operation is completed
- * {@link android.content.pm.IPackageDataObserver#onRemoveCompleted(String, boolean)}
- * will be called when that happens. observer may be null to indicate that
- * no callback is desired.
- *
+ * if XX is less than YY, just return. if not free XX-YY number
+ * of bytes if possible.
+ * @param observer call back used to notify when
+ * the operation is completed
+ *
* @hide
*/
- public abstract void freeApplicationCache(long freeStorageSize,
- IPackageDataObserver observer);
+ public abstract void freeStorageAndNotify(long freeStorageSize, IPackageDataObserver observer);
+
+ /**
+ * Free storage by deleting LRU sorted list of cache files across
+ * all applications. If the currently available free storage
+ * on the device is greater than or equal to the requested
+ * free storage, no cache files are cleared. If the currently
+ * available storage on the device is less than the requested
+ * free storage, some or all of the cache files across
+ * all applications are deleted (based on last accessed time)
+ * to increase the free storage space on the device to
+ * the requested value. There is no guarantee that clearing all
+ * the cache files from all applications will clear up
+ * enough storage to achieve the desired value.
+ * @param freeStorageSize The number of bytes of storage to be
+ * freed by the system. Say if freeStorageSize is XX,
+ * and the current free storage is YY,
+ * if XX is less than YY, just return. if not free XX-YY number
+ * of bytes if possible.
+ * @param opFinishedIntent PendingIntent call back used to
+ * notify when the operation is completed.May be null
+ * to indicate that no call back is desired.
+ *
+ * @hide
+ */
+ public abstract void freeStorage(long freeStorageSize, PendingIntent opFinishedIntent);
/**
* Retrieve the size information for a package.
diff --git a/core/java/android/gadget/GadgetManager.java b/core/java/android/gadget/GadgetManager.java
index 49c706e..088dc86 100644
--- a/core/java/android/gadget/GadgetManager.java
+++ b/core/java/android/gadget/GadgetManager.java
@@ -54,17 +54,22 @@
/**
* Sent when it is time to update your gadget.
*/
- public static final String GADGET_UPDATE_ACTION = "android.gadget.GADGET_UPDATE";
+ public static final String GADGET_UPDATE_ACTION = "android.gadget.action.GADGET_UPDATE";
/**
* Sent when the gadget is added to a host for the first time. TODO: Maybe we don't want this.
*/
- public static final String GADGET_ENABLE_ACTION = "android.gadget.GADGET_ENABLE";
+ public static final String GADGET_ENABLE_ACTION = "android.gadget.action.GADGET_ENABLE";
/**
* Sent when the gadget is removed from the last host. TODO: Maybe we don't want this.
*/
- public static final String GADGET_DISABLE_ACTION = "android.gadget.GADGET_DISABLE";
+ public static final String GADGET_DISABLE_ACTION = "android.gadget.action.GADGET_DISABLE";
+
+ /**
+ * Field for the manifest meta-data tag.
+ */
+ public static final String GADGET_PROVIDER_META_DATA = "android.gadget.provider";
static WeakHashMap<Context, WeakReference<GadgetManager>> sManagerCache = new WeakHashMap();
static IGadgetService sService;
@@ -108,10 +113,15 @@
}
/**
- * Return a list of the gadgets that are currently installed.
+ * Return a list of the gadget providers that are currently installed.
*/
- public List<GadgetInfo> getAvailableGadgets() {
- return null;
+ public List<GadgetInfo> getInstalledProviders() {
+ try {
+ return sService.getInstalledProviders();
+ }
+ catch (RemoteException e) {
+ throw new RuntimeException("system server dead?", e);
+ }
}
/**
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 1a7547d..3a9b26a 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -498,7 +498,15 @@
if (showingCandidates) {
setCandidatesViewShown(true);
}
- showWindow(showingInput);
+ if (showingInput) {
+ // If we are showing the full soft keyboard, then go through
+ // this path to take care of current decisions about fullscreen
+ // etc.
+ onShowRequested(InputMethod.SHOW_EXPLICIT);
+ } else {
+ // Otherwise just put it back for its candidates.
+ showWindow(false);
+ }
}
}
@@ -649,16 +657,14 @@
/**
* Override this to control when the input method should run in
* fullscreen mode. The default implementation runs in fullsceen only
- * when the screen is in landscape mode and the input view is being
- * shown ({@link #onEvaluateInputViewShown} returns true). If you change what
+ * when the screen is in landscape mode. If you change what
* this returns, you will need to call {@link #updateFullscreenMode()}
* yourself whenever the returned value may have changed to have it
* re-evaluated and applied.
*/
public boolean onEvaluateFullscreenMode() {
Configuration config = getResources().getConfiguration();
- return config.orientation == Configuration.ORIENTATION_LANDSCAPE
- && onEvaluateInputViewShown();
+ return config.orientation == Configuration.ORIENTATION_LANDSCAPE;
}
/**
@@ -870,7 +876,11 @@
}
/**
- * Called when an input session is starting or restarting.
+ * Called when the input view is being shown and input has started on
+ * a new editor. This will always be called after {@link #onStartInput},
+ * allowing you to do your general setup there and just view-specific
+ * setup here. You are guaranteed that {@link #onCreateInputView()} will
+ * have been called some time before this function is called.
*
* @param info Description of the type of text being edited.
* @param restarting Set to true if we are restarting input on the
@@ -892,6 +902,9 @@
* as per {@link InputMethod#showSoftInput(int) InputMethod.showSoftInput(int)}.
*/
public void onShowRequested(int flags) {
+ if (!onEvaluateInputViewShown()) {
+ return;
+ }
if ((flags&InputMethod.SHOW_EXPLICIT) == 0 && onEvaluateFullscreenMode()) {
// Don't show if this is not explicit requested by the user and
// the input method is fullscreen. That would be too disruptive.
@@ -911,9 +924,11 @@
boolean wasVisible = mWindowVisible;
mWindowVisible = true;
if (!mShowInputRequested) {
- if (showInput) {
- doShowInput = true;
- mShowInputRequested = true;
+ if (mInputStarted) {
+ if (showInput) {
+ doShowInput = true;
+ mShowInputRequested = true;
+ }
}
} else {
showInput = true;
@@ -1001,7 +1016,7 @@
mInputEditorInfo = attribute;
onStartInput(attribute, restarting);
if (mWindowVisible) {
- if (mWindowCreated) {
+ if (mShowInputRequested) {
onStartInputView(mInputEditorInfo, restarting);
}
startExtractingText();
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index 6f044b6..2f3b54b 100755
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -153,9 +153,10 @@
/** Listener for {@link OnKeyboardActionListener}. */
private OnKeyboardActionListener mKeyboardActionListener;
- private static final int MSG_REMOVE_PREVIEW = 1;
- private static final int MSG_REPEAT = 2;
- private static final int MSG_LONGPRESS = 3;
+ private static final int MSG_SHOW_PREVIEW = 1;
+ private static final int MSG_REMOVE_PREVIEW = 2;
+ private static final int MSG_REPEAT = 3;
+ private static final int MSG_LONGPRESS = 4;
private int mVerticalCorrection;
private int mProximityThreshold;
@@ -198,7 +199,8 @@
private static final int REPEAT_INTERVAL = 50; // ~20 keys per second
private static final int REPEAT_START_DELAY = 400;
- private static final int LONGPRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout();
+ private static final int LONGPRESS_TIMEOUT = 800;
+ // Deemed to be too short : ViewConfiguration.getLongPressTimeout();
private static int MAX_NEARBY_KEYS = 12;
private int[] mDistances = new int[MAX_NEARBY_KEYS];
@@ -215,6 +217,9 @@
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
+ case MSG_SHOW_PREVIEW:
+ mPreviewText.setVisibility(VISIBLE);
+ break;
case MSG_REMOVE_PREVIEW:
mPreviewText.setVisibility(INVISIBLE);
break;
@@ -731,7 +736,7 @@
return adjustCase(key.label);
}
}
-
+
private void showPreview(int keyIndex) {
int oldKeyIndex = mCurrentKeyIndex;
final PopupWindow previewPopup = mPreviewPopup;
@@ -751,6 +756,7 @@
}
// If key changed and preview is on ...
if (oldKeyIndex != mCurrentKeyIndex && mShowPreview) {
+ mHandler.removeMessages(MSG_SHOW_PREVIEW);
if (previewPopup.isShowing()) {
if (keyIndex == NOT_A_KEY) {
mHandler.sendMessageDelayed(mHandler
@@ -803,7 +809,7 @@
mPreviewText.getBackground().setState(
key.popupResId != 0 ? LONG_PRESSABLE_STATE_SET : EMPTY_STATE_SET);
if (previewPopup.isShowing()) {
- previewPopup.update(mPopupPreviewX + mOffsetInWindow[0],
+ previewPopup.update(mPopupParent, mPopupPreviewX + mOffsetInWindow[0],
mPopupPreviewY + mOffsetInWindow[1],
popupWidth, popupHeight);
} else {
@@ -811,7 +817,8 @@
mPopupPreviewX + mOffsetInWindow[0],
mPopupPreviewY + mOffsetInWindow[1]);
}
- mPreviewText.setVisibility(VISIBLE);
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SHOW_PREVIEW, keyIndex, 0),
+ ViewConfiguration.getTapTimeout());
}
}
}
@@ -1014,6 +1021,7 @@
break;
case MotionEvent.ACTION_UP:
+ mHandler.removeMessages(MSG_SHOW_PREVIEW);
mHandler.removeMessages(MSG_REPEAT);
mHandler.removeMessages(MSG_LONGPRESS);
if (keyIndex == mCurrentKey) {
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index e065063..ed7c366 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -237,7 +237,7 @@
public abstract long computeBatteryRealtime(long curTime, int which);
/**
- * Returns the total, last, or current uptime in micropeconds.
+ * Returns the total, last, or current uptime in microseconds.
*
* @param curTime the current elapsed realtime in microseconds.
* @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
@@ -299,6 +299,9 @@
}
private final String formatRatioLocked(long num, long den) {
+ if (den == 0L) {
+ return "---%";
+ }
float perc = ((float)num) / ((float)den) * 100;
mFormatBuilder.setLength(0);
mFormatter.format("%.1f%%", perc);
@@ -352,18 +355,20 @@
long batteryUptime = computeBatteryUptime(uSecNow, which);
long batteryRealtime = computeBatteryRealtime(getBatteryRealtime(uSecTime), which);
long elapsedRealtime = computeRealtime(uSecTime, which);
+ long uptime = computeUptime(SystemClock.uptimeMillis() * 1000, which);
+
pw.println(prefix
- + " On battery: " + formatTimeMs(batteryUptime) + "("
+ + " On battery: " + formatTimeMs(batteryUptime / 1000) + "("
+ formatRatioLocked(batteryUptime, batteryRealtime)
+ ") uptime, "
- + formatTimeMs(batteryRealtime) + "("
+ + formatTimeMs(batteryRealtime / 1000) + "("
+ formatRatioLocked(batteryRealtime, elapsedRealtime)
+ ") realtime");
pw.println(prefix
+ " Total: "
- + formatTimeMs(computeUptime(SystemClock.uptimeMillis() * 1000, which))
+ + formatTimeMs(uptime / 1000)
+ "uptime, "
- + formatTimeMs(elapsedRealtime)
+ + formatTimeMs(elapsedRealtime / 1000)
+ "realtime");
pw.println(" ");
@@ -479,7 +484,7 @@
if (startTime != 0 || starts != 0 || launches != 0) {
pw.println(prefix + " Service " + sent.getKey() + ":");
pw.println(prefix + " Time spent started: "
- + formatTimeMs(startTime));
+ + formatTimeMs(startTime / 1000));
pw.println(prefix + " Starts: " + starts
+ ", launches: " + launches);
apkActivity = true;
diff --git a/core/java/android/provider/Gmail.java b/core/java/android/provider/Gmail.java
index 1bbcc33..325f19d 100644
--- a/core/java/android/provider/Gmail.java
+++ b/core/java/android/provider/Gmail.java
@@ -554,13 +554,15 @@
*
* @param account the account of the conversation
* @param conversationId the conversation
- * @param maxMessageId the highest message id to whose labels should be changed
+ * @param maxServerMessageId the highest message id to whose labels should be changed. Note that
+ * everywhere else in this file messageId means local message id but here you need to use a
+ * server message id.
* @param label the label to add or remove
* @param add true to add the label, false to remove it
* @throws NonexistentLabelException thrown if the label does not exist
*/
public void addOrRemoveLabelOnConversation(
- String account, long conversationId, long maxMessageId, String label,
+ String account, long conversationId, long maxServerMessageId, String label,
boolean add)
throws NonexistentLabelException {
if (TextUtils.isEmpty(account)) {
@@ -571,7 +573,7 @@
AUTHORITY_PLUS_CONVERSATIONS + account + "/" + conversationId + "/labels");
ContentValues values = new ContentValues();
values.put(LabelColumns.CANONICAL_NAME, label);
- values.put(ConversationColumns.MAX_MESSAGE_ID, maxMessageId);
+ values.put(ConversationColumns.MAX_MESSAGE_ID, maxServerMessageId);
mContentResolver.insert(uri, values);
} else {
String encodedLabel;
@@ -584,7 +586,7 @@
AUTHORITY_PLUS_CONVERSATIONS + account + "/"
+ conversationId + "/labels/" + encodedLabel);
mContentResolver.delete(
- uri, ConversationColumns.MAX_MESSAGE_ID, new String[]{"" + maxMessageId});
+ uri, ConversationColumns.MAX_MESSAGE_ID, new String[]{"" + maxServerMessageId});
}
}
@@ -2373,7 +2375,7 @@
/**
* @return the max message id in the conversation
*/
- public long getMaxMessageId() {
+ public long getMaxServerMessageId() {
return mCursor.getLong(mMaxMessageIdIndex);
}
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 0184db8..87a02e6 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -148,6 +148,13 @@
public final static String EXTRA_VIDEO_QUALITY = "android.intent.extra.videoQuality";
/**
+ * The name of the Intent-extra used to indicate a Uri to be used to
+ * store the requested image or video.
+ * @hide
+ */
+ public final static String EXTRA_OUTPUT = "output";
+
+ /**
* Common fields for most MediaProvider tables
*/
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a18f37c..abbfd5b 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2121,6 +2121,12 @@
= "youtube_use_proxy";
/**
+ * MMS - maximum message size in bytes for a MMS message.
+ */
+ public static final String MMS_MAXIMUM_MESSAGE_SIZE
+ = "mms_maximum_message_size";
+
+ /**
* Event tags from the kernel event log to upload during checkin.
*/
public static final String CHECKIN_EVENTS = "checkin_events";
@@ -2685,6 +2691,22 @@
"short_keylight_delay_ms";
/**
+ * URL that points to the voice search servers. To be factored out of this class.
+ */
+ public static final String VOICE_SEARCH_URL = "voice_search_url";
+
+ /**
+ * Speech encoding used with voice search on 3G networks. To be factored out of this class.
+ */
+ public static final String VOICE_SEARCH_ENCODING_THREE_G = "voice_search_encoding_three_g";
+
+ /**
+ * Speech encoding used with voice search on WIFI networks. To be factored out of this class.
+ */
+ public static final String VOICE_SEARCH_ENCODING_WIFI = "voice_search_encoding_wifi";
+
+
+ /**
* @deprecated
* @hide
*/
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index be784ff..8486e4b 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -84,8 +84,7 @@
mIntentFilter = new IntentFilter(BluetoothIntent.ENABLED_ACTION);
mIntentFilter.addAction(BluetoothIntent.DISABLED_ACTION);
- mIntentFilter.addAction(BluetoothIntent.BONDING_CREATED_ACTION);
- mIntentFilter.addAction(BluetoothIntent.BONDING_REMOVED_ACTION);
+ mIntentFilter.addAction(BluetoothIntent.BOND_STATE_CHANGED_ACTION);
mContext.registerReceiver(mReceiver, mIntentFilter);
if (device.isEnabled()) {
@@ -111,10 +110,18 @@
onBluetoothEnable();
} else if (action.equals(BluetoothIntent.DISABLED_ACTION)) {
onBluetoothDisable();
- } else if (action.equals(BluetoothIntent.BONDING_CREATED_ACTION)) {
- setSinkPriority(address, BluetoothA2dp.PRIORITY_AUTO);
- } else if (action.equals(BluetoothIntent.BONDING_REMOVED_ACTION)) {
- setSinkPriority(address, BluetoothA2dp.PRIORITY_OFF);
+ } else if (action.equals(BluetoothIntent.BOND_STATE_CHANGED_ACTION)) {
+ int bondState = intent.getIntExtra(BluetoothIntent.BOND_STATE,
+ BluetoothError.ERROR);
+ switch(bondState) {
+ case BluetoothDevice.BOND_BONDED:
+ setSinkPriority(address, BluetoothA2dp.PRIORITY_AUTO);
+ break;
+ case BluetoothDevice.BOND_BONDING:
+ case BluetoothDevice.BOND_NOT_BONDED:
+ setSinkPriority(address, BluetoothA2dp.PRIORITY_OFF);
+ break;
+ }
}
}
};
diff --git a/core/java/android/server/BluetoothDeviceService.java b/core/java/android/server/BluetoothDeviceService.java
index 9bdab9f..3ce34c3 100644
--- a/core/java/android/server/BluetoothDeviceService.java
+++ b/core/java/android/server/BluetoothDeviceService.java
@@ -26,6 +26,7 @@
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset; // just for dump()
+import android.bluetooth.BluetoothError;
import android.bluetooth.BluetoothIntent;
import android.bluetooth.IBluetoothDevice;
import android.bluetooth.IBluetoothDeviceCallback;
@@ -49,14 +50,19 @@
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Map;
public class BluetoothDeviceService extends IBluetoothDevice.Stub {
private static final String TAG = "BluetoothDeviceService";
+ private static final boolean DBG = true;
+
private int mNativeData;
private BluetoothEventLoop mEventLoop;
private IntentFilter mIntentFilter;
private boolean mIsAirplaneSensitive;
+ private final BondState mBondState = new BondState(); // local cache of bondings
private volatile boolean mIsEnabled; // local cache of isEnabledNative()
private boolean mIsDiscovering;
@@ -79,10 +85,13 @@
public synchronized void init() {
initializeNativeDataNative();
mIsEnabled = (isEnabledNative() == 1);
+ if (mIsEnabled) {
+ mBondState.loadBondState();
+ }
mIsDiscovering = false;
mEventLoop = new BluetoothEventLoop(mContext, this);
registerForAirplaneMode();
-
+
disableEsco(); // TODO: enable eSCO support once its fully supported
}
private native void initializeNativeDataNative();
@@ -112,7 +121,7 @@
public synchronized boolean disable() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH_ADMIN permission");
-
+
if (mEnableThread != null && mEnableThread.isAlive()) {
return false;
}
@@ -171,7 +180,6 @@
};
private EnableThread mEnableThread;
- private String mOutgoingBondingDevAddress = null;
private class EnableThread extends Thread {
private final IBluetoothDeviceCallback mEnableCallback;
@@ -198,6 +206,7 @@
Settings.Secure.BLUETOOTH_ON, 1);
mIsDiscovering = false;
Intent intent = new Intent(BluetoothIntent.ENABLED_ACTION);
+ mBondState.loadBondState();
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
mHandler.sendMessageDelayed(mHandler.obtainMessage(REGISTER_SDP_RECORDS), 3000);
}
@@ -208,6 +217,119 @@
private native int enableNative();
private native int disableNative();
+ /* package */ BondState getBondState() {
+ return mBondState;
+ }
+
+ /** local cache of bonding state.
+ /* we keep our own state to track the intermediate state BONDING, which
+ /* bluez does not track.
+ * All addreses must be passed in upper case.
+ */
+ public class BondState {
+ private final HashMap<String, Integer> mState = new HashMap<String, Integer>();
+ private final HashMap<String, Integer> mPinAttempt = new HashMap<String, Integer>();
+
+ public synchronized void loadBondState() {
+ if (!mIsEnabled) {
+ return;
+ }
+ String[] bonds = listBondingsNative();
+ if (bonds == null) {
+ return;
+ }
+ mState.clear();
+ if (DBG) log("found " + bonds.length + " bonded devices");
+ for (String address : bonds) {
+ mState.put(address.toUpperCase(), BluetoothDevice.BOND_BONDED);
+ }
+ }
+
+ public synchronized void setBondState(String address, int state) {
+ setBondState(address, state, 0);
+ }
+
+ /** reason is ignored unless state == BOND_NOT_BONDED */
+ public synchronized void setBondState(String address, int state, int reason) {
+ int oldState = getBondState(address);
+ if (oldState == state) {
+ return;
+ }
+ if (DBG) log(address + " bond state " + oldState + " -> " + state + " (" +
+ reason + ")");
+ Intent intent = new Intent(BluetoothIntent.BOND_STATE_CHANGED_ACTION);
+ intent.putExtra(BluetoothIntent.ADDRESS, address);
+ intent.putExtra(BluetoothIntent.BOND_STATE, state);
+ intent.putExtra(BluetoothIntent.BOND_PREVIOUS_STATE, oldState);
+ if (state == BluetoothDevice.BOND_NOT_BONDED) {
+ if (reason <= 0) {
+ Log.w(TAG, "setBondState() called to unbond device with invalid reason code " +
+ "Setting reason = BOND_RESULT_REMOVED");
+ reason = BluetoothDevice.UNBOND_REASON_REMOVED;
+ }
+ intent.putExtra(BluetoothIntent.REASON, reason);
+ mState.remove(address);
+ } else {
+ mState.put(address, state);
+ }
+ if (state == BluetoothDevice.BOND_BONDING) {
+ mPinAttempt.put(address, Integer.valueOf(0));
+ } else {
+ mPinAttempt.remove(address);
+ }
+ mContext.sendBroadcast(intent, BLUETOOTH_PERM);
+ }
+
+ public synchronized int getBondState(String address) {
+ Integer state = mState.get(address);
+ if (state == null) {
+ return BluetoothDevice.BOND_NOT_BONDED;
+ }
+ return state.intValue();
+ }
+
+ public synchronized String[] listBonds() {
+ ArrayList<String> result = new ArrayList<String>(mState.size());
+ for (Map.Entry<String, Integer> e : mState.entrySet()) {
+ if (e.getValue().intValue() == BluetoothDevice.BOND_BONDED) {
+ result.add(e.getKey());
+ }
+ }
+ return result.toArray(new String[result.size()]);
+ }
+
+ public synchronized int getAttempt(String address) {
+ Integer attempt = mPinAttempt.get(address);
+ if (attempt == null) {
+ return 0;
+ }
+ return attempt.intValue();
+ }
+
+ public synchronized void attempt(String address) {
+ Integer attempt = mPinAttempt.get(address);
+ if (attempt == null) {
+ return;
+ }
+ mPinAttempt.put(address, new Integer(attempt.intValue() + 1));
+ }
+
+ }
+ private native String[] listBondingsNative();
+
+ private static String toBondStateString(int bondState) {
+ switch (bondState) {
+ case BluetoothDevice.BOND_NOT_BONDED:
+ return "not bonded";
+ case BluetoothDevice.BOND_BONDING:
+ return "bonding";
+ case BluetoothDevice.BOND_BONDED:
+ return "bonded";
+ default:
+ return "??????";
+ }
+ }
+
public synchronized String getAddress() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
return getAddressNative();
@@ -231,12 +353,6 @@
}
private native boolean setNameNative(String name);
- public synchronized String[] listBondings() {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- return listBondingsNative();
- }
- private native String[] listBondingsNative();
-
public synchronized String getMajorClass() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
return getMajorClassNative();
@@ -551,106 +667,45 @@
}
private native boolean disconnectRemoteDeviceNative(String address);
- private static final int MAX_OUTSTANDING_ASYNC = 32;
- /**
- * This method initiates a Bonding request to a remote device.
- *
- *
- * @param address The Bluetooth address of the remote device
- *
- * @see #createBonding
- * @see #cancelBondingProcess
- * @see #removeBonding
- * @see #hasBonding
- * @see #listBondings
- *
- * @see android.bluetooth.PasskeyAgent
- */
- public synchronized boolean createBonding(String address, IBluetoothDeviceCallback callback) {
+ public synchronized boolean createBond(String address) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH_ADMIN permission");
if (!BluetoothDevice.checkBluetoothAddress(address)) {
return false;
}
-
- HashMap<String, IBluetoothDeviceCallback> callbacks = mEventLoop.getCreateBondingCallbacks();
- if (callbacks.containsKey(address)) {
- Log.w(TAG, "createBonding() already in progress for " + address);
+ address = address.toUpperCase();
+ if (mBondState.getBondState(address) != BluetoothDevice.BOND_NOT_BONDED) {
return false;
}
- // Protect from malicious clients - limit number of outstanding requests
- if (callbacks.size() > MAX_OUTSTANDING_ASYNC) {
- Log.w(TAG, "Too many outstanding bonding requests, dropping request for " + address);
- return false;
- }
-
- callbacks.put(address, callback);
if (!createBondingNative(address, 60000 /* 1 minute */)) {
- callbacks.remove(address);
return false;
}
- mOutgoingBondingDevAddress = address;
+
+ mBondState.setBondState(address, BluetoothDevice.BOND_BONDING);
return true;
}
-
private native boolean createBondingNative(String address, int timeout_ms);
-
- /*package*/ String getOutgoingBondingDevAddress() {
- return mOutgoingBondingDevAddress;
- }
- /*package*/ void setOutgoingBondingDevAddress(String outgoingBondingDevAddress) {
- mOutgoingBondingDevAddress = outgoingBondingDevAddress;
- }
-
- /**
- * This method cancels a pending bonding request.
- *
- * @param address The Bluetooth address of the remote device to which a
- * bonding request has been initiated.
- *
- * Note: When a request is canceled, method
- * {@link CreateBondingResultNotifier#notifyAuthenticationFailed}
- * will be called on the object passed to method
- * {@link #createBonding}.
- *
- * Note: it is safe to call this method when there is no outstanding
- * bonding request.
- *
- * @see #createBonding
- * @see #cancelBondingProcess
- * @see #removeBonding
- * @see #hasBonding
- * @see #listBondings
- */
- public synchronized boolean cancelBondingProcess(String address) {
+ public synchronized boolean cancelBondProcess(String address) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH_ADMIN permission");
if (!BluetoothDevice.checkBluetoothAddress(address)) {
return false;
}
- return cancelBondingProcessNative(address);
+ address = address.toUpperCase();
+ if (mBondState.getBondState(address) != BluetoothDevice.BOND_BONDING) {
+ return false;
+ }
+
+ mBondState.setBondState(address, BluetoothDevice.BOND_NOT_BONDED,
+ BluetoothDevice.UNBOND_REASON_CANCELLED);
+ cancelBondingProcessNative(address);
+ return true;
}
private native boolean cancelBondingProcessNative(String address);
- /**
- * This method removes a bonding to a remote device. This is a local
- * operation only, resulting in this adapter "forgetting" the bonding
- * information about the specified remote device. The other device itself
- * does not know what the bonding has been torn down. The next time either
- * device attemps to connect to the other, the connection will fail, and
- * the pairing procedure will have to be re-initiated.
- *
- * @param address The Bluetooth address of the remote device.
- *
- * @see #createBonding
- * @see #cancelBondingProcess
- * @see #removeBonding
- * @see #hasBonding
- * @see #listBondings
- */
- public synchronized boolean removeBonding(String address) {
+ public synchronized boolean removeBond(String address) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH_ADMIN permission");
if (!BluetoothDevice.checkBluetoothAddress(address)) {
@@ -660,14 +715,18 @@
}
private native boolean removeBondingNative(String address);
- public synchronized boolean hasBonding(String address) {
+ public synchronized String[] listBonds() {
+ mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ return mBondState.listBonds();
+ }
+
+ public synchronized int getBondState(String address) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
if (!BluetoothDevice.checkBluetoothAddress(address)) {
- return false;
+ return BluetoothError.ERROR;
}
- return hasBondingNative(address);
+ return mBondState.getBondState(address.toUpperCase());
}
- private native boolean hasBondingNative(String address);
public synchronized String[] listAclConnections() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
@@ -1016,6 +1075,8 @@
}
private native byte[] getRemoteServiceRecordNative(String address, int handle);
+ private static final int MAX_OUTSTANDING_ASYNC = 32;
+
// AIDL does not yet support short's
public synchronized boolean getRemoteServiceChannel(String address, int uuid16,
IBluetoothDeviceCallback callback) {
@@ -1051,6 +1112,7 @@
!BluetoothDevice.checkBluetoothAddress(address)) {
return false;
}
+ address = address.toUpperCase();
Integer data = mEventLoop.getPasskeyAgentRequestData().remove(address);
if (data == null) {
Log.w(TAG, "setPin(" + address + ") called but no native data available, " +
@@ -1076,6 +1138,7 @@
if (!BluetoothDevice.checkBluetoothAddress(address)) {
return false;
}
+ address = address.toUpperCase();
Integer data = mEventLoop.getPasskeyAgentRequestData().remove(address);
if (data == null) {
Log.w(TAG, "cancelPin(" + address + ") called but no native data available, " +
@@ -1143,25 +1206,20 @@
BluetoothHeadset headset = new BluetoothHeadset(mContext, null);
- pw.println("\n--Bondings--");
- String[] addresses = listBondings();
+ String[] addresses = listRemoteDevices();
+
+ pw.println("\n--Known devices--");
for (String address : addresses) {
- String name = getRemoteName(address);
- pw.println(address + " (" + name + ")");
+ pw.printf("%s %10s (%d) %s\n", address,
+ toBondStateString(mBondState.getBondState(address)),
+ mBondState.getAttempt(address),
+ getRemoteName(address));
}
- pw.println("\n--Current ACL Connections--");
addresses = listAclConnections();
+ pw.println("\n--ACL connected devices--");
for (String address : addresses) {
- String name = getRemoteName(address);
- pw.println(address + " (" + name + ")");
- }
-
- pw.println("\n--Known Devices--");
- addresses = listRemoteDevices();
- for (String address : addresses) {
- String name = getRemoteName(address);
- pw.println(address + " (" + name + ")");
+ pw.println(address);
}
// Rather not do this from here, but no-where else and I need this
@@ -1189,4 +1247,8 @@
}
pw.println("\nmIsAirplaneSensitive = " + mIsAirplaneSensitive);
}
+
+ private static void log(String msg) {
+ Log.d(TAG, msg);
+ }
}
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 2d8aacc..4f63f98 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -16,8 +16,9 @@
package android.server;
-import android.bluetooth.BluetoothClass.Device;
+import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothError;
import android.bluetooth.BluetoothIntent;
import android.bluetooth.IBluetoothDeviceCallback;
import android.content.Context;
@@ -41,11 +42,9 @@
private int mNativeData;
private Thread mThread;
private boolean mInterrupted;
- private HashMap<String, IBluetoothDeviceCallback> mCreateBondingCallbacks;
private HashMap<String, Integer> mPasskeyAgentRequestData;
private HashMap<String, IBluetoothDeviceCallback> mGetRemoteServiceChannelCallbacks;
- private HashMap<String, Boolean> mDefaultPinData;
- private BluetoothDeviceService mBluetoothService;
+ private BluetoothDeviceService mBluetoothService;
private Context mContext;
private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
@@ -57,10 +56,8 @@
/* pacakge */ BluetoothEventLoop(Context context, BluetoothDeviceService bluetoothService) {
mBluetoothService = bluetoothService;
mContext = context;
- mCreateBondingCallbacks = new HashMap();
mPasskeyAgentRequestData = new HashMap();
mGetRemoteServiceChannelCallbacks = new HashMap();
- mDefaultPinData = new HashMap();
initializeNativeDataNative();
}
private native void initializeNativeDataNative();
@@ -74,9 +71,6 @@
}
private native void cleanupNativeDataNative();
- /* pacakge */ HashMap<String, IBluetoothDeviceCallback> getCreateBondingCallbacks() {
- return mCreateBondingCallbacks;
- }
/* pacakge */ HashMap<String, IBluetoothDeviceCallback> getRemoteServiceChannelCallbacks() {
return mGetRemoteServiceChannelCallbacks;
}
@@ -235,33 +229,24 @@
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
}
- private void onCreateBondingResult(String address, boolean result) {
- mBluetoothService.setOutgoingBondingDevAddress(null);
- IBluetoothDeviceCallback callback = mCreateBondingCallbacks.get(address);
- if (callback != null) {
- try {
- callback.onCreateBondingResult(address,
- result ? BluetoothDevice.RESULT_SUCCESS :
- BluetoothDevice.RESULT_FAILURE);
- } catch (RemoteException e) {}
- mCreateBondingCallbacks.remove(address);
- }
+ private void onCreateBondingResult(String address, int result) {
+ address = address.toUpperCase();
+ if (result == BluetoothError.SUCCESS) {
+ mBluetoothService.getBondState().setBondState(address, BluetoothDevice.BOND_BONDED);
+ } else {
+ mBluetoothService.getBondState().setBondState(address,
+ BluetoothDevice.BOND_NOT_BONDED, result);
+ }
}
-
- public void onBondingCreated(String address) {
- Intent intent = new Intent(BluetoothIntent.BONDING_CREATED_ACTION);
- intent.putExtra(BluetoothIntent.ADDRESS, address);
- mContext.sendBroadcast(intent, BLUETOOTH_PERM);
- }
-
- public void onBondingRemoved(String address) {
- Intent intent = new Intent(BluetoothIntent.BONDING_REMOVED_ACTION);
- intent.putExtra(BluetoothIntent.ADDRESS, address);
- mContext.sendBroadcast(intent, BLUETOOTH_PERM);
- if (mDefaultPinData.containsKey(address)) {
- mDefaultPinData.remove(address);
- }
+ public void onBondingCreated(String address) {
+ mBluetoothService.getBondState().setBondState(address.toUpperCase(),
+ BluetoothDevice.BOND_BONDED);
+ }
+
+ public void onBondingRemoved(String address) {
+ mBluetoothService.getBondState().setBondState(address.toUpperCase(),
+ BluetoothDevice.BOND_NOT_BONDED, BluetoothDevice.UNBOND_REASON_REMOVED);
}
public void onNameChanged(String name) {
@@ -271,24 +256,24 @@
}
public void onPasskeyAgentRequest(String address, int nativeData) {
- mPasskeyAgentRequestData.put(address, new Integer(nativeData));
-
- if (address.equals(mBluetoothService.getOutgoingBondingDevAddress())) {
- int btClass = mBluetoothService.getRemoteClass(address);
- int remoteDeviceClass = Device.getDevice(btClass);
- if (remoteDeviceClass == Device.AUDIO_VIDEO_WEARABLE_HEADSET ||
- remoteDeviceClass == Device.AUDIO_VIDEO_HANDSFREE ||
- remoteDeviceClass == Device.AUDIO_VIDEO_HEADPHONES ||
- remoteDeviceClass == Device.AUDIO_VIDEO_PORTABLE_AUDIO ||
- remoteDeviceClass == Device.AUDIO_VIDEO_CAR_AUDIO ||
- remoteDeviceClass == Device.AUDIO_VIDEO_HIFI_AUDIO) {
- if (!mDefaultPinData.containsKey(address)) {
- mDefaultPinData.put(address, false);
- }
- if (!mDefaultPinData.get(address)) {
- mDefaultPinData.remove(address);
- mDefaultPinData.put(address, true);
+ address = address.toUpperCase();
+ mPasskeyAgentRequestData.put(address, new Integer(nativeData));
+ if (mBluetoothService.getBondState().getBondState(address) ==
+ BluetoothDevice.BOND_BONDING) {
+ // we initiated the bonding
+ int btClass = mBluetoothService.getRemoteClass(address);
+
+ // try 0000 once if the device looks dumb
+ switch (BluetoothClass.Device.getDevice(btClass)) {
+ case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
+ case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
+ case BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES:
+ case BluetoothClass.Device.AUDIO_VIDEO_PORTABLE_AUDIO:
+ case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
+ case BluetoothClass.Device.AUDIO_VIDEO_HIFI_AUDIO:
+ if (mBluetoothService.getBondState().getAttempt(address) < 1) {
+ mBluetoothService.getBondState().attempt(address);
mBluetoothService.setPin(address, BluetoothDevice.convertPinToBytes("0000"));
return;
}
@@ -298,18 +283,17 @@
intent.putExtra(BluetoothIntent.ADDRESS, address);
mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
}
-
+
public void onPasskeyAgentCancel(String address) {
+ address = address.toUpperCase();
mPasskeyAgentRequestData.remove(address);
- if (mDefaultPinData.containsKey(address)) {
- mDefaultPinData.remove(address);
- mDefaultPinData.put(address, false);
- }
Intent intent = new Intent(BluetoothIntent.PAIRING_CANCEL_ACTION);
intent.putExtra(BluetoothIntent.ADDRESS, address);
mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
+ mBluetoothService.getBondState().setBondState(address, BluetoothDevice.BOND_NOT_BONDED,
+ BluetoothDevice.UNBOND_REASON_CANCELLED);
}
-
+
private void onGetRemoteServiceChannelResult(String address, int channel) {
IBluetoothDeviceCallback callback = mGetRemoteServiceChannelCallbacks.get(address);
if (callback != null) {
diff --git a/core/java/android/server/search/SearchableInfo.java b/core/java/android/server/search/SearchableInfo.java
index ac4cdb9..c8f395e 100644
--- a/core/java/android/server/search/SearchableInfo.java
+++ b/core/java/android/server/search/SearchableInfo.java
@@ -704,6 +704,7 @@
* positioned at the location in the buffer where it was written.
*/
public SearchableInfo(Parcel in) {
+ mSearchable = in.readInt() != 0;
mLabelId = in.readInt();
mSearchActivity = ComponentName.readFromParcel(in);
mHintId = in.readInt();
@@ -733,6 +734,7 @@
}
public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mSearchable ? 1 : 0);
dest.writeInt(mLabelId);
mSearchActivity.writeToParcel(dest, flags);
dest.writeInt(mHintId);
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 64356d5..405d934 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -659,8 +659,8 @@
p.writeInt(0);
}
- p.writeInt(tas.getTextSize());
p.writeInt(tas.getTextStyle());
+ p.writeInt(tas.getTextSize());
ColorStateList csl = tas.getTextColor();
if (csl == null) {
@@ -799,8 +799,8 @@
p.readInt() != 0
? p.readString()
: null,
- p.readInt(),
- p.readInt(),
+ p.readInt(), // style
+ p.readInt(), // size
p.readInt() != 0
? ColorStateList.CREATOR.createFromParcel(p)
: null,
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index a6def51..6af4915 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -21,6 +21,7 @@
import android.graphics.Rect;
import android.os.IBinder;
import android.os.LocalPowerManager;
+import android.view.animation.Animation;
/**
* This interface supplies all UI-specific behavior of the window manager. An
@@ -247,6 +248,13 @@
public WindowState getAppStartingWindow();
/**
+ * Is this window visible? It is not visible if there is no
+ * surface, or we are in the process of running an exit animation
+ * that will remove the surface.
+ */
+ boolean isVisibleLw();
+
+ /**
* Is this window currently visible to the user on-screen? It is
* displayed either if it is visible or it is currently running an
* animation before no longer being visible. Must be called with the
@@ -282,7 +290,7 @@
* regardless of whether the client or window manager would like
* it shown. Must be called with the window manager lock held.
*/
- public void hideLw();
+ public void hideLw(boolean doAnimation);
/**
* Can be called to undo the effect of {@link #hideLw}, allowing a
@@ -290,7 +298,7 @@
* also like it to be shown. Must be called with the window manager
* lock held.
*/
- public void showLw();
+ public void showLw(boolean doAnimation);
}
/** No transition happening. */
diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java
index 27461ff..bd7b050 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -177,6 +177,19 @@
public boolean commitCompletion(CompletionInfo text);
/**
+ * Tell the editor that you are starting a batch of editor operations.
+ * The editor will try to avoid sending you updates about its state
+ * until {@link #endBatchEdit} is called.
+ */
+ public boolean beginBatchEdit();
+
+ /**
+ * Tell the editor that you are done with a batch edit previously
+ * initiated with {@link #endBatchEdit}.
+ */
+ public boolean endBatchEdit();
+
+ /**
* Send a key event to the process that is currently attached through
* this input connection. The event will be dispatched like a normal
* key event, to the currently focused; this generally is the view that
diff --git a/core/java/android/view/inputmethod/InputConnectionWrapper.java b/core/java/android/view/inputmethod/InputConnectionWrapper.java
index a41955c..f65b2a1 100644
--- a/core/java/android/view/inputmethod/InputConnectionWrapper.java
+++ b/core/java/android/view/inputmethod/InputConnectionWrapper.java
@@ -77,6 +77,14 @@
return mBase.commitCompletion(text);
}
+ public boolean beginBatchEdit() {
+ return mBase.beginBatchEdit();
+ }
+
+ public boolean endBatchEdit() {
+ return mBase.endBatchEdit();
+ }
+
public boolean sendKeyEvent(KeyEvent event) {
return mBase.sendKeyEvent(event);
}
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index ba40782..a9a9594 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -293,6 +293,14 @@
return false;
}
+ public boolean beginBatchEdit() {
+ return false;
+ }
+
+ public boolean endBatchEdit() {
+ return false;
+ }
+
public boolean commitCompletion(CompletionInfo text) {
return false;
}
@@ -401,6 +409,12 @@
};
final InputConnection mDummyInputConnection = new BaseInputConnection(this) {
+ public boolean beginBatchEdit() {
+ return false;
+ }
+ public boolean endBatchEdit() {
+ return false;
+ }
public boolean commitText(CharSequence text, int newCursorPosition) {
return false;
}
diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java
index c45ab29..3f2bbe5 100644
--- a/core/java/android/webkit/LoadListener.java
+++ b/core/java/android/webkit/LoadListener.java
@@ -167,7 +167,7 @@
* should do with them.
*/
if (mNativeLoader != 0) {
- commitHeaders();
+ commitHeadersCheckRedirect();
}
break;
@@ -458,11 +458,6 @@
if (Config.LOGV) {
Log.v(LOGTAG, "LoadListener.data(): url: " + url());
}
-
- if (ignoreCallbacks()) {
- return;
- }
-
// Decode base64 data
// Note: It's fine that we only decode base64 here and not in the other
// data call because the only caller of the stream version is not
@@ -484,7 +479,7 @@
sendMessage = mDataBuilder.isEmpty();
mDataBuilder.append(data, 0, length);
}
- if (sendMessage) {
+ if (sendMessage && !ignoreCallbacks()) {
// Send a message whenever data comes in after a write to WebCore
sendMessageInternal(obtainMessage(MSG_CONTENT_DATA));
}
@@ -850,7 +845,8 @@
return mContentLength;
}
- private void commitHeaders() {
+ // Commit the headers if the status code is not a redirect.
+ private void commitHeadersCheckRedirect() {
if (mCancelled) return;
// do not call webcore if it is redirect. According to the code in
@@ -860,6 +856,11 @@
return;
}
+ commitHeaders();
+ }
+
+ // This commits the headers without checking the response status code.
+ private void commitHeaders() {
// Commit the headers to WebCore
int nativeResponse = createNativeResponse();
// The native code deletes the native response object.
@@ -1075,7 +1076,11 @@
}
}
} else {
- cancel();
+ // With a null redirect, commit the original headers, the buffered
+ // data, and then finish the load.
+ commitHeaders();
+ commitLoad();
+ nativeFinished();
}
if (Config.LOGV) {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 9cfc622..cab278be 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -288,10 +288,6 @@
// The time that the Zoom Controls are visible before fading away
private static final long ZOOM_CONTROLS_TIMEOUT =
ViewConfiguration.getZoomControlsTimeout();
- // Wait a short time before sending kit focus message, in case
- // the user is still moving around, to avoid rebuilding the display list
- // prematurely
- private static final long SET_KIT_FOCUS_DELAY = 250;
// The amount of content to overlap between two screens when going through
// pages with the space bar, in pixels.
private static final int PAGE_SCROLL_OVERLAP = 24;
@@ -4725,8 +4721,7 @@
// called by JNI
private void sendKitFocus() {
WebViewCore.FocusData focusData = new WebViewCore.FocusData(mFocusData);
- mWebViewCore.sendMessageDelayed(EventHub.SET_KIT_FOCUS, focusData,
- SET_KIT_FOCUS_DELAY);
+ mWebViewCore.sendMessage(EventHub.SET_KIT_FOCUS, focusData);
}
// called by JNI
diff --git a/core/java/android/widget/Button.java b/core/java/android/widget/Button.java
index f2868af..5e692d4 100644
--- a/core/java/android/widget/Button.java
+++ b/core/java/android/widget/Button.java
@@ -21,6 +21,7 @@
import android.util.Log;
import android.view.MotionEvent;
import android.view.KeyEvent;
+import android.widget.RemoteViews.RemoteView;
/**
@@ -54,6 +55,7 @@
* {@link android.R.styleable#View View Attributes}
* </p>
*/
+@RemoteView
public class Button extends TextView {
public Button(Context context) {
this(context, null);
diff --git a/core/java/android/widget/ImageButton.java b/core/java/android/widget/ImageButton.java
index 5c56428..4c1cbf6 100644
--- a/core/java/android/widget/ImageButton.java
+++ b/core/java/android/widget/ImageButton.java
@@ -21,6 +21,7 @@
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
+import android.widget.RemoteViews.RemoteView;
import java.util.Map;
@@ -36,6 +37,7 @@
* {@link android.R.styleable#View View Attributes}
* </p>
*/
+@RemoteView
public class ImageButton extends ImageView {
public ImageButton(Context context) {
this(context, null);
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 54951b7..5721095 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -16,6 +16,8 @@
package android.widget;
+import android.app.PendingIntent;
+import android.app.PendingIntent.CanceledException;
import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
@@ -31,6 +33,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.LayoutInflater.Filter;
+import android.view.View.OnClickListener;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -371,6 +374,52 @@
public final static int TAG = 6;
}
+
+ /**
+ * Equivalent to calling
+ * {@link android.view.View#setOnClickListener(android.view.View.OnClickListener)}
+ * to launch the provided {@link PendingIntent}.
+ */
+ private class SetOnClickPendingIntent extends Action {
+ public SetOnClickPendingIntent(int id, PendingIntent pendingIntent) {
+ this.viewId = id;
+ this.pendingIntent = pendingIntent;
+ }
+
+ public SetOnClickPendingIntent(Parcel parcel) {
+ viewId = parcel.readInt();
+ pendingIntent = PendingIntent.readPendingIntentOrNullFromParcel(parcel);
+ }
+
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(TAG);
+ dest.writeInt(viewId);
+ pendingIntent.writeToParcel(dest, 0 /* no flags */);
+ }
+
+ @Override
+ public void apply(View root) {
+ final View target = root.findViewById(viewId);
+ if (target != null && pendingIntent != null) {
+ OnClickListener listener = new OnClickListener() {
+ public void onClick(View v) {
+ try {
+ // TODO: Unregister this handler if PendingIntent.FLAG_ONE_SHOT?
+ pendingIntent.send();
+ } catch (CanceledException e) {
+ throw new ActionException(e.toString());
+ }
+ }
+ };
+ target.setOnClickListener(listener);
+ }
+ }
+
+ int viewId;
+ PendingIntent pendingIntent;
+
+ public final static int TAG = 7;
+ }
/**
* Create a new RemoteViews object that will display the views contained
@@ -419,6 +468,9 @@
case SetProgressBar.TAG:
mActions.add(new SetProgressBar(parcel));
break;
+ case SetOnClickPendingIntent.TAG:
+ mActions.add(new SetOnClickPendingIntent(parcel));
+ break;
default:
throw new ActionException("Tag " + tag + "not found");
}
@@ -491,8 +543,6 @@
*
* @param viewId The id of the view whose drawable should change
* @param bitmap The new Bitmap for the drawable
- *
- * @hide pending API Council approval to extend the public API
*/
public void setImageViewBitmap(int viewId, Bitmap bitmap) {
addAction(new SetImageViewBitmap(viewId, bitmap));
@@ -533,6 +583,18 @@
}
/**
+ * Equivalent to calling
+ * {@link android.view.View#setOnClickListener(android.view.View.OnClickListener)}
+ * to launch the provided {@link PendingIntent}.
+ *
+ * @param viewId The id of the view that will trigger the {@link PendingIntent} when clicked
+ * @param pendingIntent The {@link PendingIntent} to send when user clicks
+ */
+ public void setOnClickPendingIntent(int viewId, PendingIntent pendingIntent) {
+ addAction(new SetOnClickPendingIntent(viewId, pendingIntent));
+ }
+
+ /**
* Inflates the view hierarchy represented by this object and applies
* all of the actions.
*
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 8baed7d..aa70663 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -235,6 +235,7 @@
float[] mTmpOffset = new float[2];
ExtractedTextRequest mExtracting;
final ExtractedText mTmpExtracted = new ExtractedText();
+ boolean mBatchEditing;
}
InputMethodState mInputMethodState;
@@ -3505,7 +3506,8 @@
*/
InputMethodManager imm = InputMethodManager.peekInstance();
- if (highlight != null && mInputMethodState != null && imm != null) {
+ if (highlight != null && mInputMethodState != null
+ && !mInputMethodState.mBatchEditing && imm != null) {
if (imm.isActive(this)) {
int candStart = -1;
int candEnd = -1;
@@ -3865,6 +3867,38 @@
}
/**
+ * Called by the framework in response to a request to begin a batch
+ * of edit operations from the current input method, as a result of
+ * it calling {@link InputConnection#beginBatchEdit
+ * InputConnection.beginBatchEdit()}. The default implementation sets
+ * up the TextView's internal state to take care of this; if overriding
+ * you should call through to the super class.
+ */
+ public void onBeginBatchEdit() {
+ if (mInputMethodState != null) {
+ // XXX we should be smarter here, such as not doing invalidates
+ // until all edits are done.
+ mInputMethodState.mBatchEditing = true;
+ }
+ }
+
+ /**
+ * Called by the framework in response to a request to end a batch
+ * of edit operations from the current input method, as a result of
+ * it calling {@link InputConnection#endBatchEdit
+ * InputConnection.endBatchEdit()}. The default implementation sets
+ * up the TextView's internal state to take care of this; if overriding
+ * you should call through to the super class.
+ */
+ public void onEndBatchEdit() {
+ if (mInputMethodState != null) {
+ mInputMethodState.mBatchEditing = false;
+ // Cheezy way to get us to report the current cursor location.
+ invalidateCursor();
+ }
+ }
+
+ /**
* Called by the framework in response to a private command from the
* current method, provided by it calling
* {@link InputConnection#performPrivateCommand
@@ -5271,6 +5305,8 @@
if (mError != null) {
hideError();
}
+ // Don't leave us in the middle of a batch edit.
+ onEndBatchEdit();
}
startStopMarquee(focused);
@@ -5300,6 +5336,8 @@
if (mBlink != null) {
mBlink.cancel();
}
+ // Don't leave us in the middle of a batch edit.
+ onEndBatchEdit();
}
startStopMarquee(hasWindowFocus);
diff --git a/core/java/com/android/internal/gadget/IGadgetService.aidl b/core/java/com/android/internal/gadget/IGadgetService.aidl
index 0117d1d..6f9af04 100644
--- a/core/java/com/android/internal/gadget/IGadgetService.aidl
+++ b/core/java/com/android/internal/gadget/IGadgetService.aidl
@@ -25,4 +25,5 @@
void deleteGadgetId(int gadgetId);
void bindGadgetId(int gadgetId, in ComponentName provider);
GadgetInfo getGadgetInfo(int gadgetId);
+ List<GadgetInfo> getInstalledProviders();
}
diff --git a/core/java/com/android/internal/view/IInputConnectionWrapper.java b/core/java/com/android/internal/view/IInputConnectionWrapper.java
index d604259..011e944 100644
--- a/core/java/com/android/internal/view/IInputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/IInputConnectionWrapper.java
@@ -26,6 +26,8 @@
private static final int DO_FINISH_COMPOSING_TEXT = 65;
private static final int DO_SEND_KEY_EVENT = 70;
private static final int DO_DELETE_SURROUNDING_TEXT = 80;
+ private static final int DO_BEGIN_BATCH_EDIT = 90;
+ private static final int DO_END_BATCH_EDIT = 95;
private static final int DO_HIDE_STATUS_ICON = 100;
private static final int DO_SHOW_STATUS_ICON = 110;
private static final int DO_PERFORM_PRIVATE_COMMAND = 120;
@@ -107,6 +109,14 @@
leftLength, rightLength));
}
+ public void beginBatchEdit() {
+ dispatchMessage(obtainMessage(DO_BEGIN_BATCH_EDIT));
+ }
+
+ public void endBatchEdit() {
+ dispatchMessage(obtainMessage(DO_END_BATCH_EDIT));
+ }
+
public void hideStatusIcon() {
dispatchMessage(obtainMessage(DO_HIDE_STATUS_ICON));
}
@@ -202,6 +212,14 @@
mInputConnection.deleteSurroundingText(msg.arg1, msg.arg2);
return;
}
+ case DO_BEGIN_BATCH_EDIT: {
+ mInputConnection.beginBatchEdit();
+ return;
+ }
+ case DO_END_BATCH_EDIT: {
+ mInputConnection.beginBatchEdit();
+ return;
+ }
case DO_HIDE_STATUS_ICON: {
mInputConnection.hideStatusIcon();
return;
diff --git a/core/java/com/android/internal/view/IInputContext.aidl b/core/java/com/android/internal/view/IInputContext.aidl
index 55a9784..b048ce2 100644
--- a/core/java/com/android/internal/view/IInputContext.aidl
+++ b/core/java/com/android/internal/view/IInputContext.aidl
@@ -48,6 +48,10 @@
void commitCompletion(in CompletionInfo completion);
+ void beginBatchEdit();
+
+ void endBatchEdit();
+
void sendKeyEvent(in KeyEvent event);
void clearMetaKeyStates(int states);
diff --git a/core/java/com/android/internal/view/InputConnectionWrapper.java b/core/java/com/android/internal/view/InputConnectionWrapper.java
index 1cfaf17..a9ba5f6 100644
--- a/core/java/com/android/internal/view/InputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/InputConnectionWrapper.java
@@ -259,6 +259,24 @@
}
}
+ public boolean beginBatchEdit() {
+ try {
+ mIInputContext.beginBatchEdit();
+ return true;
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ public boolean endBatchEdit() {
+ try {
+ mIInputContext.endBatchEdit();
+ return true;
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
public boolean sendKeyEvent(KeyEvent event) {
try {
mIInputContext.sendKeyEvent(event);
diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java
index 263220b..a2673a5 100644
--- a/core/java/com/android/internal/widget/EditableInputConnection.java
+++ b/core/java/com/android/internal/widget/EditableInputConnection.java
@@ -242,6 +242,18 @@
return true;
}
+ public boolean beginBatchEdit() {
+ if (mTextView == null) return false;
+ mTextView.onBeginBatchEdit();
+ return true;
+ }
+
+ public boolean endBatchEdit() {
+ if (mTextView == null) return false;
+ mTextView.onEndBatchEdit();
+ return true;
+ }
+
public boolean clearMetaKeyStates(int states) {
final Editable content = getEditable();
if (content == null) return false;
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 329a695..65f44d5 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -507,6 +507,18 @@
}
}
+static void Bitmap_copyPixelsFromBuffer(JNIEnv* env, jobject,
+ const SkBitmap* bitmap, jobject jbuffer) {
+ SkAutoLockPixels alp(*bitmap);
+ void* dst = bitmap->getPixels();
+
+ if (NULL != dst) {
+ android::AutoBufferPointer abp(env, jbuffer, JNI_FALSE);
+ // the java side has already checked that buffer is large enough
+ memcpy(dst, abp.pointer(), bitmap->getSize());
+ }
+}
+
///////////////////////////////////////////////////////////////////////////////
#include <android_runtime/AndroidRuntime.h>
@@ -538,7 +550,9 @@
{ "nativeSetPixel", "(IIII)V", (void*)Bitmap_setPixel },
{ "nativeSetPixels", "(I[IIIIIII)V", (void*)Bitmap_setPixels },
{ "nativeCopyPixelsToBuffer", "(ILjava/nio/Buffer;)V",
- (void*)Bitmap_copyPixelsToBuffer }
+ (void*)Bitmap_copyPixelsToBuffer },
+ { "nativeCopyPixelsFromBuffer", "(ILjava/nio/Buffer;)V",
+ (void*)Bitmap_copyPixelsFromBuffer }
};
#define kClassPathName "android/graphics/Bitmap"
@@ -546,16 +560,7 @@
int register_android_graphics_Bitmap(JNIEnv* env);
int register_android_graphics_Bitmap(JNIEnv* env)
{
-#if 1
return android::AndroidRuntime::registerNativeMethods(env, kClassPathName,
gBitmapMethods, SK_ARRAY_COUNT(gBitmapMethods));
-#else
- short n = 0;
- int limit = (char*)env - (char*)0;
- for (int i = 0; i < limit; i++) {
- n += i*i;
- }
- return n;
-#endif
}
diff --git a/core/jni/android_server_BluetoothDeviceService.cpp b/core/jni/android_server_BluetoothDeviceService.cpp
index 3ff6af1..61a4a26 100644
--- a/core/jni/android_server_BluetoothDeviceService.cpp
+++ b/core/jni/android_server_BluetoothDeviceService.cpp
@@ -378,12 +378,12 @@
LOGV(__FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
- DBusMessage *reply =
+ DBusMessage *reply =
dbus_func_args(env, nat->conn, nat->adapter,
DBUS_CLASS_NAME, "GetDiscoverableTimeout",
DBUS_TYPE_INVALID);
return reply ? dbus_returns_uint32(env, reply) : -1;
- }
+ }
#endif
return -1;
}
@@ -394,7 +394,7 @@
native_data_t *nat = get_native_data(env, object);
if (nat) {
const char *c_address = env->GetStringUTFChars(address, NULL);
- DBusMessage *reply =
+ DBusMessage *reply =
dbus_func_args(env, nat->conn, nat->adapter,
DBUS_CLASS_NAME, "IsConnected",
DBUS_TYPE_STRING, &c_address,
@@ -412,12 +412,12 @@
native_data_t *nat = get_native_data(env, object);
if (nat) {
const char *c_address = env->GetStringUTFChars(address, NULL);
- // Set a timeout of 5 seconds. Specifying the default timeout is
- // not long enough, as a remote-device disconnect results in
- // signal RemoteDisconnectRequested being sent, followed by a
+ // Set a timeout of 5 seconds. Specifying the default timeout is
+ // not long enough, as a remote-device disconnect results in
+ // signal RemoteDisconnectRequested being sent, followed by a
// delay of 2 seconds, after which the actual disconnect takes
// place.
- DBusMessage *reply =
+ DBusMessage *reply =
dbus_func_args_timeout(env, nat->conn, 60000, nat->adapter,
DBUS_CLASS_NAME, "DisconnectRemoteDevice",
DBUS_TYPE_STRING, &c_address,
@@ -448,7 +448,7 @@
LOGV(__FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
- DBusMessage *reply =
+ DBusMessage *reply =
dbus_func_args(env, nat->conn, nat->adapter,
DBUS_CLASS_NAME, "IsDiscoverable",
DBUS_TYPE_INVALID);
@@ -463,7 +463,7 @@
LOGV(__FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
- DBusMessage *reply =
+ DBusMessage *reply =
dbus_func_args(env, nat->conn, nat->adapter,
DBUS_CLASS_NAME, "GetMode",
DBUS_TYPE_INVALID);
@@ -551,25 +551,6 @@
common_Bonding(env, object, -1, "RemoveBonding", address);
}
-static jboolean hasBondingNative(JNIEnv *env, jobject object, jstring address) {
-#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- const char *c_address = env->GetStringUTFChars(address, NULL);
- LOGV("... address = %s", c_address);
- DBusMessage *reply =
- dbus_func_args(env, nat->conn, nat->adapter,
- DBUS_CLASS_NAME, "HasBonding",
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(address, c_address);
- return reply ? dbus_returns_boolean(env, reply) : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
static jobjectArray listBondingsNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
LOGV(__FUNCTION__);
@@ -763,7 +744,7 @@
native_data_t *nat = get_native_data(env, obj);
if (nat) {
const char *c_address = env->GetStringUTFChars(address, NULL);
-
+
LOGV("... address = %s", c_address);
DBusMessage *reply = dbus_func_args(env, nat->conn, nat->adapter,
@@ -998,6 +979,7 @@
static jint enableNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
+ LOGV(__FUNCTION__);
return bt_enable();
#endif
return -1;
@@ -1005,6 +987,7 @@
static jint disableNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
+ LOGV(__FUNCTION__);
return bt_disable();
#endif
return -1;
@@ -1012,6 +995,7 @@
static jint isEnabledNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
+ LOGV(__FUNCTION__);
return bt_is_enabled();
#endif
return -1;
@@ -1113,7 +1097,6 @@
{"createBondingNative", "(Ljava/lang/String;I)Z", (void *)createBondingNative},
{"cancelBondingProcessNative", "(Ljava/lang/String;)Z", (void *)cancelBondingProcessNative},
{"listBondingsNative", "()[Ljava/lang/String;", (void *)listBondingsNative},
- {"hasBondingNative", "(Ljava/lang/String;)Z", (void *)hasBondingNative},
{"removeBondingNative", "(Ljava/lang/String;)Z", (void *)removeBondingNative},
{"getRemoteNameNative", "(Ljava/lang/String;)Ljava/lang/String;", (void *)getRemoteNameNative},
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index 1aef138..3468265 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -92,7 +92,7 @@
method_onBondingCreated = env->GetMethodID(clazz, "onBondingCreated", "(Ljava/lang/String;)V");
method_onBondingRemoved = env->GetMethodID(clazz, "onBondingRemoved", "(Ljava/lang/String;)V");
- method_onCreateBondingResult = env->GetMethodID(clazz, "onCreateBondingResult", "(Ljava/lang/String;Z)V");
+ method_onCreateBondingResult = env->GetMethodID(clazz, "onCreateBondingResult", "(Ljava/lang/String;I)V");
method_onPasskeyAgentRequest = env->GetMethodID(clazz, "onPasskeyAgentRequest", "(Ljava/lang/String;I)V");
method_onPasskeyAgentCancel = env->GetMethodID(clazz, "onPasskeyAgentCancel", "(Ljava/lang/String;)V");
@@ -609,6 +609,12 @@
}
#ifdef HAVE_BLUETOOTH
+//TODO: Unify result codes in a header
+#define BOND_RESULT_ERROR -1000
+#define BOND_RESULT_SUCCESS 0
+#define BOND_RESULT_AUTH_FAILED 1
+#define BOND_RESULT_AUTH_REJECTED 2
+#define BOND_RESULT_REMOTE_DEVICE_DOWN 3
void onCreateBondingResult(DBusMessage *msg, void *user) {
LOGV(__FUNCTION__);
@@ -619,11 +625,26 @@
LOGV("... address = %s", address);
- jboolean result = JNI_TRUE;
+ jint result = BOND_RESULT_SUCCESS;
if (dbus_set_error_from_message(&err, msg)) {
- /* if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationFailed")) */
- LOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message);
- result = JNI_FALSE;
+ if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationFailed")) {
+ // Pins did not match, or remote device did not respond to pin
+ // request in time
+ LOGV("... error = %s (%s)\n", err.name, err.message);
+ result = BOND_RESULT_AUTH_FAILED;
+ } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationRejected")) {
+ // We rejected pairing, or the remote side rejected pairing. This
+ // happens if either side presses 'cancel' at the pairing dialog.
+ LOGV("... error = %s (%s)\n", err.name, err.message);
+ result = BOND_RESULT_AUTH_REJECTED;
+ } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".ConnectionAttemptFailed")) {
+ // Other device is not responding at all
+ LOGV("... error = %s (%s)\n", err.name, err.message);
+ result = BOND_RESULT_REMOTE_DEVICE_DOWN;
+ } else {
+ LOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message);
+ result = BOND_RESULT_ERROR;
+ }
dbus_error_free(&err);
}
diff --git a/core/res/res/anim/status_bar_enter.xml b/core/res/res/anim/status_bar_enter.xml
new file mode 100644
index 0000000..2df1af4
--- /dev/null
+++ b/core/res/res/anim/status_bar_enter.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/anim/options_panel_enter.xml
+**
+** Copyright 2007, 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" android:interpolator="@anim/decelerate_interpolator">
+ <translate android:fromYDelta="-100%" android:toYDelta="0" android:duration="400"/>
+ <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="400" />
+</set>
diff --git a/core/res/res/anim/status_bar_exit.xml b/core/res/res/anim/status_bar_exit.xml
new file mode 100644
index 0000000..c72d014
--- /dev/null
+++ b/core/res/res/anim/status_bar_exit.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/anim/options_panel_exit.xml
+**
+** Copyright 2007, 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" android:interpolator="@anim/accelerate_interpolator">
+ <translate android:fromYDelta="0" android:toYDelta="-100%" android:duration="400"/>
+ <alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="400" />
+</set>
diff --git a/core/res/res/values-cs/arrays.xml b/core/res/res/values-cs/arrays.xml
deleted file mode 100644
index f9c904b..0000000
--- a/core/res/res/values-cs/arrays.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 61a2c29..76232de 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort">"B"</string>
diff --git a/core/res/res/values-de/arrays.xml b/core/res/res/values-de/arrays.xml
deleted file mode 100644
index f9c904b..0000000
--- a/core/res/res/values-de/arrays.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 44671e6..a8115a8 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort">"B"</string>
diff --git a/core/res/res/values-es/arrays.xml b/core/res/res/values-es/arrays.xml
deleted file mode 100644
index f9c904b..0000000
--- a/core/res/res/values-es/arrays.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 07a92fa..2ceea2c 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort">"B"</string>
diff --git a/core/res/res/values-fr/arrays.xml b/core/res/res/values-fr/arrays.xml
deleted file mode 100644
index f9c904b..0000000
--- a/core/res/res/values-fr/arrays.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 0f58ba1..ef826cb 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort">"O"</string>
diff --git a/core/res/res/values-it/arrays.xml b/core/res/res/values-it/arrays.xml
deleted file mode 100644
index f9c904b..0000000
--- a/core/res/res/values-it/arrays.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 8b96f89..caf63c7 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort">"B"</string>
diff --git a/core/res/res/values-ja/arrays.xml b/core/res/res/values-ja/arrays.xml
deleted file mode 100644
index f9c904b..0000000
--- a/core/res/res/values-ja/arrays.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 0735837..055a8b1 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort">"B"</string>
diff --git a/core/res/res/values-mcc204-cs/strings.xml b/core/res/res/values-mcc204-cs/strings.xml
index c846c60..7d96230 100644
--- a/core/res/res/values-mcc204-cs/strings.xml
+++ b/core/res/res/values-mcc204-cs/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"nl_nl"</string>
diff --git a/core/res/res/values-mcc204-de/strings.xml b/core/res/res/values-mcc204-de/strings.xml
index c846c60..7d96230 100644
--- a/core/res/res/values-mcc204-de/strings.xml
+++ b/core/res/res/values-mcc204-de/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"nl_nl"</string>
diff --git a/core/res/res/values-mcc204-es/strings.xml b/core/res/res/values-mcc204-es/strings.xml
index c846c60..7d96230 100644
--- a/core/res/res/values-mcc204-es/strings.xml
+++ b/core/res/res/values-mcc204-es/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"nl_nl"</string>
diff --git a/core/res/res/values-mcc204-fr/strings.xml b/core/res/res/values-mcc204-fr/strings.xml
index c846c60..7d96230 100644
--- a/core/res/res/values-mcc204-fr/strings.xml
+++ b/core/res/res/values-mcc204-fr/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"nl_nl"</string>
diff --git a/core/res/res/values-mcc204-it/strings.xml b/core/res/res/values-mcc204-it/strings.xml
index c846c60..7d96230 100644
--- a/core/res/res/values-mcc204-it/strings.xml
+++ b/core/res/res/values-mcc204-it/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"nl_nl"</string>
diff --git a/core/res/res/values-mcc204-ja/strings.xml b/core/res/res/values-mcc204-ja/strings.xml
index c846c60..7d96230 100644
--- a/core/res/res/values-mcc204-ja/strings.xml
+++ b/core/res/res/values-mcc204-ja/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"nl_nl"</string>
diff --git a/core/res/res/values-mcc204-nl/strings.xml b/core/res/res/values-mcc204-nl/strings.xml
index c846c60..7d96230 100644
--- a/core/res/res/values-mcc204-nl/strings.xml
+++ b/core/res/res/values-mcc204-nl/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"nl_nl"</string>
diff --git a/core/res/res/values-mcc204-pl/strings.xml b/core/res/res/values-mcc204-pl/strings.xml
index c846c60..7d96230 100644
--- a/core/res/res/values-mcc204-pl/strings.xml
+++ b/core/res/res/values-mcc204-pl/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"nl_nl"</string>
diff --git a/core/res/res/values-mcc204-ru/strings.xml b/core/res/res/values-mcc204-ru/strings.xml
index c846c60..7d96230 100644
--- a/core/res/res/values-mcc204-ru/strings.xml
+++ b/core/res/res/values-mcc204-ru/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"nl_nl"</string>
diff --git a/core/res/res/values-mcc204-zh-rCN/strings.xml b/core/res/res/values-mcc204-zh-rCN/strings.xml
index c846c60..7d96230 100644
--- a/core/res/res/values-mcc204-zh-rCN/strings.xml
+++ b/core/res/res/values-mcc204-zh-rCN/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"nl_nl"</string>
diff --git a/core/res/res/values-mcc204-zh-rTW/strings.xml b/core/res/res/values-mcc204-zh-rTW/strings.xml
index c846c60..7d96230 100644
--- a/core/res/res/values-mcc204-zh-rTW/strings.xml
+++ b/core/res/res/values-mcc204-zh-rTW/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"nl_nl"</string>
diff --git a/core/res/res/values-mcc230-cs/strings.xml b/core/res/res/values-mcc230-cs/strings.xml
index fd82191..d3ecdbb 100644
--- a/core/res/res/values-mcc230-cs/strings.xml
+++ b/core/res/res/values-mcc230-cs/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"cs_cz"</string>
diff --git a/core/res/res/values-mcc230-de/strings.xml b/core/res/res/values-mcc230-de/strings.xml
index fd82191..d3ecdbb 100644
--- a/core/res/res/values-mcc230-de/strings.xml
+++ b/core/res/res/values-mcc230-de/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"cs_cz"</string>
diff --git a/core/res/res/values-mcc230-es/strings.xml b/core/res/res/values-mcc230-es/strings.xml
index fd82191..d3ecdbb 100644
--- a/core/res/res/values-mcc230-es/strings.xml
+++ b/core/res/res/values-mcc230-es/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"cs_cz"</string>
diff --git a/core/res/res/values-mcc230-fr/strings.xml b/core/res/res/values-mcc230-fr/strings.xml
index fd82191..d3ecdbb 100644
--- a/core/res/res/values-mcc230-fr/strings.xml
+++ b/core/res/res/values-mcc230-fr/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"cs_cz"</string>
diff --git a/core/res/res/values-mcc230-it/strings.xml b/core/res/res/values-mcc230-it/strings.xml
index fd82191..d3ecdbb 100644
--- a/core/res/res/values-mcc230-it/strings.xml
+++ b/core/res/res/values-mcc230-it/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"cs_cz"</string>
diff --git a/core/res/res/values-mcc230-ja/strings.xml b/core/res/res/values-mcc230-ja/strings.xml
index fd82191..d3ecdbb 100644
--- a/core/res/res/values-mcc230-ja/strings.xml
+++ b/core/res/res/values-mcc230-ja/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"cs_cz"</string>
diff --git a/core/res/res/values-mcc230-nl/strings.xml b/core/res/res/values-mcc230-nl/strings.xml
index fd82191..d3ecdbb 100644
--- a/core/res/res/values-mcc230-nl/strings.xml
+++ b/core/res/res/values-mcc230-nl/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"cs_cz"</string>
diff --git a/core/res/res/values-mcc230-pl/strings.xml b/core/res/res/values-mcc230-pl/strings.xml
index fd82191..d3ecdbb 100644
--- a/core/res/res/values-mcc230-pl/strings.xml
+++ b/core/res/res/values-mcc230-pl/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"cs_cz"</string>
diff --git a/core/res/res/values-mcc230-ru/strings.xml b/core/res/res/values-mcc230-ru/strings.xml
index fd82191..d3ecdbb 100644
--- a/core/res/res/values-mcc230-ru/strings.xml
+++ b/core/res/res/values-mcc230-ru/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"cs_cz"</string>
diff --git a/core/res/res/values-mcc230-zh-rCN/strings.xml b/core/res/res/values-mcc230-zh-rCN/strings.xml
index fd82191..d3ecdbb 100644
--- a/core/res/res/values-mcc230-zh-rCN/strings.xml
+++ b/core/res/res/values-mcc230-zh-rCN/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"cs_cz"</string>
diff --git a/core/res/res/values-mcc230-zh-rTW/strings.xml b/core/res/res/values-mcc230-zh-rTW/strings.xml
index fd82191..d3ecdbb 100644
--- a/core/res/res/values-mcc230-zh-rTW/strings.xml
+++ b/core/res/res/values-mcc230-zh-rTW/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"cs_cz"</string>
diff --git a/core/res/res/values-mcc232-cs/strings.xml b/core/res/res/values-mcc232-cs/strings.xml
index 1376f0c..4773838 100644
--- a/core/res/res/values-mcc232-cs/strings.xml
+++ b/core/res/res/values-mcc232-cs/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"de_at"</string>
diff --git a/core/res/res/values-mcc232-de/strings.xml b/core/res/res/values-mcc232-de/strings.xml
index 1376f0c..4773838 100644
--- a/core/res/res/values-mcc232-de/strings.xml
+++ b/core/res/res/values-mcc232-de/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"de_at"</string>
diff --git a/core/res/res/values-mcc232-es/strings.xml b/core/res/res/values-mcc232-es/strings.xml
index 1376f0c..4773838 100644
--- a/core/res/res/values-mcc232-es/strings.xml
+++ b/core/res/res/values-mcc232-es/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"de_at"</string>
diff --git a/core/res/res/values-mcc232-fr/strings.xml b/core/res/res/values-mcc232-fr/strings.xml
index 1376f0c..4773838 100644
--- a/core/res/res/values-mcc232-fr/strings.xml
+++ b/core/res/res/values-mcc232-fr/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"de_at"</string>
diff --git a/core/res/res/values-mcc232-it/strings.xml b/core/res/res/values-mcc232-it/strings.xml
index 1376f0c..4773838 100644
--- a/core/res/res/values-mcc232-it/strings.xml
+++ b/core/res/res/values-mcc232-it/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"de_at"</string>
diff --git a/core/res/res/values-mcc232-ja/strings.xml b/core/res/res/values-mcc232-ja/strings.xml
index 1376f0c..4773838 100644
--- a/core/res/res/values-mcc232-ja/strings.xml
+++ b/core/res/res/values-mcc232-ja/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"de_at"</string>
diff --git a/core/res/res/values-mcc232-nl/strings.xml b/core/res/res/values-mcc232-nl/strings.xml
index 1376f0c..4773838 100644
--- a/core/res/res/values-mcc232-nl/strings.xml
+++ b/core/res/res/values-mcc232-nl/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"de_at"</string>
diff --git a/core/res/res/values-mcc232-pl/strings.xml b/core/res/res/values-mcc232-pl/strings.xml
index 1376f0c..4773838 100644
--- a/core/res/res/values-mcc232-pl/strings.xml
+++ b/core/res/res/values-mcc232-pl/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"de_at"</string>
diff --git a/core/res/res/values-mcc232-ru/strings.xml b/core/res/res/values-mcc232-ru/strings.xml
index 1376f0c..4773838 100644
--- a/core/res/res/values-mcc232-ru/strings.xml
+++ b/core/res/res/values-mcc232-ru/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"de_at"</string>
diff --git a/core/res/res/values-mcc232-zh-rCN/strings.xml b/core/res/res/values-mcc232-zh-rCN/strings.xml
index 1376f0c..4773838 100644
--- a/core/res/res/values-mcc232-zh-rCN/strings.xml
+++ b/core/res/res/values-mcc232-zh-rCN/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"de_at"</string>
diff --git a/core/res/res/values-mcc232-zh-rTW/strings.xml b/core/res/res/values-mcc232-zh-rTW/strings.xml
index 1376f0c..4773838 100644
--- a/core/res/res/values-mcc232-zh-rTW/strings.xml
+++ b/core/res/res/values-mcc232-zh-rTW/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"de_at"</string>
diff --git a/core/res/res/values-mcc234-cs/strings.xml b/core/res/res/values-mcc234-cs/strings.xml
index 44a7841..2538b73 100644
--- a/core/res/res/values-mcc234-cs/strings.xml
+++ b/core/res/res/values-mcc234-cs/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"en_gb"</string>
diff --git a/core/res/res/values-mcc234-de/strings.xml b/core/res/res/values-mcc234-de/strings.xml
index 44a7841..2538b73 100644
--- a/core/res/res/values-mcc234-de/strings.xml
+++ b/core/res/res/values-mcc234-de/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"en_gb"</string>
diff --git a/core/res/res/values-mcc234-es/strings.xml b/core/res/res/values-mcc234-es/strings.xml
index 44a7841..2538b73 100644
--- a/core/res/res/values-mcc234-es/strings.xml
+++ b/core/res/res/values-mcc234-es/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"en_gb"</string>
diff --git a/core/res/res/values-mcc234-fr/strings.xml b/core/res/res/values-mcc234-fr/strings.xml
index 44a7841..2538b73 100644
--- a/core/res/res/values-mcc234-fr/strings.xml
+++ b/core/res/res/values-mcc234-fr/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"en_gb"</string>
diff --git a/core/res/res/values-mcc234-it/strings.xml b/core/res/res/values-mcc234-it/strings.xml
index 44a7841..2538b73 100644
--- a/core/res/res/values-mcc234-it/strings.xml
+++ b/core/res/res/values-mcc234-it/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"en_gb"</string>
diff --git a/core/res/res/values-mcc234-ja/strings.xml b/core/res/res/values-mcc234-ja/strings.xml
index 44a7841..2538b73 100644
--- a/core/res/res/values-mcc234-ja/strings.xml
+++ b/core/res/res/values-mcc234-ja/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"en_gb"</string>
diff --git a/core/res/res/values-mcc234-nl/strings.xml b/core/res/res/values-mcc234-nl/strings.xml
index 44a7841..2538b73 100644
--- a/core/res/res/values-mcc234-nl/strings.xml
+++ b/core/res/res/values-mcc234-nl/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"en_gb"</string>
diff --git a/core/res/res/values-mcc234-pl/strings.xml b/core/res/res/values-mcc234-pl/strings.xml
index 44a7841..2538b73 100644
--- a/core/res/res/values-mcc234-pl/strings.xml
+++ b/core/res/res/values-mcc234-pl/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"en_gb"</string>
diff --git a/core/res/res/values-mcc234-ru/strings.xml b/core/res/res/values-mcc234-ru/strings.xml
index 44a7841..2538b73 100644
--- a/core/res/res/values-mcc234-ru/strings.xml
+++ b/core/res/res/values-mcc234-ru/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"en_gb"</string>
diff --git a/core/res/res/values-mcc234-zh-rCN/strings.xml b/core/res/res/values-mcc234-zh-rCN/strings.xml
index 44a7841..2538b73 100644
--- a/core/res/res/values-mcc234-zh-rCN/strings.xml
+++ b/core/res/res/values-mcc234-zh-rCN/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"en_gb"</string>
diff --git a/core/res/res/values-mcc234-zh-rTW/strings.xml b/core/res/res/values-mcc234-zh-rTW/strings.xml
index 44a7841..2538b73 100644
--- a/core/res/res/values-mcc234-zh-rTW/strings.xml
+++ b/core/res/res/values-mcc234-zh-rTW/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"en_gb"</string>
diff --git a/core/res/res/values-mcc260-cs/strings.xml b/core/res/res/values-mcc260-cs/strings.xml
index 2e40a50..1161f9a 100644
--- a/core/res/res/values-mcc260-cs/strings.xml
+++ b/core/res/res/values-mcc260-cs/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"pl_pl"</string>
diff --git a/core/res/res/values-mcc260-de/strings.xml b/core/res/res/values-mcc260-de/strings.xml
index 2e40a50..1161f9a 100644
--- a/core/res/res/values-mcc260-de/strings.xml
+++ b/core/res/res/values-mcc260-de/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"pl_pl"</string>
diff --git a/core/res/res/values-mcc260-es/strings.xml b/core/res/res/values-mcc260-es/strings.xml
index 2e40a50..1161f9a 100644
--- a/core/res/res/values-mcc260-es/strings.xml
+++ b/core/res/res/values-mcc260-es/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"pl_pl"</string>
diff --git a/core/res/res/values-mcc260-fr/strings.xml b/core/res/res/values-mcc260-fr/strings.xml
index 2e40a50..1161f9a 100644
--- a/core/res/res/values-mcc260-fr/strings.xml
+++ b/core/res/res/values-mcc260-fr/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"pl_pl"</string>
diff --git a/core/res/res/values-mcc260-it/strings.xml b/core/res/res/values-mcc260-it/strings.xml
index 2e40a50..1161f9a 100644
--- a/core/res/res/values-mcc260-it/strings.xml
+++ b/core/res/res/values-mcc260-it/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"pl_pl"</string>
diff --git a/core/res/res/values-mcc260-ja/strings.xml b/core/res/res/values-mcc260-ja/strings.xml
index 2e40a50..1161f9a 100644
--- a/core/res/res/values-mcc260-ja/strings.xml
+++ b/core/res/res/values-mcc260-ja/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"pl_pl"</string>
diff --git a/core/res/res/values-mcc260-nl/strings.xml b/core/res/res/values-mcc260-nl/strings.xml
index 2e40a50..1161f9a 100644
--- a/core/res/res/values-mcc260-nl/strings.xml
+++ b/core/res/res/values-mcc260-nl/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"pl_pl"</string>
diff --git a/core/res/res/values-mcc260-pl/strings.xml b/core/res/res/values-mcc260-pl/strings.xml
index 2e40a50..1161f9a 100644
--- a/core/res/res/values-mcc260-pl/strings.xml
+++ b/core/res/res/values-mcc260-pl/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"pl_pl"</string>
diff --git a/core/res/res/values-mcc260-ru/strings.xml b/core/res/res/values-mcc260-ru/strings.xml
index 2e40a50..1161f9a 100644
--- a/core/res/res/values-mcc260-ru/strings.xml
+++ b/core/res/res/values-mcc260-ru/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"pl_pl"</string>
diff --git a/core/res/res/values-mcc260-zh-rCN/strings.xml b/core/res/res/values-mcc260-zh-rCN/strings.xml
index 2e40a50..1161f9a 100644
--- a/core/res/res/values-mcc260-zh-rCN/strings.xml
+++ b/core/res/res/values-mcc260-zh-rCN/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"pl_pl"</string>
diff --git a/core/res/res/values-mcc260-zh-rTW/strings.xml b/core/res/res/values-mcc260-zh-rTW/strings.xml
index 2e40a50..1161f9a 100644
--- a/core/res/res/values-mcc260-zh-rTW/strings.xml
+++ b/core/res/res/values-mcc260-zh-rTW/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"pl_pl"</string>
diff --git a/core/res/res/values-mcc262-cs/strings.xml b/core/res/res/values-mcc262-cs/strings.xml
index c4b1b72..9505cf4 100644
--- a/core/res/res/values-mcc262-cs/strings.xml
+++ b/core/res/res/values-mcc262-cs/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"de_de"</string>
diff --git a/core/res/res/values-mcc262-de/strings.xml b/core/res/res/values-mcc262-de/strings.xml
index c4b1b72..9505cf4 100644
--- a/core/res/res/values-mcc262-de/strings.xml
+++ b/core/res/res/values-mcc262-de/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"de_de"</string>
diff --git a/core/res/res/values-mcc262-es/strings.xml b/core/res/res/values-mcc262-es/strings.xml
index c4b1b72..9505cf4 100644
--- a/core/res/res/values-mcc262-es/strings.xml
+++ b/core/res/res/values-mcc262-es/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"de_de"</string>
diff --git a/core/res/res/values-mcc262-fr/strings.xml b/core/res/res/values-mcc262-fr/strings.xml
index c4b1b72..9505cf4 100644
--- a/core/res/res/values-mcc262-fr/strings.xml
+++ b/core/res/res/values-mcc262-fr/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"de_de"</string>
diff --git a/core/res/res/values-mcc262-it/strings.xml b/core/res/res/values-mcc262-it/strings.xml
index c4b1b72..9505cf4 100644
--- a/core/res/res/values-mcc262-it/strings.xml
+++ b/core/res/res/values-mcc262-it/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"de_de"</string>
diff --git a/core/res/res/values-mcc262-ja/strings.xml b/core/res/res/values-mcc262-ja/strings.xml
index c4b1b72..9505cf4 100644
--- a/core/res/res/values-mcc262-ja/strings.xml
+++ b/core/res/res/values-mcc262-ja/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"de_de"</string>
diff --git a/core/res/res/values-mcc262-nl/strings.xml b/core/res/res/values-mcc262-nl/strings.xml
index c4b1b72..9505cf4 100644
--- a/core/res/res/values-mcc262-nl/strings.xml
+++ b/core/res/res/values-mcc262-nl/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"de_de"</string>
diff --git a/core/res/res/values-mcc262-pl/strings.xml b/core/res/res/values-mcc262-pl/strings.xml
index c4b1b72..9505cf4 100644
--- a/core/res/res/values-mcc262-pl/strings.xml
+++ b/core/res/res/values-mcc262-pl/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"de_de"</string>
diff --git a/core/res/res/values-mcc262-ru/strings.xml b/core/res/res/values-mcc262-ru/strings.xml
index c4b1b72..9505cf4 100644
--- a/core/res/res/values-mcc262-ru/strings.xml
+++ b/core/res/res/values-mcc262-ru/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"de_de"</string>
diff --git a/core/res/res/values-mcc262-zh-rCN/strings.xml b/core/res/res/values-mcc262-zh-rCN/strings.xml
index c4b1b72..9505cf4 100644
--- a/core/res/res/values-mcc262-zh-rCN/strings.xml
+++ b/core/res/res/values-mcc262-zh-rCN/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"de_de"</string>
diff --git a/core/res/res/values-mcc262-zh-rTW/strings.xml b/core/res/res/values-mcc262-zh-rTW/strings.xml
index c4b1b72..9505cf4 100644
--- a/core/res/res/values-mcc262-zh-rTW/strings.xml
+++ b/core/res/res/values-mcc262-zh-rTW/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="locale_replacement">"de_de"</string>
diff --git a/core/res/res/values-nl/arrays.xml b/core/res/res/values-nl/arrays.xml
deleted file mode 100644
index f9c904b..0000000
--- a/core/res/res/values-nl/arrays.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 9426f35..5c54226 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort">"B"</string>
diff --git a/core/res/res/values-pl/arrays.xml b/core/res/res/values-pl/arrays.xml
deleted file mode 100644
index f9c904b..0000000
--- a/core/res/res/values-pl/arrays.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index d76922f..c3e3a46 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort">"B"</string>
diff --git a/core/res/res/values-ru/arrays.xml b/core/res/res/values-ru/arrays.xml
deleted file mode 100644
index f9c904b..0000000
--- a/core/res/res/values-ru/arrays.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index a00973f..33efbf6 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort">"б"</string>
diff --git a/core/res/res/values-zh-rCN/arrays.xml b/core/res/res/values-zh-rCN/arrays.xml
deleted file mode 100644
index f9c904b..0000000
--- a/core/res/res/values-zh-rCN/arrays.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 87bd4e4..cb13390 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort">"B"</string>
diff --git a/core/res/res/values-zh-rTW/arrays.xml b/core/res/res/values-zh-rTW/arrays.xml
deleted file mode 100644
index f9c904b..0000000
--- a/core/res/res/values-zh-rTW/arrays.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index fbe8c55..758bf82 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort">"位元組"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 2562a8a..5477538 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2934,5 +2934,22 @@
requested keyboard mode, the key will be skipped -->
<attr name="keyboardMode" />
</declare-styleable>
+
+ <!-- =============================== -->
+ <!-- Gadget package class attributes -->
+ <!-- =============================== -->
+
+ <!-- Use <code>gadget-provider</code> as the root tag of the XML resource that
+ describes a gadget provider. See TODO android.gadget android.gadget package
+ for more info.
+ -->
+ <declare-styleable name="GadgetProviderInfo">
+ <attr name="minWidth"/>
+ <attr name="minHeight"/>
+ <attr name="updatePeriodMillis" format="integer" />
+ <attr name="initialLayout" format="reference" />
+ </declare-styleable>
+
+
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index f25d829..c757c56 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -986,6 +986,8 @@
<public type="attr" name="keyboardMode" id="0x01010253" />
<public type="attr" name="isScrollContainer" id="0x01010254" />
<public type="attr" name="fillEnabled" id="0x01010255" />
+ <public type="attr" name="updatePeriodMillis" id="0x01010256" />
+ <public type="attr" name="initialLayout" id="0x01010257" />
<!-- The part of the UI shown by an
{@link android.inputmethodservice.InputMethodService} that contains the
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 73e7dd0..41d3a81 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -74,6 +74,12 @@
<item name="windowExitAnimation">@anim/dialog_exit</item>
</style>
+ <!-- Standard animations for hiding and showing the status bar. -->
+ <style name="Animation.StatusBar">
+ <item name="windowEnterAnimation">@anim/status_bar_enter</item>
+ <item name="windowExitAnimation">@anim/status_bar_exit</item>
+ </style>
+
<!-- Standard animations for a translucent window or activity. -->
<style name="Animation.Translucent">
</style>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 72367f8..3f07e70 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -31,7 +31,7 @@
<item name="colorForegroundInverse">@android:color/bright_foreground_dark_inverse</item>
<item name="colorBackground">@android:color/background_dark</item>
<item name="disabledAlpha">0.5</item>
- <item name="backgroundDimAmount">0.5</item>
+ <item name="backgroundDimAmount">0.6</item>
<!-- Text styles -->
<item name="textAppearance">@android:style/TextAppearance</item>
diff --git a/data/localization/import-from-xtb b/data/localization/import-from-xtb
index 15b060a..f0a0b7d 100755
--- a/data/localization/import-from-xtb
+++ b/data/localization/import-from-xtb
@@ -44,7 +44,12 @@
p4 edit $out
p4 add $out
mkdir -p `dirname $out`
- ../../../../out/host/linux-x86/bin/transconsole -m $1 $2 -p $module -i $module-$locale.xtb $i > $out
+ if ../../../../out/host/linux-x86/bin/transconsole -m $1 $2 -p $module -i $module-$locale.xtb $i > $out
+ then :
+ else
+ p4 revert $out
+ p4 delete $out
+ fi
done
}
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 501c99f..dc16c39 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -184,6 +184,37 @@
}
/**
+ * Copy the pixels from the buffer, beginning at the current position,
+ * overwriting the bitmap's pixels. The data in the buffer is not changed
+ * in any way (unlike setPixels(), which converts from unpremultipled 32bit
+ * to whatever the bitmap's native format is.
+ */
+ public void copyPixelsFromBuffer(Buffer src) {
+ checkRecycled("copyPixelsFromBuffer called on recycled bitmap");
+
+ int elements = src.remaining();
+ int shift;
+ if (src instanceof ByteBuffer) {
+ shift = 0;
+ } else if (src instanceof ShortBuffer) {
+ shift = 1;
+ } else if (src instanceof IntBuffer) {
+ shift = 2;
+ } else {
+ throw new RuntimeException("unsupported Buffer subclass");
+ }
+
+ long bufferBytes = (long)elements << shift;
+ long bitmapBytes = (long)getRowBytes() * getHeight();
+
+ if (bufferBytes < bitmapBytes) {
+ throw new RuntimeException("Buffer not large enough for pixels");
+ }
+
+ nativeCopyPixelsFromBuffer(mNativeBitmap, src);
+ }
+
+ /**
* Tries to make a new bitmap based on the dimensions of this bitmap,
* setting the new bitmap's config to the one specified, and then copying
* this bitmap's pixels into the new bitmap. If the conversion is not
@@ -794,6 +825,7 @@
int y, int width, int height);
private static native void nativeCopyPixelsToBuffer(int nativeBitmap,
Buffer dst);
+ private static native void nativeCopyPixelsFromBuffer(int nb, Buffer src);
private static native Bitmap nativeCreateFromParcel(Parcel p);
// returns true on success
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index d1e6090..2c3f543 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -304,11 +304,6 @@
bm = nativeDecodeStream(is, tempStorage, outPadding, opts);
}
- try {
- is.reset();
- } catch (IOException ex) {
- // ignore
- }
return bm;
}
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index fa5ed0a..59dfbd4 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -340,10 +340,10 @@
final int N = mLayerState.mNum;
for (int i=0; i<N; i++) {
reapplyPadding(i, array[i]);
- padding.left = Math.max(padding.left, mPaddingL[i]);
- padding.top = Math.max(padding.top, mPaddingT[i]);
- padding.right = Math.max(padding.right, mPaddingR[i]);
- padding.bottom = Math.max(padding.bottom, mPaddingB[i]);
+ padding.left += mPaddingL[i];
+ padding.top += mPaddingT[i];
+ padding.right += mPaddingR[i];
+ padding.bottom += mPaddingB[i];
}
return true;
}
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 51b800c..c330bc8 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -104,7 +104,7 @@
mA2dpOutput(0), mOutput(0), mRequestedOutput(0), mAudioRecordThread(0),
mSampleRate(0), mFrameCount(0), mChannelCount(0), mFormat(0), mMixBuffer(0),
mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mStandby(false),
- mInWrite(false)
+ mInWrite(false), mA2dpDisableCount(0), mA2dpSuppressed(false)
{
mHardwareStatus = AUDIO_HW_IDLE;
mAudioHardware = AudioHardwareInterface::create();
@@ -205,6 +205,27 @@
return output->bufferSize() / output->channelCount() / sizeof(int16_t);
}
+#ifdef WITH_A2DP
+bool AudioFlinger::streamDisablesA2dp(int streamType)
+{
+ return (streamType == AudioTrack::SYSTEM ||
+ streamType == AudioTrack::RING ||
+ streamType == AudioTrack::ALARM ||
+ streamType == AudioTrack::NOTIFICATION);
+}
+
+void AudioFlinger::setA2dpEnabled(bool enable)
+{
+ if (enable) {
+ LOGD("set output to A2DP\n");
+ setOutput(mA2dpOutput);
+ } else {
+ LOGD("set output to hardware audio\n");
+ setOutput(mHardwareOutput);
+ }
+}
+#endif // WITH_A2DP
+
status_t AudioFlinger::dumpClients(int fd, const Vector<String16>& args)
{
const size_t SIZE = 256;
@@ -457,7 +478,7 @@
if (UNLIKELY(count)) {
for (size_t i=0 ; i<count ; i++) {
const sp<Track>& track = tracksToRemove[i];
- mActiveTracks.remove(track);
+ removeActiveTrack(track);
if (track->isTerminated()) {
mTracks.remove(track);
mAudioMixer->deleteTrackName(track->mName);
@@ -653,13 +674,16 @@
LOGD("setRouting %d %d %d\n", mode, routes, mask);
if (mode == AudioSystem::MODE_NORMAL &&
(mask & AudioSystem::ROUTE_BLUETOOTH_A2DP)) {
+ AutoMutex lock(&mLock);
+
+ bool enableA2dp = false;
if (routes & AudioSystem::ROUTE_BLUETOOTH_A2DP) {
- LOGD("set output to A2DP\n");
- setOutput(mA2dpOutput);
- } else {
- LOGD("set output to hardware audio\n");
- setOutput(mHardwareOutput);
+ if (mA2dpDisableCount > 0)
+ mA2dpSuppressed = true;
+ else
+ enableA2dp = true;
}
+ setA2dpEnabled(enableA2dp);
LOGD("setOutput done\n");
}
#endif
@@ -875,7 +899,7 @@
// effectively get the latency it requested.
track->mFillingUpStatus = Track::FS_FILLING;
track->mResetDone = false;
- mActiveTracks.add(track);
+ addActiveTrack(track);
return NO_ERROR;
}
return ALREADY_EXISTS;
@@ -897,7 +921,7 @@
t->reset();
}
audioMixer()->deleteTrackName(name);
- mActiveTracks.remove(track);
+ removeActiveTrack(track);
mWaitWorkCV.broadcast();
}
@@ -918,6 +942,44 @@
}
}
+void AudioFlinger::addActiveTrack(const wp<Track>& t)
+{
+ mActiveTracks.add(t);
+
+#ifdef WITH_A2DP
+ // disable A2DP for certain stream types
+ sp<Track> track = t.promote();
+ if (streamDisablesA2dp(track->type())) {
+ if (mA2dpDisableCount++ == 0 && isA2dpEnabled()) {
+ setA2dpEnabled(false);
+ mA2dpSuppressed = true;
+ LOGD("mA2dpSuppressed = true\n");
+ }
+ LOGD("mA2dpDisableCount incremented to %d\n", mA2dpDisableCount);
+ }
+#endif
+}
+
+void AudioFlinger::removeActiveTrack(const wp<Track>& t)
+{
+ mActiveTracks.remove(t);
+#ifdef WITH_A2DP
+ // disable A2DP for certain stream types
+ sp<Track> track = t.promote();
+ if (streamDisablesA2dp(track->type())) {
+ if (mA2dpDisableCount > 0) {
+ mA2dpDisableCount--;
+ if (mA2dpDisableCount == 0 && mA2dpSuppressed) {
+ setA2dpEnabled(true);
+ mA2dpSuppressed = false;
+ }
+ LOGD("mA2dpDisableCount decremented to %d\n", mA2dpDisableCount);
+ } else
+ LOGE("mA2dpDisableCount is already zero");
+ }
+#endif
+}
+
// ----------------------------------------------------------------------------
AudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index 90bc72d..9ab362a 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -153,6 +153,15 @@
void doSetOutput(AudioStreamOut* output);
size_t getOutputFrameCount(AudioStreamOut* output);
+#ifdef WITH_A2DP
+ static bool streamDisablesA2dp(int streamType);
+ inline bool isA2dpEnabled() const {
+ return (mRequestedOutput == mA2dpOutput ||
+ (mOutput && mOutput == mA2dpOutput));
+ }
+ void setA2dpEnabled(bool enable);
+#endif
+
// Internal dump utilites.
status_t dumpPermissionDenial(int fd, const Vector<String16>& args);
status_t dumpClients(int fd, const Vector<String16>& args);
@@ -371,6 +380,8 @@
void removeTrack(wp<Track> track, int name);
void remove_track_l(wp<Track> track, int name);
void destroyTrack(const sp<Track>& track);
+ void addActiveTrack(const wp<Track>& track);
+ void removeActiveTrack(const wp<Track>& track);
AudioMixer* audioMixer() {
return mAudioMixer;
@@ -481,6 +492,8 @@
int mNumDelayedWrites;
bool mStandby;
bool mInWrite;
+ int mA2dpDisableCount;
+ bool mA2dpSuppressed;
};
// ----------------------------------------------------------------------------
diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java
index 3d4d4a2..c6f13c9 100644
--- a/location/java/com/android/internal/location/GpsLocationProvider.java
+++ b/location/java/com/android/internal/location/GpsLocationProvider.java
@@ -155,6 +155,7 @@
private ArrayList<Listener> mListeners = new ArrayList<Listener>();
private GpsEventThread mEventThread;
private GpsNetworkThread mNetworkThread;
+ private Object mNetworkThreadLock = new Object();
// how often to request NTP time, in milliseconds
// current setting 4 hours
@@ -301,8 +302,9 @@
* when the provider is enabled.
*/
@Override
- public void enable() {
+ public synchronized void enable() {
if (Config.LOGD) Log.d(TAG, "enable");
+ if (mEnabled) return;
mEnabled = native_init();
if (mEnabled) {
@@ -330,8 +332,10 @@
* down while the provider is disabled.
*/
@Override
- public void disable() {
+ public synchronized void disable() {
if (Config.LOGD) Log.d(TAG, "disable");
+ if (!mEnabled) return;
+
mEnabled = false;
stopNavigating();
native_disable();
@@ -346,6 +350,11 @@
mEventThread = null;
}
+ if (mNetworkThread != null) {
+ mNetworkThread.setDone();
+ mNetworkThread = null;
+ }
+
native_cleanup();
}
@@ -745,12 +754,21 @@
private long mNextNtpTime = 0;
private long mNextXtraTime = 0;
private boolean mXtraDownloadRequested = false;
+ private boolean mDone = false;
public GpsNetworkThread() {
super("GpsNetworkThread");
}
public void run() {
+ synchronized (mNetworkThreadLock) {
+ if (!mDone) {
+ runLocked();
+ }
+ }
+ }
+
+ public void runLocked() {
if (Config.LOGD) Log.d(TAG, "NetworkThread starting");
SntpClient client = new SntpClient();
@@ -761,7 +779,7 @@
}
// thread exits after disable() is called
- while (mEnabled) {
+ while (!mDone) {
long waitTime = getWaitTime();
do {
synchronized (this) {
@@ -784,11 +802,11 @@
}
}
waitTime = getWaitTime();
- } while (mEnabled && ((!mXtraDownloadRequested && waitTime > 0)
+ } while (!mDone && ((!mXtraDownloadRequested && waitTime > 0)
|| !mNetworkAvailable));
if (Config.LOGD) Log.d(TAG, "NetworkThread out of wake loop");
- if (mEnabled) {
+ if (!mDone) {
if (mNtpServer != null &&
mNextNtpTime <= System.currentTimeMillis()) {
if (Config.LOGD) {
@@ -840,6 +858,12 @@
notify();
}
+ synchronized void setDone() {
+ if (Config.LOGD) Log.d(TAG, "stopping NetworkThread");
+ mDone = true;
+ notify();
+ }
+
private long getWaitTime() {
long now = System.currentTimeMillis();
long waitTime = Long.MAX_VALUE;
diff --git a/services/java/com/android/server/DeviceMemoryMonitor.java b/services/java/com/android/server/DeviceMemoryMonitor.java
deleted file mode 100644
index 3669e1f..0000000
--- a/services/java/com/android/server/DeviceMemoryMonitor.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 2007 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.server;
-
-import com.android.server.am.ActivityManagerService;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.IPackageDataObserver;
-import android.content.pm.IPackageManager;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.StatFs;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.provider.Settings.Gservices;
-import android.util.Config;
-import android.util.EventLog;
-import android.util.Log;
-import android.provider.Settings;
-
-/**
- * This class implements a service to monitor the amount of disk storage space
- * on the device. If the free storage on device is less than a tunable threshold value
- * (default is 10%. this value is a gservices parameter) a low memory notification is
- * displayed to alert the user. If the user clicks on the low memory notification the
- * Application Manager application gets launched to let the user free storage space.
- * Event log events:
- * A low memory event with the free storage on device in bytes is logged to the event log
- * when the device goes low on storage space.
- * The amount of free storage on the device is periodically logged to the event log. The log
- * interval is a gservices parameter with a default value of 12 hours
- * When the free storage differential goes below a threshold(again a gservices parameter with
- * a default value of 2MB), the free memory is logged to the event log
- */
-class DeviceMemoryMonitorService extends Binder {
- private static final String TAG = "DeviceMemoryMonitor";
- private static final boolean DEBUG = false;
- private static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
- private static final int DEVICE_MEMORY_WHAT = 1;
- private static final int MONITOR_INTERVAL = 1; //in minutes
- private static final int LOW_MEMORY_NOTIFICATION_ID = 1;
- private static final int DEFAULT_THRESHOLD_PERCENTAGE = 10;
- private static final int DEFAULT_FREE_STORAGE_LOG_INTERVAL_IN_MINUTES = 12*60; //in minutes
- private static final int EVENT_LOG_STORAGE_BELOW_THRESHOLD = 2744;
- private static final int EVENT_LOG_LOW_STORAGE_NOTIFICATION = 2745;
- private static final int EVENT_LOG_FREE_STORAGE_LEFT = 2746;
- private static final long DEFAULT_DISK_FREE_CHANGE_REPORTING_THRESHOLD = 2 * 1024 * 1024; // 2MB
- private long mFreeMem;
- private long mLastReportedFreeMem;
- private long mLastReportedFreeMemTime;
- private boolean mLowMemFlag=false;
- private Context mContext;
- private ContentResolver mContentResolver;
- int mBlkSize;
- long mTotalMemory;
- StatFs mFileStats;
- private static final String DATA_PATH="/data";
- long mThreadStartTime = -1;
- boolean mClearSucceeded = false;
- boolean mClearingCache;
- private Intent mStorageLowIntent;
- private Intent mStorageOkIntent;
- /**
- * Handler that checks the amount of disk space on the device and sends a
- * notification if the device runs low on disk space
- */
- Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- //dont handle an invalid message
- if (msg.what != DEVICE_MEMORY_WHAT) {
- Log.e(TAG, "Will not process invalid message");
- return;
- }
- checkMemory();
- }
- };
-
- class CachePackageDataObserver extends IPackageDataObserver.Stub {
- public void onRemoveCompleted(String packageName, boolean succeeded) {
- mClearSucceeded = succeeded;
- mClearingCache = false;
- if(localLOGV) Log.i(TAG, " Clear succeeded:"+mClearSucceeded
- +", mClearingCache:"+mClearingCache);
- }
- }
-
- private final void restatDataDir() {
- mFileStats.restat(DATA_PATH);
- mFreeMem = mFileStats.getAvailableBlocks()*mBlkSize;
- // Allow freemem to be overridden by debug.freemem for testing
- String debugFreeMem = SystemProperties.get("debug.freemem");
- if (!"".equals(debugFreeMem)) {
- mFreeMem = Long.parseLong(debugFreeMem);
- }
- // Read the log interval from Gservices
- long freeMemLogInterval = Gservices.getLong(mContentResolver,
- Gservices.SYS_FREE_STORAGE_LOG_INTERVAL,
- DEFAULT_FREE_STORAGE_LOG_INTERVAL_IN_MINUTES)*60*1000;
- //log the amount of free memory in event log
- long currTime = SystemClock.elapsedRealtime();
- if((mLastReportedFreeMemTime == 0) ||
- (currTime-mLastReportedFreeMemTime) >= freeMemLogInterval) {
- mLastReportedFreeMemTime = currTime;
- EventLog.writeEvent(EVENT_LOG_FREE_STORAGE_LEFT, mFreeMem);
- }
- // Read the reporting threshold from Gservices
- long threshold = Gservices.getLong(mContentResolver,
- Gservices.DISK_FREE_CHANGE_REPORTING_THRESHOLD,
- DEFAULT_DISK_FREE_CHANGE_REPORTING_THRESHOLD);
- // If mFree changed significantly log the new value
- long delta = mFreeMem - mLastReportedFreeMem;
- if (delta > threshold || delta < -threshold) {
- mLastReportedFreeMem = mFreeMem;
- EventLog.writeEvent(EVENT_LOG_STORAGE_BELOW_THRESHOLD, mFreeMem);
- }
- }
-
- private final void clearCache() {
- CachePackageDataObserver observer = new CachePackageDataObserver();
- mClearingCache = true;
- try {
- IPackageManager.Stub.asInterface(ServiceManager.getService("package")).
- freeApplicationCache(getMemThreshold(), observer);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to get handle for PackageManger Exception: "+e);
- mClearingCache = false;
- mClearSucceeded = false;
- }
- }
-
- private final void checkMemory() {
- //if the thread that was started to clear cache is still running do nothing till its
- //finished clearing cache. Ideally this flag could be modified by clearCache
- // and should be accessed via a lock but even if it does this test will fail now and
- //hopefully the next time this flag will be set to the correct value.
- if(mClearingCache) {
- if(localLOGV) Log.i(TAG, "Thread already running just skip");
- //make sure the thread is not hung for too long
- long diffTime = System.currentTimeMillis() - mThreadStartTime;
- if(diffTime > (10*60*1000)) {
- Log.w(TAG, "Thread that clears cache file seems to run for ever");
- }
- } else {
- restatDataDir();
- if (localLOGV) Log.v(TAG, "freeMemory="+mFreeMem);
- //post intent to NotificationManager to display icon if necessary
- long memThreshold = getMemThreshold();
- if (mFreeMem < memThreshold) {
- if (!mLowMemFlag) {
- //see if clearing cache helps
- mThreadStartTime = System.currentTimeMillis();
- clearCache();
- Log.i(TAG, "Running low on memory. Sending notification");
- sendNotification();
- mLowMemFlag = true;
- } else {
- if (localLOGV) Log.v(TAG, "Running low on memory " +
- "notification already sent. do nothing");
- }
- } else {
- if (mLowMemFlag) {
- Log.i(TAG, "Memory available. Cancelling notification");
- cancelNotification();
- mLowMemFlag = false;
- }
- }
- }
- if(localLOGV) Log.i(TAG, "Posting Message again");
- //keep posting messages to itself periodically
- mHandler.sendMessageDelayed(mHandler.obtainMessage(DEVICE_MEMORY_WHAT),
- MONITOR_INTERVAL*60*1000);
- }
-
- /*
- * just query settings to retrieve the memory threshold.
- * Preferred this over using a ContentObserver since Settings.Gservices caches the value
- * any way
- */
- private long getMemThreshold() {
- int value = Settings.Gservices.getInt(
- mContentResolver,
- Settings.Gservices.SYS_STORAGE_THRESHOLD_PERCENTAGE,
- DEFAULT_THRESHOLD_PERCENTAGE);
- if(localLOGV) Log.v(TAG, "Threshold Percentage="+value);
- //evaluate threshold value
- return mTotalMemory*value;
- }
-
- /**
- * Constructor to run service. initializes the disk space threshold value
- * and posts an empty message to kickstart the process.
- */
- public DeviceMemoryMonitorService(Context context) {
- mLastReportedFreeMemTime = 0;
- mContext = context;
- mContentResolver = mContext.getContentResolver();
- //create StatFs object
- mFileStats = new StatFs(DATA_PATH);
- //initialize block size
- mBlkSize = mFileStats.getBlockSize();
- //initialize total storage on device
- mTotalMemory = (mFileStats.getBlockCount()*mBlkSize)/100;
- mStorageLowIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_LOW);
- mStorageOkIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_OK);
- checkMemory();
- }
-
-
- /**
- * This method sends a notification to NotificationManager to display
- * an error dialog indicating low disk space and launch the Installer
- * application
- */
- private final void sendNotification() {
- if(localLOGV) Log.i(TAG, "Sending low memory notification");
- //log the event to event log with the amount of free storage(in bytes) left on the device
- EventLog.writeEvent(EVENT_LOG_LOW_STORAGE_NOTIFICATION, mFreeMem);
- // Pack up the values and broadcast them to everyone
- Intent lowMemIntent = new Intent(Intent.ACTION_MANAGE_PACKAGE_STORAGE);
- lowMemIntent.putExtra("memory", mFreeMem);
- lowMemIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- NotificationManager mNotificationMgr =
- (NotificationManager)mContext.getSystemService(
- Context.NOTIFICATION_SERVICE);
- CharSequence title = mContext.getText(
- com.android.internal.R.string.low_internal_storage_view_title);
- CharSequence details = mContext.getText(
- com.android.internal.R.string.low_internal_storage_view_text);
- PendingIntent intent = PendingIntent.getActivity(mContext, 0, lowMemIntent, 0);
- Notification notification = new Notification();
- notification.icon = com.android.internal.R.drawable.stat_notify_disk_full;
- notification.tickerText = title;
- notification.flags |= Notification.FLAG_NO_CLEAR;
- notification.setLatestEventInfo(mContext, title, details, intent);
- mNotificationMgr.notify(LOW_MEMORY_NOTIFICATION_ID, notification);
- mContext.sendStickyBroadcast(mStorageLowIntent);
- }
-
- /**
- * Cancels low storage notification and sends OK intent.
- */
- private final void cancelNotification() {
- if(localLOGV) Log.i(TAG, "Canceling low memory notification");
- NotificationManager mNotificationMgr =
- (NotificationManager)mContext.getSystemService(
- Context.NOTIFICATION_SERVICE);
- //cancel notification since memory has been freed
- mNotificationMgr.cancel(LOW_MEMORY_NOTIFICATION_ID);
-
- mContext.removeStickyBroadcast(mStorageLowIntent);
- mContext.sendBroadcast(mStorageOkIntent);
- }
-
- public void updateMemory() {
- ActivityManagerService ams = (ActivityManagerService)ServiceManager.getService("activity");
- int callingUid = getCallingUid();
- if(callingUid != Process.SYSTEM_UID) {
- return;
- }
- //remove queued messages
- mHandler.removeMessages(DEVICE_MEMORY_WHAT);
- //force an early check
- checkMemory();
- }
-}
diff --git a/services/java/com/android/server/DeviceStorageMonitorService.java b/services/java/com/android/server/DeviceStorageMonitorService.java
index 04b1900..44f70f0d 100644
--- a/services/java/com/android/server/DeviceStorageMonitorService.java
+++ b/services/java/com/android/server/DeviceStorageMonitorService.java
@@ -149,7 +149,7 @@
mClearingCache = true;
try {
IPackageManager.Stub.asInterface(ServiceManager.getService("package")).
- freeApplicationCache(getMemThreshold(), observer);
+ freeStorageAndNotify(getMemThreshold(), observer);
} catch (RemoteException e) {
Log.w(TAG, "Failed to get handle for PackageManger Exception: "+e);
mClearingCache = false;
diff --git a/services/java/com/android/server/GadgetService.java b/services/java/com/android/server/GadgetService.java
index 4e49253..4be9ed5 100644
--- a/services/java/com/android/server/GadgetService.java
+++ b/services/java/com/android/server/GadgetService.java
@@ -19,30 +19,264 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.PackageItemInfo;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
import android.gadget.GadgetManager;
import android.gadget.GadgetInfo;
+import android.os.Binder;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Xml;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
import com.android.internal.gadget.IGadgetService;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
class GadgetService extends IGadgetService.Stub
{
private static final String TAG = "GadgetService";
+ static class GadgetId {
+ int gadgetId;
+ String hostPackage;
+ GadgetInfo info;
+ }
+
Context mContext;
+ PackageManager mPackageManager;
+ ArrayList<GadgetInfo> mInstalledProviders;
+ int mNextGadgetId = 1;
+ ArrayList<GadgetId> mGadgetIds = new ArrayList();
GadgetService(Context context) {
mContext = context;
+ mPackageManager = context.getPackageManager();
+ mInstalledProviders = getGadgetList();
+ }
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (mContext.checkCallingPermission(android.Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+ pw.println("Permission Denial: can't dump from from pid="
+ + Binder.getCallingPid()
+ + ", uid=" + Binder.getCallingUid());
+ return;
+ }
+
+ synchronized (mGadgetIds) {
+ int N = mInstalledProviders.size();
+ pw.println("Providers: (size=" + N + ")");
+ for (int i=0; i<N; i++) {
+ GadgetInfo info = mInstalledProviders.get(i);
+ pw.println(" [" + i + "] provder=" + info.provider
+ + " min=(" + info.minWidth + "x" + info.minHeight + ")"
+ + " updatePeriodMillis=" + info.updatePeriodMillis
+ + " initialLayout=" + info.initialLayout);
+ }
+
+ N = mGadgetIds.size();
+ pw.println("GadgetIds: (size=" + N + ")");
+ for (int i=0; i<N; i++) {
+ GadgetId id = mGadgetIds.get(i);
+ pw.println(" [" + i + "] gadgetId=" + id.gadgetId + " host=" + id.hostPackage
+ + " provider=" + (id.info == null ? "null" : id.info.provider));
+ }
+ }
}
public int allocateGadgetId(String hostPackage) {
- return 42;
+ synchronized (mGadgetIds) {
+ // TODO: Check for pick permission
+ int gadgetId = mNextGadgetId++;
+
+ GadgetId id = new GadgetId();
+ id.gadgetId = gadgetId;
+ id.hostPackage = hostPackage;
+
+ mGadgetIds.add(id);
+
+ return gadgetId;
+ }
}
public void deleteGadgetId(int gadgetId) {
+ synchronized (mGadgetIds) {
+ String callingPackage = getCallingPackage();
+ final int N = mGadgetIds.size();
+ for (int i=0; i<N; i++) {
+ GadgetId id = mGadgetIds.get(i);
+ if (canAccessGadgetId(id, callingPackage)) {
+ mGadgetIds.remove(i);
+ // TODO: Notify someone?
+ return;
+ }
+ }
+ }
}
public void bindGadgetId(int gadgetId, ComponentName provider) {
- sendEnabled(provider);
+ synchronized (mGadgetIds) {
+ GadgetId id = lookupGadgetIdLocked(gadgetId);
+ if (id == null) {
+ throw new IllegalArgumentException("bad gadgetId"); // TODO: use a better exception
+ }
+ if (id.info != null) {
+ throw new IllegalArgumentException("gadgetId " + gadgetId + " already bound to "
+ + id.info.provider);
+ }
+ GadgetInfo info = lookupGadgetInfoLocked(provider);
+ if (info == null) {
+ throw new IllegalArgumentException("not a gadget provider: " + provider);
+ }
+
+ id.info = info;
+ }
+ }
+
+ public GadgetInfo getGadgetInfo(int gadgetId) {
+ synchronized (mGadgetIds) {
+ GadgetId id = lookupGadgetIdLocked(gadgetId);
+ if (id != null) {
+ return id.info;
+ }
+ return null;
+ }
+ }
+
+ public List<GadgetInfo> getInstalledProviders() {
+ synchronized (mGadgetIds) {
+ return new ArrayList<GadgetInfo>(mInstalledProviders);
+ }
+ }
+
+ boolean canAccessGadgetId(GadgetId id, String callingPackage) {
+ if (id.hostPackage.equals(callingPackage)) {
+ return true;
+ }
+ if (id.info != null && id.info.provider.getPackageName().equals(callingPackage)) {
+ return true;
+ }
+ // TODO: Check for the pick permission
+ //if (has permission) {
+ // return true;
+ //}
+ //return false;
+ return true;
+ }
+
+ private GadgetId lookupGadgetIdLocked(int gadgetId) {
+ String callingPackage = getCallingPackage();
+ final int N = mGadgetIds.size();
+ for (int i=0; i<N; i++) {
+ GadgetId id = mGadgetIds.get(i);
+ if (canAccessGadgetId(id, callingPackage)) {
+ return id;
+ }
+ }
+ return null;
+ }
+
+ GadgetInfo lookupGadgetInfoLocked(ComponentName provider) {
+ final int N = mInstalledProviders.size();
+ for (int i=0; i<N; i++) {
+ GadgetInfo info = mInstalledProviders.get(i);
+ if (info.provider.equals(provider)) {
+ return info;
+ }
+ }
+ return null;
+ }
+
+ ArrayList<GadgetInfo> getGadgetList() {
+ PackageManager pm = mPackageManager;
+
+ // TODO: We have these as different actions. I wonder if it makes more sense to
+ // have like a GADGET_ACTION, and then subcommands. It's kind of arbitrary that
+ // we look for GADGET_UPDATE_ACTION and not any of the other gadget actions.
+ Intent intent = new Intent(GadgetManager.GADGET_UPDATE_ACTION);
+ List<ResolveInfo> broadcastReceivers = pm.queryBroadcastReceivers(intent,
+ PackageManager.GET_META_DATA);
+
+ ArrayList<GadgetInfo> result = new ArrayList<GadgetInfo>();
+
+ final int N = broadcastReceivers.size();
+ for (int i=0; i<N; i++) {
+ ResolveInfo ri = broadcastReceivers.get(i);
+ ActivityInfo ai = ri.activityInfo;
+ GadgetInfo gi = parseGadgetInfoXml(new ComponentName(ai.packageName, ai.name),
+ ri.activityInfo);
+ if (gi != null) {
+ result.add(gi);
+ }
+ }
+
+ return result;
+ }
+
+ private GadgetInfo parseGadgetInfoXml(ComponentName component,
+ PackageItemInfo packageItemInfo) {
+ GadgetInfo gi = null;
+
+ XmlResourceParser parser = null;
+ try {
+ parser = packageItemInfo.loadXmlMetaData(mPackageManager,
+ GadgetManager.GADGET_PROVIDER_META_DATA);
+ if (parser == null) {
+ Log.w(TAG, "No " + GadgetManager.GADGET_PROVIDER_META_DATA + " meta-data for "
+ + "gadget provider '" + component + '\'');
+ return null;
+ }
+
+ AttributeSet attrs = Xml.asAttributeSet(parser);
+
+ int type;
+ while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+ && type != XmlPullParser.START_TAG) {
+ // drain whitespace, comments, etc.
+ }
+
+ String nodeName = parser.getName();
+ if (!"gadget-provider".equals(nodeName)) {
+ Log.w(TAG, "Meta-data does not start with gadget-provider tag for"
+ + " gadget provider '" + component + '\'');
+ return null;
+ }
+
+ gi = new GadgetInfo();
+
+ gi.provider = component;
+
+ TypedArray sa = mContext.getResources().obtainAttributes(attrs,
+ com.android.internal.R.styleable.GadgetProviderInfo);
+ gi.minWidth = sa.getDimensionPixelSize(
+ com.android.internal.R.styleable.GadgetProviderInfo_minWidth, 0);
+ gi.minHeight = sa.getDimensionPixelSize(
+ com.android.internal.R.styleable.GadgetProviderInfo_minHeight, 0);
+ gi.updatePeriodMillis = sa.getInt(
+ com.android.internal.R.styleable.GadgetProviderInfo_updatePeriodMillis, 0);
+ gi.initialLayout = sa.getResourceId(
+ com.android.internal.R.styleable.GadgetProviderInfo_initialLayout, 0);
+ sa.recycle();
+ } catch (Exception e) {
+ // Ok to catch Exception here, because anything going wrong because
+ // of what a client process passes to us should not be fatal for the
+ // system process.
+ Log.w(TAG, "XML parsing failed for gadget provider '" + component + '\'', e);
+ } finally {
+ if (parser != null) parser.close();
+ }
+ return gi;
}
void sendEnabled(ComponentName provider) {
@@ -51,14 +285,8 @@
mContext.sendBroadcast(intent);
}
- public GadgetInfo getGadgetInfo(int gadgetId) {
- GadgetInfo info = new GadgetInfo();
- info.provider = new ComponentName("com.android.gadgethost",
- "com.android.gadgethost.TestGadgetProvider");
- info.minWidth = 0;
- info.minHeight = 0;
- info.updatePeriodMillis = 60 * 1000; // 60s
- return info;
+ String getCallingPackage() {
+ return mPackageManager.getNameForUid(getCallingUid());
}
}
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index f0d5eaf..58ad426 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -26,6 +26,8 @@
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
+import android.app.PendingIntent;
+import android.app.PendingIntent.CanceledException;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
@@ -892,32 +894,57 @@
}
- public void freeApplicationCache(final long freeStorageSize, final IPackageDataObserver observer) {
+ public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CLEAR_APP_CACHE, null);
// Queue up an async operation since clearing cache may take a little while.
mHandler.post(new Runnable() {
public void run() {
mHandler.removeCallbacks(this);
- boolean succeded = true;
+ int retCode = -1;
if (mInstaller != null) {
- int retCode = mInstaller.freeCache(freeStorageSize);
+ retCode = mInstaller.freeCache(freeStorageSize);
if (retCode < 0) {
Log.w(TAG, "Couldn't clear application caches");
- succeded = false;
- }
- } //end if mInstaller
- if(observer != null) {
- try {
- observer.onRemoveCompleted(null, succeded);
- } catch (RemoteException e) {
- Log.i(TAG, "Observer no longer exists.");
}
- } //end if observer
- } //end run
+ } //end if mInstaller
+ if (observer != null) {
+ try {
+ observer.onRemoveCompleted(null, (retCode >= 0));
+ } catch (RemoteException e) {
+ Log.w(TAG, "RemoveException when invoking call back");
+ }
+ }
+ }
});
}
+ public void freeStorage(final long freeStorageSize, final PendingIntent opFinishedIntent) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.CLEAR_APP_CACHE, null);
+ // Queue up an async operation since clearing cache may take a little while.
+ mHandler.post(new Runnable() {
+ public void run() {
+ mHandler.removeCallbacks(this);
+ int retCode = -1;
+ if (mInstaller != null) {
+ retCode = mInstaller.freeCache(freeStorageSize);
+ if (retCode < 0) {
+ Log.w(TAG, "Couldn't clear application caches");
+ }
+ }
+ if(opFinishedIntent != null) {
+ try {
+ // Callback via pending intent
+ opFinishedIntent.send((retCode >= 0) ? 1 : 0);
+ } catch (CanceledException e1) {
+ Log.i(TAG, "Failed to send pending intent");
+ }
+ }
+ }
+ });
+ }
+
public ActivityInfo getActivityInfo(ComponentName component, int flags) {
synchronized (mPackages) {
PackageParser.Activity a = mActivities.mActivities.get(component);
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 881add1..7ed0aec 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -165,6 +165,10 @@
* value to another, when no window animation is driving it.
*/
static final int DEFAULT_DIM_DURATION = 200;
+
+ /** Adjustment to time to perform a dim, to make it more dramatic.
+ */
+ static final int DIM_DURATION_MULTIPLIER = 6;
static final int UPDATE_FOCUS_NORMAL = 0;
static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
@@ -1129,7 +1133,7 @@
if (win.mSurface != null && !mDisplayFrozen) {
// If we are not currently running the exit animation, we
// need to see about starting one.
- if (win.isVisible()) {
+ if (win.isVisibleLw()) {
int transit = WindowManagerPolicy.TRANSIT_EXIT;
if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
@@ -1339,7 +1343,7 @@
win.mViewVisibility = viewVisibility;
if (viewVisibility == View.VISIBLE &&
(win.mAppToken == null || !win.mAppToken.clientHidden)) {
- displayed = !win.isVisible();
+ displayed = !win.isVisibleLw();
if (win.mExiting) {
win.mExiting = false;
win.mAnimation = null;
@@ -1389,7 +1393,7 @@
if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
}
- if (win.isVisible() &&
+ if (win.isVisibleLw() &&
applyAnimationLocked(win, transit, false)) {
win.mExiting = true;
mKeyWaiter.finishedKey(session, client, true,
@@ -2215,6 +2219,7 @@
if (swin != null && (swin.mDrawPending
|| swin.mCommitDrawPending)) {
swin.mPolicyVisibility = false;
+ swin.mPolicyVisibilityAfterAnim = false;
}
}
@@ -2901,7 +2906,7 @@
final int N = mWindows.size();
for (int i=0; i<N; i++) {
WindowState w = (WindowState)mWindows.get(i);
- if (w.isVisible() && !w.isDisplayedLw()) {
+ if (w.isVisibleLw() && !w.isDisplayedLw()) {
return;
}
}
@@ -4126,7 +4131,7 @@
topErrWindow = child;
}
}
- if (!child.isVisible()) {
+ if (!child.isVisibleLw()) {
//Log.i(TAG, "Not visible!");
continue;
}
@@ -4455,7 +4460,7 @@
}
if (mLastWin == null || !mLastWin.mToken.paused
- || !mLastWin.isVisible()) {
+ || !mLastWin.isVisibleLw()) {
// If the current window has been paused, we aren't -really-
// finished... so let the waiters still wait.
mLastWin = null;
@@ -4990,6 +4995,7 @@
final boolean mIsImWindow;
int mViewVisibility;
boolean mPolicyVisibility = true;
+ boolean mPolicyVisibilityAfterAnim = true;
boolean mAppFreezing;
Surface mSurface;
boolean mAttachedHidden; // is our parent window hidden?
@@ -5634,6 +5640,7 @@
mAnimation = null;
mAnimLayer = mLayer;
mHasTransformation = false;
+ mPolicyVisibility = mPolicyVisibilityAfterAnim;
mTransformation.clear();
if (mHasDrawn
&& mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
@@ -5782,7 +5789,7 @@
* surface, or we are in the process of running an exit animation
* that will remove the surface.
*/
- boolean isVisible() {
+ public boolean isVisibleLw() {
final AppWindowToken atoken = mAppToken;
return mSurface != null && mPolicyVisibility && !mAttachedHidden
&& (atoken == null || !atoken.hiddenRequested)
@@ -5937,18 +5944,32 @@
return mHasDrawn;
}
- public void showLw() {
- if (!mPolicyVisibility) {
+ public void showLw(boolean doAnimation) {
+ if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim) {
mSurfacesChanged = true;
mPolicyVisibility = true;
+ mPolicyVisibilityAfterAnim = true;
+ if (doAnimation) {
+ applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
+ }
requestAnimationLocked(0);
}
}
- public void hideLw() {
- if (mPolicyVisibility) {
+ public void hideLw(boolean doAnimation) {
+ if (mPolicyVisibility || mPolicyVisibilityAfterAnim) {
mSurfacesChanged = true;
- mPolicyVisibility = false;
+ if (doAnimation) {
+ applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
+ if (mAnimation == null) {
+ doAnimation = false;
+ }
+ }
+ if (doAnimation) {
+ mPolicyVisibilityAfterAnim = false;
+ } else {
+ mPolicyVisibility = false;
+ }
requestAnimationLocked(0);
}
}
@@ -5974,7 +5995,8 @@
pw.println(prefix + "mTargetAppToken=" + mTargetAppToken);
pw.println(prefix + "mViewVisibility=0x" + Integer.toHexString(mViewVisibility)
+ " mPolicyVisibility=" + mPolicyVisibility
- + " mAttachedHidden=" + mAttachedHidden
+ + " (after=" + mPolicyVisibilityAfterAnim
+ + ") mAttachedHidden=" + mAttachedHidden
+ " mLastHidden=" + mLastHidden
+ " mHaveFrame=" + mHaveFrame);
pw.println(prefix + "Requested w=" + mRequestedWidth + " h=" + mRequestedHeight
@@ -7590,6 +7612,13 @@
long duration = (w.mAnimating && w.mAnimation != null)
? w.mAnimation.computeDurationHint()
: DEFAULT_DIM_DURATION;
+ if (target > mDimTargetAlpha) {
+ // This is happening behind the activity UI,
+ // so we can make it run a little longer to
+ // give a stronger impression without disrupting
+ // the user.
+ duration *= DIM_DURATION_MULTIPLIER;
+ }
mDimTargetAlpha = target;
mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha)
/ duration;
@@ -7660,6 +7689,7 @@
if (more) {
if (SHOW_TRANSACTIONS) Log.i(TAG, " DIM "
+ mDimSurface + ": alpha=" + mDimCurrentAlpha);
+ mLastDimAnimTime = currentTime;
mDimSurface.setAlpha(mDimCurrentAlpha);
animating = true;
} else {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d0c2dac..361c7f7 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -118,6 +118,7 @@
static final boolean DEBUG_SERVICE = localLOGV || false;
static final boolean DEBUG_VISBILITY = localLOGV || false;
static final boolean DEBUG_PROCESSES = localLOGV || false;
+ static final boolean DEBUG_USER_LEAVING = localLOGV || false;
static final boolean VALIDATE_TOKENS = false;
static final boolean SHOW_ACTIVITY_START_TIME = true;
@@ -327,6 +328,12 @@
boolean mBroadcastsScheduled = false;
/**
+ * Set to indicate whether to issue an onUserLeaving callback when a
+ * newly launched activity is being brought in front of us.
+ */
+ boolean mUserLeaving = false;
+
+ /**
* When we are in the process of pausing an activity, before starting the
* next one, this variable holds the activity that is currently being paused.
*/
@@ -1768,7 +1775,7 @@
}
}
- private final void startPausingLocked() {
+ private final void startPausingLocked(boolean userLeaving) {
if (mPausingActivity != null) {
RuntimeException e = new RuntimeException();
Log.e(TAG, "Trying to pause when pause is already pending for "
@@ -1795,7 +1802,7 @@
EventLog.writeEvent(LOG_AM_PAUSE_ACTIVITY,
System.identityHashCode(prev),
prev.shortComponentName);
- prev.app.thread.schedulePauseActivity(prev, prev.finishing,
+ prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving,
prev.configChangeFlags);
} catch (Exception e) {
// Ignore exception, if process died other code will cleanup.
@@ -2092,6 +2099,11 @@
// Find the first activity that is not finishing.
HistoryRecord next = topRunningActivityLocked(null);
+ // Remember how we'll process this pause/resume situation, and ensure
+ // that the state is reset however we wind up proceeding.
+ final boolean userLeaving = mUserLeaving;
+ mUserLeaving = false;
+
if (next == null) {
// There are no more activities! Let's just start up the
// Launcher...
@@ -2154,7 +2166,7 @@
// can be resumed...
if (mResumedActivity != null) {
if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: need to start pausing");
- startPausingLocked();
+ startPausingLocked(userLeaving);
return true;
}
@@ -2380,12 +2392,21 @@
}
}
+ // Place a new activity at top of stack, so it is next to interact
+ // with the user.
if (addPos < 0) {
addPos = mHistory.size();
}
- // Place activity at top of stack, so it is next to interact
- // with the user.
+ // If we are not placing the new activity frontmost, we do not want
+ // to deliver the onUserLeaving callback to the actual frontmost
+ // activity
+ if (addPos < NH) {
+ mUserLeaving = false;
+ if (DEBUG_USER_LEAVING) Log.v(TAG, "startActivity() behind front, mUserLeaving=false");
+ }
+
+ // Slot the activity into the history stack and proceed
mHistory.add(addPos, r);
r.inHistory = true;
r.frontOfTask = newTask;
@@ -2673,6 +2694,12 @@
HistoryRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
!= 0 ? r : null;
+ // We'll invoke onUserLeaving before onPause only if the launching
+ // activity did not explicitly state that this is an automated launch.
+ mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
+ if (DEBUG_USER_LEAVING) Log.v(TAG,
+ "startActivity() => mUserLeaving=" + mUserLeaving);
+
// If the onlyIfNeeded flag is set, then we can do this if the activity
// being launched is the same as the one making the call... or, as
// a special case, if we do not know the caller then we count the
@@ -3360,7 +3387,8 @@
if (mPausingActivity == null) {
if (DEBUG_PAUSE) Log.v(TAG, "Finish needs to pause: " + r);
- startPausingLocked();
+ if (DEBUG_USER_LEAVING) Log.v(TAG, "finish() => pause with userLeaving=false");
+ startPausingLocked(false);
}
} else if (r.state != ActivityState.PAUSING) {
@@ -6875,7 +6903,8 @@
// run and release the wake lock when all done.
if (mPausingActivity == null) {
if (DEBUG_PAUSE) Log.v(TAG, "Sleep needs to pause...");
- startPausingLocked();
+ if (DEBUG_USER_LEAVING) Log.v(TAG, "Sleep => pause with userLeaving=false");
+ startPausingLocked(false);
}
}
}
diff --git a/services/java/com/android/server/status/StatusBarService.java b/services/java/com/android/server/status/StatusBarService.java
index 2d2faeb..3b6e354 100644
--- a/services/java/com/android/server/status/StatusBarService.java
+++ b/services/java/com/android/server/status/StatusBarService.java
@@ -331,6 +331,7 @@
mPixelFormat);
lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
lp.setTitle("StatusBar");
+ lp.windowAnimations = R.style.Animation_StatusBar;
WindowManagerImpl.getDefault().addView(mStatusBarView, lp);
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java b/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java
index a90e7ea..c0c4ceb 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java
@@ -528,7 +528,16 @@
}
private void handleCmdResponse(StkResponseMessage resMsg) {
- // make sure the response details match the last valid command.
+ // Make sure the response details match the last valid command. An invalid
+ // response is a one that doesn't have a corresponding proactive command
+ // and sending it can "confuse" the baseband/ril.
+ // One reason for out of order responses can be UI glitches. For example,
+ // if the application launch an activity, and that activity is stored
+ // by the framework inside the history stack. That activity will be
+ // available for relaunch using the latest application dialog
+ // (long press on the home button). Relaunching that activity can send
+ // the same command's result again to the StkService and can cause it to
+ // get out of sync with the SIM.
if (!validateResponse(resMsg)) {
return;
}
@@ -578,9 +587,11 @@
break;
case SET_UP_CALL:
mCmdIf.handleCallSetupRequestFromSim(resMsg.usersConfirm, null);
- if (!resMsg.usersConfirm) {
- resMsg.resCode = ResultCode.USER_NOT_ACCEPT;
- }
+ // No need to send terminal response for SET UP CALL. The user's
+ // confirmation result is send back using a dedicated ril message
+ // invoked by the CommandInterface call above.
+ mCurrntCmd = null;
+ return;
}
break;
case NO_RESPONSE_FROM_USER:
diff --git a/test-runner/android/test/mock/MockPackageManager.java b/test-runner/android/test/mock/MockPackageManager.java
index 34ebd78..f131bf2 100644
--- a/test-runner/android/test/mock/MockPackageManager.java
+++ b/test-runner/android/test/mock/MockPackageManager.java
@@ -16,6 +16,7 @@
package android.test.mock;
+import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
@@ -304,10 +305,19 @@
* @hide - to match hiding in superclass
*/
@Override
- public void freeApplicationCache(
+ public void freeStorageAndNotify(
long idealStorageSize, IPackageDataObserver observer) {
throw new UnsupportedOperationException();
}
+
+ /**
+ * @hide - to match hiding in superclass
+ */
+ @Override
+ public void freeStorage(
+ long idealStorageSize, PendingIntent onFinishedIntent) {
+ throw new UnsupportedOperationException();
+ }
/**
* @hide - to match hiding in superclass
diff --git a/tests/AndroidTests/src/com/android/unit_tests/AppCacheTest.java b/tests/AndroidTests/src/com/android/unit_tests/AppCacheTest.java
index 914d98b..6a9ac86 100755
--- a/tests/AndroidTests/src/com/android/unit_tests/AppCacheTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/AppCacheTest.java
@@ -21,7 +21,12 @@
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
+
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageStatsObserver;
@@ -33,12 +38,13 @@
import android.test.suitebuilder.annotation.SmallTest;
import android.test.suitebuilder.annotation.Suppress;
import android.util.Log;
+import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.StatFs;
public class AppCacheTest extends AndroidTestCase {
- private static final boolean localLOGV = false;
+ private static final boolean localLOGV = true;
public static final String TAG="AppCacheTest";
public final long MAX_WAIT_TIME=60*1000;
public final long WAIT_TIME_INCR=10*1000;
@@ -471,12 +477,11 @@
boolean invokePMFreeApplicationCache(long idealStorageSize) throws Exception {
try {
-
String packageName = mContext.getPackageName();
PackageDataObserver observer = new PackageDataObserver();
//wait on observer
synchronized(observer) {
- getPm().freeApplicationCache(idealStorageSize, observer);
+ getPm().freeStorageAndNotify(idealStorageSize, observer);
long waitTime = 0;
while(!observer.isDone() || (waitTime > MAX_WAIT_TIME)) {
observer.wait(WAIT_TIME_INCR);
@@ -495,6 +500,31 @@
return false;
}
}
+
+ boolean invokePMFreeStorage(long idealStorageSize, FreeStorageReceiver r,
+ PendingIntent pi) throws Exception {
+ try {
+ // Spin lock waiting for call back
+ synchronized(r) {
+ getPm().freeStorage(idealStorageSize, pi);
+ long waitTime = 0;
+ while(!r.isDone() && (waitTime < MAX_WAIT_TIME)) {
+ r.wait(WAIT_TIME_INCR);
+ waitTime += WAIT_TIME_INCR;
+ }
+ if(!r.isDone()) {
+ throw new Exception("timed out waiting for call back from PendingIntent");
+ }
+ }
+ return r.getResultCode() == 1;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to get handle for PackageManger Exception: "+e);
+ return false;
+ } catch (InterruptedException e) {
+ Log.w(TAG, "InterruptedException :"+e);
+ return false;
+ }
+ }
@LargeTest
public void testDeleteAppCacheFiles() throws Exception {
@@ -563,6 +593,52 @@
", cache="+stats.cacheSize);
}
+ class FreeStorageReceiver extends BroadcastReceiver {
+ public static final String ACTION_FREE = "com.android.unit_tests.testcallback";
+ private boolean doneFlag = false;
+
+ public boolean isDone() {
+ return doneFlag;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if(intent.getAction().equalsIgnoreCase(ACTION_FREE)) {
+ if (localLOGV) Log.i(TAG, "Got notification: clear cache succeeded "+getResultCode());
+ synchronized (this) {
+ doneFlag = true;
+ notifyAll();
+ }
+ }
+ }
+ }
+
+ @SmallTest
+ public void testFreeStorage() throws Exception {
+ StatFs st = new StatFs("/data");
+ long blks1 = getFreeStorageBlks(st);
+ if(localLOGV) Log.i(TAG, "Available free blocks="+blks1);
+ long availableMem = getFreeStorageSize(st);
+ File cacheDir = mContext.getCacheDir();
+ assertNotNull(cacheDir);
+ createTestFiles1(cacheDir, "testtmpdir", 5);
+ long blks2 = getFreeStorageBlks(st);
+ if(localLOGV) Log.i(TAG, "Available blocks after writing test files in application cache="+blks2);
+ // Create receiver and register it
+ FreeStorageReceiver receiver = new FreeStorageReceiver();
+ mContext.registerReceiver(receiver, new IntentFilter(FreeStorageReceiver.ACTION_FREE));
+ PendingIntent pi = PendingIntent.getBroadcast(mContext,
+ 0, new Intent(FreeStorageReceiver.ACTION_FREE), 0);
+ // Invoke PackageManager api
+ invokePMFreeStorage(availableMem, receiver, pi);
+ long blks3 = getFreeStorageBlks(st);
+ if(localLOGV) Log.i(TAG, "Available blocks after freeing cache"+blks3);
+ assertEquals(receiver.getResultCode(), 1);
+ mContext.unregisterReceiver(receiver);
+ // Verify result
+ verifyTestFiles1(cacheDir, "testtmpdir", 5);
+ }
+
/* utility method used to create observer and check async call back from PackageManager.
* ClearApplicationUserData
*/
diff --git a/tests/AndroidTests/src/com/android/unit_tests/BluetoothTest.java b/tests/AndroidTests/src/com/android/unit_tests/BluetoothTest.java
index 48a02c4..21fb94b 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/BluetoothTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/BluetoothTest.java
@@ -234,30 +234,18 @@
}
Log.i(TAG, "onEnableResult(" + result + ")");
}
- public void onCreateBondingResult(String device, int res) {
- String result = "unknown";
- switch (res) {
- case BluetoothDevice.RESULT_SUCCESS:
- result = "success";
- break;
- case BluetoothDevice.RESULT_FAILURE:
- result = "FAILURE";
- break;
- }
- Log.i(TAG, "onEnableResult(" + device + ", " + result + ")");
- }
public void onGetRemoteServiceChannelResult(String device, int channel) {}
};
@SmallTest
- public void testCreateBondingWithCallback() throws Exception {
+ public void testCreateBond() throws Exception {
BluetoothDevice device =
(BluetoothDevice)getContext().getSystemService(Context.BLUETOOTH_SERVICE);
if (device == null) {
Log.i(TAG, "Device not Bluetooth capable, skipping test");
return;
}
- if (!device.createBonding("01:23:45:67:89:AB", mCallback)) {
+ if (!device.createBond("01:23:45:67:89:AB")) {
Log.e(TAG, "createBonding() failed");
}
}
@@ -286,7 +274,7 @@
Log.i(TAG, "Device not Bluetooth capable, skipping test");
return;
}
- String[] addresses = device.listBondings();
+ String[] addresses = device.listBonds();
if (addresses == null) {
Log.i(TAG, "Bluetooth disabled");
return;
@@ -363,8 +351,7 @@
filter.addAction(BluetoothIntent.REMOTE_NAME_FAILED_ACTION);
filter.addAction(BluetoothIntent.REMOTE_ALIAS_CHANGED_ACTION);
filter.addAction(BluetoothIntent.REMOTE_ALIAS_CLEARED_ACTION);
- filter.addAction(BluetoothIntent.BONDING_CREATED_ACTION);
- filter.addAction(BluetoothIntent.BONDING_REMOVED_ACTION);
+ filter.addAction(BluetoothIntent.BOND_STATE_CHANGED_ACTION);
filter.addAction(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION);
getContext().registerReceiver(
(BroadcastReceiver)new BluetoothIntentReceiver(), filter);
diff --git a/tests/FrameworkTest/res/layout/remote_view_test_good.xml b/tests/FrameworkTest/res/layout/remote_view_test_good.xml
index 92ff21c..54f4db9 100644
--- a/tests/FrameworkTest/res/layout/remote_view_test_good.xml
+++ b/tests/FrameworkTest/res/layout/remote_view_test_good.xml
@@ -47,4 +47,13 @@
<ProgressBar android:id="@+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
+
+ <ImageButton android:id="@+id/image_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <Button android:id="@+id/button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
</LinearLayout>
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/view/RemoteViewsActivityTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/RemoteViewsActivityTest.java
index 5f63178..3dcb252 100644
--- a/tests/FrameworkTest/tests/src/com/android/frameworktest/view/RemoteViewsActivityTest.java
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/RemoteViewsActivityTest.java
@@ -62,6 +62,8 @@
assertTrue("RelateiveLayout not inflated", result.findViewById(R.id.relative) != null);
assertTrue("AbsoluteLayout not inflated", result.findViewById(R.id.absolute) != null);
assertTrue("ProgressBar not inflated", result.findViewById(R.id.progress) != null);
+ assertTrue("ImageButton not inflated", result.findViewById(R.id.image_button) != null);
+ assertTrue("Button not inflated", result.findViewById(R.id.button) != null);
}
@MediumTest
diff --git a/tests/GadgetHost/AndroidManifest.xml b/tests/GadgetHost/AndroidManifest.xml
index 8da4485..eeb8979 100644
--- a/tests/GadgetHost/AndroidManifest.xml
+++ b/tests/GadgetHost/AndroidManifest.xml
@@ -17,6 +17,10 @@
</intent-filter>
</activity>
<receiver android:name="TestGadgetProvider">
+ <intent-filter>
+ <action android:name="android.gadget.action.GADGET_UPDATE" />
+ </intent-filter>
+ <meta-data android:name="android.gadget.provider" android:resource="@xml/gadget_info" />
</receiver>
</application>
</manifest>
diff --git a/tests/GadgetHost/res/xml/gadget_info.xml b/tests/GadgetHost/res/xml/gadget_info.xml
new file mode 100644
index 0000000..84d0603
--- /dev/null
+++ b/tests/GadgetHost/res/xml/gadget_info.xml
@@ -0,0 +1,7 @@
+<gadget-provider xmlns:android="http://schemas.android.com/apk/res/android"
+ android:minWidth="40dp"
+ android:minHeight="30dp"
+ android:updatePeriodMillis="30000"
+ android:initialLayout="@layout/test_gadget"
+ >
+</gadget-provider>
diff --git a/tests/GadgetHost/src/com/android/gadgethost/GadgetHostActivity.java b/tests/GadgetHost/src/com/android/gadgethost/GadgetHostActivity.java
index 323141e..38073fa 100644
--- a/tests/GadgetHost/src/com/android/gadgethost/GadgetHostActivity.java
+++ b/tests/GadgetHost/src/com/android/gadgethost/GadgetHostActivity.java
@@ -81,9 +81,6 @@
}
void addGadgetView(int gadgetId, GadgetInfo gadget) {
- // TODO: Remove this hard-coded value when the GadgetInfo is real.
- gadget.initialLayout = R.layout.test_gadget;
-
// Inflate the gadget's RemoteViews
GadgetHostView view = mHost.createView(this, gadgetId, gadget);
diff --git a/tests/GadgetHost/src/com/android/gadgethost/GadgetPickActivity.java b/tests/GadgetHost/src/com/android/gadgethost/GadgetPickActivity.java
index e8b3121..a995544 100644
--- a/tests/GadgetHost/src/com/android/gadgethost/GadgetPickActivity.java
+++ b/tests/GadgetHost/src/com/android/gadgethost/GadgetPickActivity.java
@@ -27,11 +27,14 @@
import android.widget.ListView;
import android.util.Log;
+import java.util.List;
+
public class GadgetPickActivity extends ListActivity
{
private static final String TAG = "GadgetPickActivity";
GadgetManager mGadgetManager;
+ List<GadgetInfo> mInstalled;
public GadgetPickActivity() {
mGadgetManager = GadgetManager.getInstance(this);
@@ -43,9 +46,12 @@
Bundle extras = getIntent().getExtras();
- String[] labels = new String[10];
- for (int i=0; i<labels.length; i++) {
- labels[i] = "Gadget " + (i+1);
+ List<GadgetInfo> installed = mGadgetManager.getInstalledProviders();
+ mInstalled = installed;
+ final int N = installed.size();
+ String[] labels = new String[N];
+ for (int i=0; i<N; i++) {
+ labels[i] = installed.get(i).provider.getClassName();
}
setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, labels));
@@ -54,11 +60,8 @@
@Override
public void onListItemClick(ListView l, View v, int position, long id)
{
- Log.d(TAG, "Clicked item " + position);
-
int gadgetId = mGadgetManager.allocateGadgetId(getCallingPackage());
- mGadgetManager.bindGadgetId(gadgetId, new ComponentName(
- "com.android.gadgethost", "com.android.gadgethost.TestGadgetProvider"));
+ mGadgetManager.bindGadgetId(gadgetId, mInstalled.get(position).provider);
Intent result = new Intent();
result.putExtra(GadgetManager.EXTRA_GADGET_ID, gadgetId);
diff --git a/tests/ImfTest/Android.mk b/tests/ImfTest/Android.mk
new file mode 100755
index 0000000..eb5327b
--- /dev/null
+++ b/tests/ImfTest/Android.mk
@@ -0,0 +1,15 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := ImfTest
+
+include $(BUILD_PACKAGE)
+
+# Use the following include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/ImfTest/AndroidManifest.xml b/tests/ImfTest/AndroidManifest.xml
new file mode 100755
index 0000000..85d6b0c
--- /dev/null
+++ b/tests/ImfTest/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.imftest">
+
+ <application>
+
+ <activity android:name=".samples.InputTypeActivity" android:label="Input Type Activity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER" />
+ <category android:name="android.intent.category.IMF_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".samples.ButtonActivity" android:label="Button Activity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER" />
+ <category android:name="android.intent.category.IMF_TEST" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
diff --git a/tests/ImfTest/res/layout/sample_edit_text.xml b/tests/ImfTest/res/layout/sample_edit_text.xml
new file mode 100755
index 0000000..99a5cf8
--- /dev/null
+++ b/tests/ImfTest/res/layout/sample_edit_text.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/samples/SampleCode/res/layout/baseline_1.xml
+**
+** Copyright 2007, 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="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+>
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:orientation="horizontal"
+ android:baselineAligned="false"
+ android:gravity="center_vertical"
+ >
+
+ <TextView android:id="@+id/label"
+ android:layout_width="100dip"
+ android:layout_height="wrap_content"
+ android:gravity="right|center_vertical"
+ />
+
+ <EditText android:id="@+id/data"
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="8dip"
+ />
+ </LinearLayout>
+
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dip"
+ android:background="@android:drawable/divider_horizontal_dark"
+ />
+</LinearLayout>
diff --git a/tests/ImfTest/res/values/strings.xml b/tests/ImfTest/res/values/strings.xml
new file mode 100755
index 0000000..a56c363
--- /dev/null
+++ b/tests/ImfTest/res/values/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Strings for sample activities -->
+ <string name="normal_edit_text_label">Normal</string>
+ <string name="uri_edit_text_label">Uri</string>
+ <string name="email_address_edit_text_label">Email Address</string>
+ <string name="email_subject_edit_text_label">Email Subject</string>
+ <string name="email_content_edit_text_label">Email Content</string>
+ <string name="person_name_edit_text_label">Person Name</string>
+ <string name="postal_address_edit_text_label">Postal Address</string>
+ <string name="password_edit_text_label">Password</string>
+ <string name="search_string_edit_text_label">Search String</string>
+ <string name="web_edit_text_label">Web Edit Text</string>
+ <string name="signed_number_edit_text_label">Signed Number</string>
+ <string name="decimal_number_edit_text_label">Decimal Number</string>
+ <string name="phone_number_edit_text_label">Phone Number</string>
+ <string name="normal_datetime_edit_text_label">Datetime</string>
+ <string name="date_edit_text_label">Date</string>
+ <string name="time_edit_text_label">Time</string>
+
+</resources>
diff --git a/tests/ImfTest/src/com/android/imftest/samples/ButtonActivity.java b/tests/ImfTest/src/com/android/imftest/samples/ButtonActivity.java
new file mode 100644
index 0000000..4233811
--- /dev/null
+++ b/tests/ImfTest/src/com/android/imftest/samples/ButtonActivity.java
@@ -0,0 +1,52 @@
+package com.android.imftest.samples;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
+import android.widget.Button;
+import android.widget.TextView;
+
+public class ButtonActivity extends Activity
+{
+ static boolean mKeyboardIsActive = false;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ final ButtonActivity instance = this;
+
+ final Button myButton = new Button(this);
+ myButton.setClickable(true);
+ myButton.setText("Keyboard UP!");
+ myButton.setOnClickListener(new View.OnClickListener()
+ {
+ public void onClick (View v)
+ {
+ InputMethodManager imm = InputMethodManager.getInstance(instance);
+ if (mKeyboardIsActive)
+ {
+ imm.hideSoftInputFromInputMethod(v.getWindowToken(), 0);
+ myButton.setText("Keyboard UP!");
+
+ }
+ else
+ {
+ imm.showSoftInput(null, 0);
+ myButton.setText("Keyboard DOWN!");
+ }
+
+ mKeyboardIsActive = !mKeyboardIsActive;
+ }
+ });
+
+ LinearLayout layout = new LinearLayout(this);
+ layout.setOrientation(LinearLayout.VERTICAL);
+ layout.addView(myButton);
+ setContentView(layout);
+ }
+}
diff --git a/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java b/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java
new file mode 100755
index 0000000..f7aaa7b
--- /dev/null
+++ b/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2007 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.imftest.samples;
+
+import com.android.imftest.R;
+
+import android.app.Activity;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.Button;
+import android.widget.ScrollView;
+import android.widget.TextView;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.view.ViewRoot;
+import android.view.inputmethod.EditorInfo;
+import android.content.Context;
+
+public class InputTypeActivity extends Activity {
+
+ private LinearLayout mLayout;
+ private ScrollView mScrollView;
+ private LayoutInflater mInflater;
+ private ViewGroup mParent;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mScrollView = new ScrollView(this);
+
+ mLayout = new LinearLayout(this);
+ mLayout.setOrientation(LinearLayout.VERTICAL);
+ mLayout.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.FILL_PARENT));
+
+ mInflater = getLayoutInflater();
+ mParent = mLayout;
+
+ /* Normal Edit Text */
+ mLayout.addView(buildEntryView(EditorInfo.TYPE_TEXT_VARIATION_NORMAL,
+ R.string.normal_edit_text_label));
+
+ /* Uri Edit Text */
+ mLayout.addView(buildEntryView(EditorInfo.TYPE_TEXT_VARIATION_URI,
+ R.string.uri_edit_text_label));
+
+ /* Email Address Edit Text */
+ mLayout.addView(buildEntryView(EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS,
+ R.string.email_address_edit_text_label));
+
+ /* Email Subject Text */
+ mLayout.addView(buildEntryView(EditorInfo.TYPE_TEXT_VARIATION_EMAIL_SUBJECT,
+ R.string.email_subject_edit_text_label));
+
+ /* Email Content Edit Text */
+ mLayout.addView(buildEntryView(EditorInfo.TYPE_TEXT_VARIATION_EMAIL_CONTENT,
+ R.string.email_content_edit_text_label));
+
+ /* Person Name Edit Text */
+ mLayout.addView(buildEntryView(EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME,
+ R.string.person_name_edit_text_label));
+
+ /* Postal Address Edit Text */
+ mLayout.addView(buildEntryView(EditorInfo.TYPE_TEXT_VARIATION_POSTAL_ADDRESS,
+ R.string.postal_address_edit_text_label));
+
+ /* Password Edit Text */
+ mLayout.addView(buildEntryView(EditorInfo.TYPE_TEXT_VARIATION_PASSWORD,
+ R.string.password_edit_text_label));
+
+ /* Search String Edit Text */
+ mLayout.addView(buildEntryView(EditorInfo.TYPE_TEXT_VARIATION_SEARCH_STRING,
+ R.string.search_string_edit_text_label));
+
+ /* Web Edit Text */
+ mLayout.addView(buildEntryView(EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT,
+ R.string.web_edit_text_label));
+
+ /* Signed Number Edit Text */
+ mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_NUMBER|EditorInfo.TYPE_NUMBER_FLAG_SIGNED,
+ R.string.signed_number_edit_text_label));
+
+ /* Decimal Number Edit Text */
+ mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_NUMBER|EditorInfo.TYPE_NUMBER_FLAG_DECIMAL,
+ R.string.decimal_number_edit_text_label));
+
+ /* Phone Number Edit Text */
+ mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_PHONE,
+ R.string.phone_number_edit_text_label));
+
+ /* Normal Datetime Edit Text */
+ mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_DATETIME|EditorInfo.TYPE_DATETIME_VARIATION_NORMAL,
+ R.string.normal_datetime_edit_text_label));
+
+ /* Date Edit Text */
+ mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_DATETIME|EditorInfo.TYPE_DATETIME_VARIATION_DATE,
+ R.string.date_edit_text_label));
+
+ /* Time Edit Text */
+ mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_DATETIME|EditorInfo.TYPE_DATETIME_VARIATION_TIME,
+ R.string.time_edit_text_label));
+
+ mScrollView.addView(mLayout);
+ setContentView(mScrollView);
+ }
+
+ private View buildEntryView(int inputType, int label) {
+
+
+ View view = mInflater.inflate(R.layout.sample_edit_text, mParent, false);
+
+ EditText editText = (EditText) view.findViewById(R.id.data);
+ editText.setInputType(inputType);
+
+ TextView textView = (TextView) view.findViewById(R.id.label);
+ textView.setText(label);
+
+ return view;
+ }
+
+}