Merge "Don't update 9patches on every frame."
diff --git a/api/current.xml b/api/current.xml
index b0f0b14..35c0dc6 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -2352,6 +2352,17 @@
visibility="public"
>
</field>
+<field name="alertDialogTheme"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843598"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="allContactsName"
type="int"
transient="false"
@@ -3617,6 +3628,17 @@
visibility="public"
>
</field>
+<field name="dialogTheme"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843597"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="dialogTitle"
type="int"
transient="false"
@@ -44007,6 +44029,17 @@
synchronized="false"
static="true"
final="false"
+ deprecated="deprecated"
+ visibility="public"
+>
+</method>
+<method name="getCurrentSyncs"
+ return="java.util.List<android.content.SyncInfo>"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
deprecated="not deprecated"
visibility="public"
>
@@ -54150,6 +54183,34 @@
deprecated="not deprecated"
visibility="public"
>
+<implements name="android.os.Parcelable">
+</implements>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="writeToParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="parcel" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
<field name="account"
type="android.accounts.Account"
transient="false"
@@ -236345,6 +236406,32 @@
<parameter name="listener" type="android.widget.SearchView.OnQueryChangeListener">
</parameter>
</method>
+<method name="setOnQueryTextFocusChangeListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.view.View.OnFocusChangeListener">
+</parameter>
+</method>
+<method name="setOnSuggestionSelectionListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.widget.SearchView.OnSuggestionSelectionListener">
+</parameter>
+</method>
<method name="setQuery"
return="void"
abstract="false"
@@ -236479,6 +236566,40 @@
</parameter>
</method>
</interface>
+<interface name="SearchView.OnSuggestionSelectionListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onSuggestionClicked"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="position" type="int">
+</parameter>
+</method>
+<method name="onSuggestionSelected"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="position" type="int">
+</parameter>
+</method>
+</interface>
<interface name="SectionIndexer"
abstract="true"
static="false"
diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp
index 7decf9a..0159edd 100644
--- a/cmds/app_process/app_main.cpp
+++ b/cmds/app_process/app_main.cpp
@@ -171,9 +171,9 @@
runtime.start();
}
} else {
- LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
+ LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
return 10;
}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index ee49d97..f08d88d 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1745,35 +1745,11 @@
}
/**
- * @deprecated This functionality will be removed in the future; please do
- * not use.
- *
- * Control whether this activity is required to be persistent. By default
- * activities are not persistent; setting this to true will prevent the
- * system from stopping this activity or its process when running low on
- * resources.
- *
- * <p><em>You should avoid using this method</em>, it has severe negative
- * consequences on how well the system can manage its resources. A better
- * approach is to implement an application service that you control with
- * {@link Context#startService} and {@link Context#stopService}.
- *
- * @param isPersistent Control whether the current activity must be
- * persistent, true if so, false for the normal
- * behavior.
+ * @deprecated As of {@link android.os.Build.VERSION_CODES#GINGERBREAD}
+ * this is a no-op.
*/
@Deprecated
public void setPersistent(boolean isPersistent) {
- if (mParent == null) {
- try {
- ActivityManagerNative.getDefault()
- .setPersistent(mToken, isPersistent);
- } catch (RemoteException e) {
- // Empty
- }
- } else {
- throw new RuntimeException("setPersistent() not yet supported for embedded activities");
- }
}
/**
@@ -2876,6 +2852,10 @@
* <p>This can be useful if you know that you will never show a dialog again and
* want to avoid the overhead of saving and restoring it in the future.
*
+ * <p>As of {@link android.os.Build.VERSION_CODES#GINGERBREAD}, this function
+ * will not throw an exception if you try to remove an ID that does not
+ * currently have an associated dialog.</p>
+ *
* @param id The id of the managed dialog.
*
* @see #onCreateDialog(int, Bundle)
@@ -2884,17 +2864,13 @@
* @see #dismissDialog(int)
*/
public final void removeDialog(int id) {
- if (mManagedDialogs == null) {
- return;
+ if (mManagedDialogs != null) {
+ final ManagedDialog md = mManagedDialogs.get(id);
+ if (md != null) {
+ md.mDialog.dismiss();
+ mManagedDialogs.remove(id);
+ }
}
-
- final ManagedDialog md = mManagedDialogs.get(id);
- if (md == null) {
- return;
- }
-
- md.mDialog.dismiss();
- mManagedDialogs.remove(id);
}
/**
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index b34c243..8cc6428 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -345,17 +345,6 @@
return true;
}
- case SET_PERSISTENT_TRANSACTION: {
- data.enforceInterface(IActivityManager.descriptor);
- IBinder token = data.readStrongBinder();
- boolean isPersistent = data.readInt() != 0;
- if (token != null) {
- setPersistent(token, isPersistent);
- }
- reply.writeNoException();
- return true;
- }
-
case ATTACH_APPLICATION_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IApplicationThread app = ApplicationThreadNative.asInterface(
@@ -1640,18 +1629,6 @@
data.recycle();
reply.recycle();
}
- public void setPersistent(IBinder token, boolean isPersistent) throws RemoteException
- {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- data.writeInterfaceToken(IActivityManager.descriptor);
- data.writeStrongBinder(token);
- data.writeInt(isPersistent ? 1 : 0);
- mRemote.transact(SET_PERSISTENT_TRANSACTION, data, reply, 0);
- reply.readException();
- data.recycle();
- reply.recycle();
- }
public void attachApplication(IApplicationThread app) throws RemoteException
{
Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java
index f0477e5..0a40a98 100644
--- a/core/java/android/app/AlertDialog.java
+++ b/core/java/android/app/AlertDialog.java
@@ -22,9 +22,10 @@
import android.content.DialogInterface;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
-import android.os.Build;
import android.os.Bundle;
import android.os.Message;
+import android.util.Log;
+import android.util.TypedValue;
import android.view.ContextThemeWrapper;
import android.view.KeyEvent;
import android.view.View;
@@ -58,27 +59,29 @@
private AlertController mAlert;
protected AlertDialog(Context context) {
- this(context,
- context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB
- ? com.android.internal.R.style.Theme_Holo_Dialog_Alert
- : com.android.internal.R.style.Theme_Dialog_Alert);
+ this(context, getDefaultDialogTheme(context));
}
protected AlertDialog(Context context, int theme) {
- super(context, theme);
+ super(context, theme == 0 ? getDefaultDialogTheme(context) : theme);
mAlert = new AlertController(context, this, getWindow());
}
protected AlertDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
- super(context,
- context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB
- ? com.android.internal.R.style.Theme_Holo_Dialog_Alert
- : com.android.internal.R.style.Theme_Dialog_Alert);
+ super(context, getDefaultDialogTheme(context));
setCancelable(cancelable);
setOnCancelListener(cancelListener);
mAlert = new AlertController(context, this, getWindow());
}
+ private static int getDefaultDialogTheme(Context context) {
+ TypedValue outValue = new TypedValue();
+ context.getTheme().resolveAttribute(com.android.internal.R.attr.alertDialogTheme,
+ outValue, true);
+ Log.d("AlertDialog", "getDefaultDialogTheme data " + outValue.data + " id " + outValue.resourceId);
+ return outValue.resourceId;
+ }
+
/**
* Gets one of the buttons used in the dialog.
* <p>
@@ -280,10 +283,7 @@
* Constructor using a context for this builder and the {@link AlertDialog} it creates.
*/
public Builder(Context context) {
- this(context,
- context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB
- ? com.android.internal.R.style.Theme_Holo_Dialog_Alert
- : com.android.internal.R.style.Theme_Dialog_Alert);
+ this(context, getDefaultDialogTheme(context));
}
/**
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index a178c04..526129a 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -29,6 +29,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
+import android.util.TypedValue;
import android.view.ActionMode;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
@@ -140,11 +141,14 @@
* <var>context</var>. If 0, the default dialog theme will be used.
*/
public Dialog(Context context, int theme) {
- mContext = new ContextThemeWrapper(
- context, theme == 0 ?
- (context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB
- ? com.android.internal.R.style.Theme_Holo_Dialog
- : com.android.internal.R.style.Theme_Dialog) : theme);
+ if (theme == 0) {
+ TypedValue outValue = new TypedValue();
+ context.getTheme().resolveAttribute(com.android.internal.R.attr.dialogTheme,
+ outValue, true);
+ theme = outValue.resourceId;
+ }
+
+ mContext = new ContextThemeWrapper(context, theme);
mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
Window w = PolicyManager.makeNewWindow(mContext);
mWindow = w;
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index cd229e3..c9d5448 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -116,7 +116,6 @@
public void unbroadcastIntent(IApplicationThread caller, Intent intent) throws RemoteException;
/* oneway */
public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map, boolean abortBroadcast) throws RemoteException;
- public void setPersistent(IBinder token, boolean isPersistent) throws RemoteException;
public void attachApplication(IApplicationThread app) throws RemoteException;
/* oneway */
public void activityIdle(IBinder token, Configuration config) throws RemoteException;
@@ -455,7 +454,7 @@
int REPORT_THUMBNAIL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+27;
int GET_CONTENT_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+28;
int PUBLISH_CONTENT_PROVIDERS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+29;
- int SET_PERSISTENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+30;
+
int FINISH_SUB_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+31;
int GET_RUNNING_SERVICE_CONTROL_PANEL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+32;
int START_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+33;
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 3289120..da1aac4 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -1319,12 +1319,36 @@
}
/**
- * If a sync is active returns the information about it, otherwise returns false.
+ * If a sync is active returns the information about it, otherwise returns null.
+ * <p>
* @return the SyncInfo for the currently active sync or null if one is not active.
+ * @deprecated
+ * Since multiple concurrent syncs are now supported you should use
+ * {@link #getCurrentSyncs()} to get the accurate list of current syncs.
+ * This method returns the first item from the list of current syncs
+ * or null if there are none.
*/
+ @Deprecated
public static SyncInfo getCurrentSync() {
try {
- return getContentService().getCurrentSync();
+ final List<SyncInfo> syncs = getContentService().getCurrentSyncs();
+ if (syncs.isEmpty()) {
+ return null;
+ }
+ return syncs.get(0);
+ } catch (RemoteException e) {
+ throw new RuntimeException("the ContentService should always be reachable", e);
+ }
+ }
+
+ /**
+ * Returns a list with information about all the active syncs. This list will be empty
+ * if there are no active syncs.
+ * @return a List of SyncInfo objects for the currently active syncs.
+ */
+ public static List<SyncInfo> getCurrentSyncs() {
+ try {
+ return getContentService().getCurrentSyncs();
} catch (RemoteException e) {
throw new RuntimeException("the ContentService should always be reachable", e);
}
diff --git a/core/java/android/content/ContentService.java b/core/java/android/content/ContentService.java
index fc2dfc0..afe8483 100644
--- a/core/java/android/content/ContentService.java
+++ b/core/java/android/content/ContentService.java
@@ -386,19 +386,15 @@
return false;
}
- public SyncInfo getCurrentSync() {
+ public List<SyncInfo> getCurrentSyncs() {
mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
"no permission to read the sync stats");
long identityToken = clearCallingIdentity();
try {
- SyncManager syncManager = getSyncManager();
- if (syncManager != null) {
- return syncManager.getSyncStorageEngine().getCurrentSync();
- }
+ return getSyncManager().getSyncStorageEngine().getCurrentSyncs();
} finally {
restoreCallingIdentity(identityToken);
}
- return null;
}
public SyncStatusInfo getSyncStatus(Account account, String authority) {
diff --git a/core/java/android/content/IContentService.aidl b/core/java/android/content/IContentService.aidl
index a6368d5..86a9392 100644
--- a/core/java/android/content/IContentService.aidl
+++ b/core/java/android/content/IContentService.aidl
@@ -104,7 +104,7 @@
*/
boolean isSyncActive(in Account account, String authority);
- SyncInfo getCurrentSync();
+ List<SyncInfo> getCurrentSyncs();
/**
* Returns the types of the SyncAdapters that are registered with the system.
diff --git a/core/java/android/content/SyncInfo.java b/core/java/android/content/SyncInfo.java
index 616b05f..abfe964 100644
--- a/core/java/android/content/SyncInfo.java
+++ b/core/java/android/content/SyncInfo.java
@@ -18,12 +18,13 @@
import android.accounts.Account;
import android.os.Parcel;
+import android.os.Parcelable;
import android.os.Parcelable.Creator;
/**
* Information about the sync operation that is currently underway.
*/
-public class SyncInfo {
+public class SyncInfo implements Parcelable {
/** @hide */
public final int authorityId;
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index 487f6ce..0639573 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -95,7 +95,7 @@
public static final long NOT_IN_BACKOFF_MODE = -1;
- private static final Intent SYNC_CONNECTION_SETTING_CHANGED_INTENT =
+ public static final Intent SYNC_CONNECTION_SETTING_CHANGED_INTENT =
new Intent("com.android.sync.SYNC_CONN_STATUS_CHANGED");
// TODO: i18n -- grab these out of resources.
@@ -1088,23 +1088,6 @@
}
/**
- * Return the currently active sync information, or null if there is no
- * active sync. Note that the returned object is the real, live active
- * sync object, so be careful what you do with it.
- * <p>
- * Since multiple concurrent syncs are now supported you should use
- * {@link #getCurrentSyncs()} to get the accurate list of current syncs.
- * This method returns the first item from the list of current syncs
- * or null if there are none.
- * @deprecated use {@link #getCurrentSyncs()}
- */
- public SyncInfo getCurrentSync() {
- synchronized (mAuthorities) {
- return !mCurrentSyncs.isEmpty() ? mCurrentSyncs.get(0) : null;
- }
- }
-
- /**
* Return a list of the currently active syncs. Note that the returned items are the
* real, live active sync objects, so be careful what you do with it.
*/
diff --git a/core/java/android/database/sqlite/SQLiteCursor.java b/core/java/android/database/sqlite/SQLiteCursor.java
index 89e8ab7..aba37a4 100644
--- a/core/java/android/database/sqlite/SQLiteCursor.java
+++ b/core/java/android/database/sqlite/SQLiteCursor.java
@@ -416,8 +416,10 @@
// BEGIN STOPSHIP remove the following line
t = new RequeryOnUiThreadException(packageName);
// END STOPSHIP
- Log.w(TAG, "should not attempt requery on main (UI) thread: app = " +
- packageName == null ? "'unknown'" : packageName, t);
+ String s = packageName == null ? "'unknown'" : packageName;
+ Log.w(TAG, "should not attempt requery on main (UI) thread: app = " + s +
+ " (database: " + mQuery.mDatabase.getPath() +
+ ", query: " + mQuery.mSql + ")", t);
}
}
}
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index a98a305..0e921e9 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -2114,7 +2114,14 @@
return;
}
- if (!mCacheFullWarning && mCompiledQueries.size() == mMaxSqlCacheSize) {
+ int maxCacheSz = (mConnectionNum == 0) ? mMaxSqlCacheSize :
+ mParentConnObj.mMaxSqlCacheSize;
+ boolean printWarning =
+ (mConnectionNum == 0)
+ ? (!mCacheFullWarning && mCompiledQueries.size() == maxCacheSz)
+ : (!mParentConnObj.mCacheFullWarning &&
+ mParentConnObj.mCompiledQueries.size() == maxCacheSz);
+ if (printWarning) {
/*
* cache size of {@link #mMaxSqlCacheSize} is not enough for this app.
* log a warning.
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 7b930d5..a27ba84 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -1354,8 +1354,23 @@
/**
* Sets the dimensions for preview pictures.
*
+ * The sides of width and height are based on camera orientation. That
+ * is, the preview size is the size before it is rotated by display
+ * orientation. So applications need to consider the display orientation
+ * while setting preview size. For example, suppose the camera supports
+ * both 480x320 and 320x480 preview sizes. The application wants a 3:2
+ * preview ratio. If the display orientation is set to 0 or 180, preview
+ * size should be set to 480x320. If the display orientation is set to
+ * 90 or 270, preview size should be set to 320x480. The display
+ * orientation should also be considered while setting picture size and
+ * thumbnail size.
+ *
* @param width the width of the pictures, in pixels
* @param height the height of the pictures, in pixels
+ * @see #setDisplayOrientation(int)
+ * @see #getCameraInfo(int, CameraInfo)
+ * @see #setPictureSize(int, int)
+ * @see #setJpegThumbnailSize(int, int)
*/
public void setPreviewSize(int width, int height) {
String v = Integer.toString(width) + "x" + Integer.toString(height);
@@ -1389,8 +1404,12 @@
* applications set both width and height to 0, EXIF will not contain
* thumbnail.
*
+ * Applications need to consider the display orientation. See {@link
+ * #setPreviewSize(int,int)} for reference.
+ *
* @param width the width of the thumbnail, in pixels
* @param height the height of the thumbnail, in pixels
+ * @see #setPreviewSize(int,int)
*/
public void setJpegThumbnailSize(int width, int height) {
set(KEY_JPEG_THUMBNAIL_WIDTH, width);
@@ -1606,8 +1625,13 @@
/**
* Sets the dimensions for pictures.
*
+ * Applications need to consider the display orientation. See {@link
+ * #setPreviewSize(int,int)} for reference.
+ *
* @param width the width for pictures, in pixels
* @param height the height for pictures, in pixels
+ * @see #setPreviewSize(int,int)
+ *
*/
public void setPictureSize(int width, int height) {
String v = Integer.toString(width) + "x" + Integer.toString(height);
diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java
index cb302da..3f03a2a 100644
--- a/core/java/android/net/LinkAddress.java
+++ b/core/java/android/net/LinkAddress.java
@@ -34,26 +34,26 @@
private final InetAddress address;
/**
- * Network prefix
+ * Network prefix length
*/
- private final int prefix;
+ private final int prefixLength;
public LinkAddress(InetAddress address, InetAddress mask) {
this.address = address;
- this.prefix = computeprefix(mask);
+ this.prefixLength = computeprefixLength(mask);
}
- public LinkAddress(InetAddress address, int prefix) {
+ public LinkAddress(InetAddress address, int prefixLength) {
this.address = address;
- this.prefix = prefix;
+ this.prefixLength = prefixLength;
}
public LinkAddress(InterfaceAddress interfaceAddress) {
this.address = interfaceAddress.getAddress();
- this.prefix = interfaceAddress.getNetworkPrefixLength();
+ this.prefixLength = interfaceAddress.getNetworkPrefixLength();
}
- private static int computeprefix(InetAddress mask) {
+ private static int computeprefixLength(InetAddress mask) {
int count = 0;
for (byte b : mask.getAddress()) {
for (int i = 0; i < 8; ++i) {
@@ -67,12 +67,12 @@
@Override
public String toString() {
- return (address == null ? "" : (address.getHostAddress() + "/" + prefix));
+ return (address == null ? "" : (address.getHostAddress() + "/" + prefixLength));
}
/**
* Compares this {@code LinkAddress} instance against the specified address
- * in {@code obj}. Two addresses are equal if their InetAddress and prefix
+ * in {@code obj}. Two addresses are equal if their InetAddress and prefixLength
* are equal
*
* @param obj the object to be tested for equality.
@@ -85,7 +85,7 @@
}
LinkAddress linkAddress = (LinkAddress) obj;
return this.address.equals(linkAddress.address) &&
- this.prefix == linkAddress.prefix;
+ this.prefixLength == linkAddress.prefixLength;
}
/**
@@ -98,8 +98,8 @@
/**
* Get network prefix length
*/
- public int getNetworkPrefix() {
- return prefix;
+ public int getNetworkPrefixLength() {
+ return prefixLength;
}
/**
@@ -118,7 +118,7 @@
if (address != null) {
dest.writeByte((byte)1);
dest.writeByteArray(address.getAddress());
- dest.writeInt(prefix);
+ dest.writeInt(prefixLength);
} else {
dest.writeByte((byte)0);
}
@@ -132,14 +132,14 @@
new Creator<LinkAddress>() {
public LinkAddress createFromParcel(Parcel in) {
InetAddress address = null;
- int prefix = 0;
+ int prefixLength = 0;
if (in.readByte() == 1) {
try {
address = InetAddress.getByAddress(in.createByteArray());
- prefix = in.readInt();
+ prefixLength = in.readInt();
} catch (UnknownHostException e) { }
}
- return new LinkAddress(address, prefix);
+ return new LinkAddress(address, prefixLength);
}
public LinkAddress[] newArray(int size) {
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 01004c2..6b1fe99 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -146,6 +146,57 @@
}
/**
+ * Convert a IPv4 address from an InetAddress to an integer
+ * @param inetAddr is an InetAddress corresponding to the IPv4 address
+ * @return the IP address as an integer in network byte order
+ */
+ public static int inetAddressToInt(InetAddress inetAddr)
+ throws IllegalArgumentException {
+ byte [] addr = inetAddr.getAddress();
+ if (addr.length != 4) {
+ throw new IllegalArgumentException("Not an IPv4 address");
+ }
+ return ((addr[3] & 0xff) << 24) | ((addr[2] & 0xff) << 16) |
+ ((addr[1] & 0xff) << 8) | (addr[0] & 0xff);
+ }
+
+ /**
+ * Convert a network prefix length to an IPv4 netmask integer
+ * @param prefixLength
+ * @return the IPv4 netmask as an integer in network byte order
+ */
+ public static int prefixLengthToNetmaskInt(int prefixLength)
+ throws IllegalArgumentException {
+ if (prefixLength < 0 || prefixLength > 32) {
+ throw new IllegalArgumentException("Invalid prefix length (0 <= prefix <= 32)");
+ }
+ int value = 0xffffffff << (32 - prefixLength);
+ return Integer.reverseBytes(value);
+ }
+
+ public static boolean isIpAddress(String address) {
+ //TODO: Add NetworkUtils support for IPv6 configuration and
+ //remove IPv4 validation and use a generic InetAddress validation
+ try {
+ String[] parts = address.split("\\.");
+ if (parts.length != 4) {
+ return false;
+ }
+ int a = Integer.parseInt(parts[0]);
+ if (a < 0 || a > 255) return false;
+ a = Integer.parseInt(parts[1]);
+ if (a < 0 || a > 255) return false;
+ a = Integer.parseInt(parts[2]);
+ if (a < 0 || a > 255) return false;
+ a = Integer.parseInt(parts[3]);
+ if (a < 0 || a > 255) return false;
+ } catch (NumberFormatException ex) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
* Add a default route through the specified gateway.
* @param interfaceName interface on which the route should be added
* @param gw the IP address of the gateway to which the route is desired,
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index b87dbc5..3de7962 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -215,6 +215,49 @@
}
/**
+ * Return a string for the EGL error code, or the hex representation
+ * if an unknown error.
+ * @param error EGL error.
+ * @return Error string.
+ */
+ static String getEGLErrorString(int error) {
+ switch (error) {
+ case EGL10.EGL_SUCCESS:
+ return "EGL_SUCCESS";
+ case EGL10.EGL_NOT_INITIALIZED:
+ return "EGL_NOT_INITIALIZED";
+ case EGL10.EGL_BAD_ACCESS:
+ return "EGL_BAD_ACCESS";
+ case EGL10.EGL_BAD_ALLOC:
+ return "EGL_BAD_ALLOC";
+ case EGL10.EGL_BAD_ATTRIBUTE:
+ return "EGL_BAD_ATTRIBUTE";
+ case EGL10.EGL_BAD_CONFIG:
+ return "EGL_BAD_CONFIG";
+ case EGL10.EGL_BAD_CONTEXT:
+ return "EGL_BAD_CONTEXT";
+ case EGL10.EGL_BAD_CURRENT_SURFACE:
+ return "EGL_BAD_CURRENT_SURFACE";
+ case EGL10.EGL_BAD_DISPLAY:
+ return "EGL_BAD_DISPLAY";
+ case EGL10.EGL_BAD_MATCH:
+ return "EGL_BAD_MATCH";
+ case EGL10.EGL_BAD_NATIVE_PIXMAP:
+ return "EGL_BAD_NATIVE_PIXMAP";
+ case EGL10.EGL_BAD_NATIVE_WINDOW:
+ return "EGL_BAD_NATIVE_WINDOW";
+ case EGL10.EGL_BAD_PARAMETER:
+ return "EGL_BAD_PARAMETER";
+ case EGL10.EGL_BAD_SURFACE:
+ return "EGL_BAD_SURFACE";
+ case EGL11.EGL_CONTEXT_LOST:
+ return "EGL_CONTEXT_LOST";
+ default:
+ return "0x" + Integer.toHexString(error);
+ }
+ }
+
+ /**
* Checks for OpenGL errors. If an error has occured, {@link #destroy(boolean)}
* is invoked and the requested flag is turned off. The error code is
* also logged as a warning.
@@ -230,7 +273,7 @@
// we'll try again if it was context lost
setRequested(false);
}
- Log.w(LOG_TAG, "EGL error: " + Integer.toHexString(error));
+ Log.w(LOG_TAG, "EGL error: " + getEGLErrorString(error));
}
}
}
@@ -276,13 +319,15 @@
sEglDisplay = sEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
if (sEglDisplay == EGL10.EGL_NO_DISPLAY) {
- throw new RuntimeException("eglGetDisplay failed");
+ throw new RuntimeException("eglGetDisplay failed "
+ + getEGLErrorString(sEgl.eglGetError()));
}
// We can now initialize EGL for that display
int[] version = new int[2];
if (!sEgl.eglInitialize(sEglDisplay, version)) {
- throw new RuntimeException("eglInitialize failed");
+ throw new RuntimeException("eglInitialize failed "
+ + getEGLErrorString(sEgl.eglGetError()));
}
sEglConfig = getConfigChooser(mGlVersion).chooseConfig(sEgl, sEglDisplay);
@@ -332,7 +377,8 @@
Log.e("EglHelper", "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
return null;
}
- throw new RuntimeException("createWindowSurface failed");
+ throw new RuntimeException("createWindowSurface failed "
+ + getEGLErrorString(error));
}
/*
@@ -340,7 +386,8 @@
* the context is current and bound to a surface.
*/
if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, sEglContext)) {
- throw new RuntimeException("eglMakeCurrent failed");
+ throw new RuntimeException("eglMakeCurrent failed "
+ + getEGLErrorString(sEgl.eglGetError()));
}
return sEglContext.getGL();
@@ -454,7 +501,8 @@
if (sEgl.eglGetCurrentContext() != sEglContext ||
sEgl.eglGetCurrentSurface(EGL10.EGL_DRAW) != mEglSurface) {
if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, sEglContext)) {
- throw new RuntimeException("eglMakeCurrent failed");
+ throw new RuntimeException("eglMakeCurrent failed "
+ + getEGLErrorString(sEgl.eglGetError()));
}
}
}
@@ -471,7 +519,8 @@
EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
int[] index = new int[1];
if (!egl.eglChooseConfig(display, mConfigSpec, null, 0, index)) {
- throw new IllegalArgumentException("eglChooseConfig failed");
+ throw new IllegalArgumentException("eglChooseConfig failed "
+ + getEGLErrorString(egl.eglGetError()));
}
int numConfigs = index[0];
@@ -481,7 +530,8 @@
EGLConfig[] configs = new EGLConfig[numConfigs];
if (!egl.eglChooseConfig(display, mConfigSpec, configs, numConfigs, index)) {
- throw new IllegalArgumentException("eglChooseConfig failed");
+ throw new IllegalArgumentException("eglChooseConfig failed "
+ + getEGLErrorString(egl.eglGetError()));
}
EGLConfig config = chooseConfig(egl, display, configs);
diff --git a/core/java/android/view/InputQueue.java b/core/java/android/view/InputQueue.java
index 43c957a..9e800df 100644
--- a/core/java/android/view/InputQueue.java
+++ b/core/java/android/view/InputQueue.java
@@ -28,8 +28,21 @@
private static final boolean DEBUG = false;
+ /**
+ * Interface to receive notification of when an InputQueue is associated
+ * and dissociated with a thread.
+ */
public static interface Callback {
+ /**
+ * Called when the given InputQueue is now associated with the
+ * thread making this call, so it can start receiving events from it.
+ */
void onInputQueueCreated(InputQueue queue);
+
+ /**
+ * Called when the given InputQueue is no longer associated with
+ * the thread and thus not dispatching events.
+ */
void onInputQueueDestroyed(InputQueue queue);
}
diff --git a/core/java/android/view/WindowOrientationListener.java b/core/java/android/view/WindowOrientationListener.java
index 3e2e92b..2a76e33 100755
--- a/core/java/android/view/WindowOrientationListener.java
+++ b/core/java/android/view/WindowOrientationListener.java
@@ -109,7 +109,9 @@
}
public void setAllow180Rotation(boolean allowed) {
- mSensorEventListener.setAllow180Rotation(allowed);
+ if (mSensorEventListener != null) {
+ mSensorEventListener.setAllow180Rotation(allowed);
+ }
}
public int getCurrentRotation(int lastRotation) {
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index b00f88c..8c9f266 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -710,6 +710,9 @@
break;
case ADD_MESSAGE_TO_CONSOLE:
+ if (mWebChromeClient == null) {
+ break;
+ }
String message = msg.getData().getString("message");
String sourceID = msg.getData().getString("sourceID");
int lineNumber = msg.getData().getInt("lineNumber");
@@ -786,7 +789,9 @@
host, realm, username, password);
break;
case SET_INSTALLABLE_WEBAPP:
- mWebChromeClient.setInstallableWebApp();
+ if (mWebChromeClient != null) {
+ mWebChromeClient.setInstallableWebApp();
+ }
break;
}
}
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index dd67197..cfd6754 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -56,6 +56,8 @@
private OnQueryChangeListener mOnQueryChangeListener;
private OnCloseListener mOnCloseListener;
+ private OnFocusChangeListener mOnQueryTextFocusChangeListener;
+ private OnSuggestionSelectionListener mOnSuggestionListener;
private boolean mIconifiedByDefault;
private boolean mIconified;
@@ -68,6 +70,7 @@
private boolean mSubmitButtonEnabled;
private CharSequence mQueryHint;
private boolean mQueryRefinement;
+ private boolean mClearingFocus;
private SearchableInfo mSearchable;
@@ -117,6 +120,32 @@
boolean onClose();
}
+ /**
+ * Callback interface for selection events on suggestions. These callbacks
+ * are only relevant when a SearchableInfo has been specified by {@link #setSearchableInfo}.
+ */
+ public interface OnSuggestionSelectionListener {
+
+ /**
+ * Called when a suggestion was selected by navigating to it.
+ * @param position the absolute position in the list of suggestions.
+ *
+ * @return true if the listener handles the event and wants to override the default
+ * behavior of possibly rewriting the query based on the selected item, false otherwise.
+ */
+ boolean onSuggestionSelected(int position);
+
+ /**
+ * Called when a suggestion was clicked.
+ * @param position the absolute position of the clicked item in the list of suggestions.
+ *
+ * @return true if the listener handles the event and wants to override the default
+ * behavior of launching any intent or submitting a search query specified on that item.
+ * Return false otherwise.
+ */
+ boolean onSuggestionClicked(int position);
+ }
+
public SearchView(Context context) {
this(context, null);
}
@@ -141,6 +170,15 @@
mQueryTextView.setOnEditorActionListener(mOnEditorActionListener);
mQueryTextView.setOnItemClickListener(mOnItemClickListener);
mQueryTextView.setOnItemSelectedListener(mOnItemSelectedListener);
+ // Inform any listener of focus changes
+ mQueryTextView.setOnFocusChangeListener(new OnFocusChangeListener() {
+
+ public void onFocusChange(View v, boolean hasFocus) {
+ if (mOnQueryTextFocusChangeListener != null) {
+ mOnQueryTextFocusChangeListener.onFocusChange(SearchView.this, hasFocus);
+ }
+ }
+ });
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SearchView, 0, 0);
setIconifiedByDefault(a.getBoolean(R.styleable.SearchView_iconifiedByDefault, true));
@@ -165,6 +203,27 @@
updateViewsVisibility(mIconifiedByDefault);
}
+ /** @hide */
+ @Override
+ public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
+ if (mClearingFocus) return false;
+ boolean result = mQueryTextView.requestFocus(direction, previouslyFocusedRect);
+ if (result && !isIconified()) {
+ setImeVisibility(true);
+ }
+ return result;
+ }
+
+ /** @hide */
+ @Override
+ public void clearFocus() {
+ mClearingFocus = true;
+ super.clearFocus();
+ mQueryTextView.clearFocus();
+ setImeVisibility(false);
+ mClearingFocus = false;
+ }
+
/**
* Sets a listener for user actions within the SearchView.
*
@@ -185,6 +244,24 @@
}
/**
+ * Sets a listener to inform when the focus of the query text field changes.
+ *
+ * @param listener the listener to inform of focus changes.
+ */
+ public void setOnQueryTextFocusChangeListener(OnFocusChangeListener listener) {
+ mOnQueryTextFocusChangeListener = listener;
+ }
+
+ /**
+ * Sets a listener to inform when a suggestion is focused or clicked.
+ *
+ * @param listener the listener to inform of suggestion selection events.
+ */
+ public void setOnSuggestionSelectionListener(OnSuggestionSelectionListener listener) {
+ mOnSuggestionListener = listener;
+ }
+
+ /**
* Sets a query string in the text field and optionally submits the query as well.
*
* @param query the query string. This replaces any query text already present in the
@@ -224,6 +301,7 @@
public void setIconifiedByDefault(boolean iconified) {
mIconifiedByDefault = iconified;
updateViewsVisibility(iconified);
+ setImeVisibility(!iconified);
}
/**
@@ -340,28 +418,25 @@
final int visCollapsed = collapsed ? VISIBLE : GONE;
// Visibility of views that are visible when expanded
final int visExpanded = collapsed ? GONE : VISIBLE;
+ // Is there text in the query
+ final boolean hasText = !TextUtils.isEmpty(mQueryTextView.getText());
mSearchButton.setVisibility(visCollapsed);
- mSubmitButton.setVisibility(mSubmitButtonEnabled ? visExpanded : GONE);
+ mSubmitButton.setVisibility(mSubmitButtonEnabled && hasText ? visExpanded : GONE);
mSearchEditFrame.setVisibility(visExpanded);
-
- setImeVisibility(!collapsed);
}
private void setImeVisibility(boolean visible) {
- // don't mess with the soft input if we're not iconified by default
- if (mIconifiedByDefault) {
- InputMethodManager imm = (InputMethodManager)
- getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+ InputMethodManager imm = (InputMethodManager)
+ getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
- // We made sure the IME was displayed, so also make sure it is closed
- // when we go away.
- if (imm != null) {
- if (visible) {
- imm.showSoftInputUnchecked(0, null);
- } else {
- imm.hideSoftInputFromWindow(getWindowToken(), 0);
- }
+ // We made sure the IME was displayed, so also make sure it is closed
+ // when we go away.
+ if (imm != null) {
+ if (visible) {
+ imm.showSoftInputUnchecked(0, null);
+ } else {
+ imm.hideSoftInputFromWindow(getWindowToken(), 0);
}
}
}
@@ -478,6 +553,7 @@
|| !mOnQueryChangeListener.onSubmitQuery(query.toString())) {
if (mSearchable != null) {
launchQuerySearch(KeyEvent.KEYCODE_UNKNOWN, null, query.toString());
+ setImeVisibility(false);
}
}
}
@@ -485,7 +561,14 @@
private void onCloseClicked() {
if (mOnCloseListener == null || !mOnCloseListener.onClose()) {
- mQueryTextView.setText("");
+ CharSequence text = mQueryTextView.getText();
+ if (TextUtils.isEmpty(text)) {
+ // query field already empty, hide the keyboard and remove focus
+ mQueryTextView.clearFocus();
+ setImeVisibility(false);
+ } else {
+ mQueryTextView.setText("");
+ }
updateViewsVisibility(mIconifiedByDefault);
}
}
@@ -493,6 +576,7 @@
private void onSearchClicked() {
mQueryTextView.requestFocus();
updateViewsVisibility(false);
+ setImeVisibility(true);
}
private final OnItemClickListener mOnItemClickListener = new OnItemClickListener() {
@@ -503,7 +587,10 @@
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (DBG)
Log.d(LOG_TAG, "onItemClick() position " + position);
- launchSuggestion(position, KeyEvent.KEYCODE_UNKNOWN, null);
+ if (mOnSuggestionListener == null
+ || !mOnSuggestionListener.onSuggestionClicked(position)) {
+ launchSuggestion(position, KeyEvent.KEYCODE_UNKNOWN, null);
+ }
}
};
@@ -517,7 +604,10 @@
Log.d(LOG_TAG, "onItemSelected() position " + position);
// A suggestion has been selected, rewrite the query if possible,
// otherwise the restore the original query.
- rewriteQueryFromSuggestion(position);
+ if (mOnSuggestionListener == null
+ || !mOnSuggestionListener.onSuggestionSelected(position)) {
+ rewriteQueryFromSuggestion(position);
+ }
}
/**
@@ -722,13 +812,4 @@
public void afterTextChanged(Editable s) {
}
};
-
- /*
- * Avoid getting focus when searching for something to focus on.
- * The user will have to touch the text view to get focus.
- */
- protected boolean onRequestFocusInDescendants(int direction,
- Rect previouslyFocusedRect) {
- return false;
- }
- }
+}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index d63af4e..66777b9 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -293,9 +293,13 @@
}
InputMethodState mInputMethodState;
- private int mTextSelectHandleLeftRes;
- private int mTextSelectHandleRightRes;
- private int mTextSelectHandleRes;
+ int mTextSelectHandleLeftRes;
+ int mTextSelectHandleRightRes;
+ int mTextSelectHandleRes;
+
+ Drawable mSelectHandleLeft;
+ Drawable mSelectHandleRight;
+ Drawable mSelectHandleCenter;
/*
* Kick-start the font cache for the zygote process (to pay the cost of
@@ -4364,6 +4368,7 @@
switch (keyCode) {
case KeyEvent.KEYCODE_ENTER:
+ mEnterKeyIsDown = true;
// If ALT modifier is held, then we always insert a
// newline character.
if ((event.getMetaState()&KeyEvent.META_ALT_ON) == 0) {
@@ -4396,6 +4401,7 @@
break;
case KeyEvent.KEYCODE_DPAD_CENTER:
+ mDPadCenterIsDown = true;
if (shouldAdvanceFocusOnEnter()) {
return 0;
}
@@ -4490,6 +4496,7 @@
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
+ mDPadCenterIsDown = false;
/*
* If there is a click listener, just call through to
* super, which will invoke it.
@@ -4510,6 +4517,7 @@
return super.onKeyUp(keyCode, event);
case KeyEvent.KEYCODE_ENTER:
+ mEnterKeyIsDown = false;
if (mInputContentType != null
&& mInputContentType.onEditorActionListener != null
&& mInputContentType.enterDown) {
@@ -7288,9 +7296,21 @@
}
// Two ints packed in a long
+ return packRangeInLong(start, end);
+ }
+
+ private static long packRangeInLong(int start, int end) {
return (((long) start) << 32) | end;
}
+ private static int extractRangeStartFromLong(long range) {
+ return (int) (range >>> 32);
+ }
+
+ private static int extractRangeEndFromLong(long range) {
+ return (int) (range & 0x00000000FFFFFFFFL);
+ }
+
private void selectCurrentWord() {
// In case selection mode is started after an orientation change or after a select all,
// use the current selection instead of creating one
@@ -7298,67 +7318,31 @@
return;
}
- int selectionStart, selectionEnd;
+ int minOffset, maxOffset;
- // selectionModifierCursorController is not null at that point
- SelectionModifierCursorController selectionModifierCursorController =
- ((SelectionModifierCursorController) mSelectionModifierCursorController);
- int minOffset = selectionModifierCursorController.getMinTouchOffset();
- int maxOffset = selectionModifierCursorController.getMaxTouchOffset();
-
- if (minOffset == maxOffset) {
- int offset = Math.max(0, Math.min(minOffset, mTransformed.length()));
-
- // Tolerance, number of charaters around tapped position
- final int range = 1;
- final int max = mTransformed.length() - 1;
-
- // 'Smart' word selection: detect position between words
- for (int i = -range; i <= range; i++) {
- int index = offset + i;
- if (index >= 0 && index <= max) {
- if (Character.isSpaceChar(mTransformed.charAt(index))) {
- // Select current space
- selectionStart = index;
- selectionEnd = selectionStart + 1;
-
- // Extend selection to maximum space range
- while (selectionStart > 0 &&
- Character.isSpaceChar(mTransformed.charAt(selectionStart - 1))) {
- selectionStart--;
- }
- while (selectionEnd < max &&
- Character.isSpaceChar(mTransformed.charAt(selectionEnd))) {
- selectionEnd++;
- }
-
- Selection.setSelection((Spannable) mText, selectionStart, selectionEnd);
- return;
- }
- }
- }
-
- // 'Smart' word selection: detect position at beginning or end of text.
- if (offset <= range) {
- Selection.setSelection((Spannable) mText, 0, 0);
- return;
- }
- if (offset >= (max - range)) {
- Selection.setSelection((Spannable) mText, max + 1, max + 1);
- return;
- }
+ if (mDPadCenterIsDown || mEnterKeyIsDown) {
+ minOffset = getSelectionStart();
+ maxOffset = getSelectionEnd();
+ } else {
+ // selectionModifierCursorController is not null at that point
+ SelectionModifierCursorController selectionModifierCursorController =
+ ((SelectionModifierCursorController) mSelectionModifierCursorController);
+ minOffset = selectionModifierCursorController.getMinTouchOffset();
+ maxOffset = selectionModifierCursorController.getMaxTouchOffset();
}
+ int selectionStart, selectionEnd;
+
long wordLimits = getWordLimitsAt(minOffset);
if (wordLimits >= 0) {
- selectionStart = (int) (wordLimits >>> 32);
+ selectionStart = extractRangeStartFromLong(wordLimits);
} else {
selectionStart = Math.max(minOffset - 5, 0);
}
wordLimits = getWordLimitsAt(maxOffset);
if (wordLimits >= 0) {
- selectionEnd = (int) (wordLimits & 0x00000000FFFFFFFFL);
+ selectionEnd = extractRangeEndFromLong(wordLimits);
} else {
selectionEnd = Math.min(maxOffset + 5, mText.length());
}
@@ -7487,7 +7471,6 @@
switch (id) {
case ID_COPY_URL:
-
URLSpan[] urls = ((Spanned) mText).getSpans(min, max, URLSpan.class);
if (urls.length >= 1) {
ClipData clip = null;
@@ -7513,6 +7496,49 @@
return false;
}
+ /**
+ * Prepare text so that there are not zero or two spaces at beginning and end of region defined
+ * by [min, max] when replacing this region by paste.
+ */
+ private long prepareSpacesAroundPaste(int min, int max, CharSequence paste) {
+ // Paste adds/removes spaces before or after insertion as needed.
+ if (Character.isSpaceChar(paste.charAt(0))) {
+ if (min > 0 && Character.isSpaceChar(mTransformed.charAt(min - 1))) {
+ // Two spaces at beginning of paste: remove one
+ final int originalLength = mText.length();
+ ((Editable) mText).replace(min - 1, min, "");
+ // Due to filters, there is no garantee that exactly one character was
+ // removed. Count instead.
+ final int delta = mText.length() - originalLength;
+ min += delta;
+ max += delta;
+ }
+ } else {
+ if (min > 0 && !Character.isSpaceChar(mTransformed.charAt(min - 1))) {
+ // No space at beginning of paste: add one
+ final int originalLength = mText.length();
+ ((Editable) mText).replace(min, min, " ");
+ // Taking possible filters into account as above.
+ final int delta = mText.length() - originalLength;
+ min += delta;
+ max += delta;
+ }
+ }
+
+ if (Character.isSpaceChar(paste.charAt(paste.length() - 1))) {
+ if (max < mText.length() && Character.isSpaceChar(mTransformed.charAt(max))) {
+ // Two spaces at end of paste: remove one
+ ((Editable) mText).replace(max, max + 1, "");
+ }
+ } else {
+ if (max < mText.length() && !Character.isSpaceChar(mTransformed.charAt(max))) {
+ // No space at end of paste: add one
+ ((Editable) mText).replace(max, max, " ");
+ }
+ }
+ return packRangeInLong(min, max);
+ }
+
@Override
public boolean performLongClick() {
if (super.performLongClick()) {
@@ -7704,6 +7730,9 @@
CharSequence paste = clip.getItem(i).coerceToText(getContext());
if (paste != null) {
if (!didfirst) {
+ long minMax = prepareSpacesAroundPaste(min, max, paste);
+ min = extractRangeStartFromLong(minMax);
+ max = extractRangeEndFromLong(minMax);
Selection.setSelection((Spannable) mText, max);
((Editable) mText).replace(min, max, paste);
} else {
@@ -7714,7 +7743,6 @@
}
stopSelectionActionMode();
}
-
return true;
case ID_CUT:
@@ -7790,26 +7818,74 @@
private int mPositionY;
private CursorController mController;
private boolean mIsDragging;
- private float mOffsetX;
- private float mOffsetY;
+ private float mTouchToWindowOffsetX;
+ private float mTouchToWindowOffsetY;
private float mHotspotX;
private float mHotspotY;
+ private int mHeight;
+ private float mTouchOffsetY;
private int mLastParentX;
private int mLastParentY;
- public HandleView(CursorController controller, Drawable handle) {
+ public static final int LEFT = 0;
+ public static final int CENTER = 1;
+ public static final int RIGHT = 2;
+
+ public HandleView(CursorController controller, int pos) {
super(TextView.this.mContext);
mController = controller;
- mDrawable = handle;
mContainer = new PopupWindow(TextView.this.mContext, null,
com.android.internal.R.attr.textSelectHandleWindowStyle);
mContainer.setSplitTouchEnabled(true);
mContainer.setClippingEnabled(false);
- final int handleWidth = mDrawable.getIntrinsicWidth();
+ setOrientation(pos);
+ }
+
+ public void setOrientation(int pos) {
+ int handleWidth;
+ switch (pos) {
+ case LEFT: {
+ if (mSelectHandleLeft == null) {
+ mSelectHandleLeft = mContext.getResources().getDrawable(
+ mTextSelectHandleLeftRes);
+ }
+ mDrawable = mSelectHandleLeft;
+ handleWidth = mDrawable.getIntrinsicWidth();
+ mHotspotX = handleWidth / 4 * 3;
+ break;
+ }
+
+ case RIGHT: {
+ if (mSelectHandleRight == null) {
+ mSelectHandleRight = mContext.getResources().getDrawable(
+ mTextSelectHandleRightRes);
+ }
+ mDrawable = mSelectHandleRight;
+ handleWidth = mDrawable.getIntrinsicWidth();
+ mHotspotX = handleWidth / 4;
+ break;
+ }
+
+ case CENTER:
+ default: {
+ if (mSelectHandleCenter == null) {
+ mSelectHandleCenter = mContext.getResources().getDrawable(
+ mTextSelectHandleRes);
+ }
+ mDrawable = mSelectHandleCenter;
+ handleWidth = mDrawable.getIntrinsicWidth();
+ mHotspotX = handleWidth / 2;
+ break;
+ }
+ }
+
final int handleHeight = mDrawable.getIntrinsicHeight();
- mHotspotX = handleWidth * 0.5f;
- mHotspotY = -handleHeight * 0.2f;
+
+ mTouchOffsetY = -handleHeight * 0.3f;
+ mHotspotY = 0;
+ mHeight = handleHeight;
+ invalidate();
}
@Override
@@ -7874,10 +7950,10 @@
final int[] coords = mTempCoords;
hostView.getLocationInWindow(coords);
final int posX = coords[0] + mPositionX + (int) mHotspotX;
- final int posY = coords[1] + mPositionY;
+ final int posY = coords[1] + mPositionY + (int) mHotspotY;
return posX >= clip.left && posX <= clip.right &&
- posY >= clip.top && posY + mHotspotY <= clip.bottom;
+ posY >= clip.top && posY <= clip.bottom;
}
private void moveTo(int x, int y) {
@@ -7900,8 +7976,8 @@
TextView.this.getLocationInWindow(coords);
}
if (coords[0] != mLastParentX || coords[1] != mLastParentY) {
- mOffsetX += coords[0] - mLastParentX;
- mOffsetY += coords[1] - mLastParentY;
+ mTouchToWindowOffsetX += coords[0] - mLastParentX;
+ mTouchToWindowOffsetY += coords[1] - mLastParentY;
mLastParentX = coords[0];
mLastParentY = coords[1];
}
@@ -7930,8 +8006,8 @@
case MotionEvent.ACTION_DOWN: {
final float rawX = ev.getRawX();
final float rawY = ev.getRawY();
- mOffsetX = rawX - mPositionX;
- mOffsetY = rawY - mPositionY;
+ mTouchToWindowOffsetX = rawX - mPositionX;
+ mTouchToWindowOffsetY = rawY - mPositionY;
final int[] coords = mTempCoords;
TextView.this.getLocationInWindow(coords);
mLastParentX = coords[0];
@@ -7942,8 +8018,8 @@
case MotionEvent.ACTION_MOVE: {
final float rawX = ev.getRawX();
final float rawY = ev.getRawY();
- final float newPosX = rawX - mOffsetX + mHotspotX;
- final float newPosY = rawY - mOffsetY + mHotspotY;
+ final float newPosX = rawX - mTouchToWindowOffsetX + mHotspotX;
+ final float newPosY = rawY - mTouchToWindowOffsetY + mHotspotY + mTouchOffsetY;
mController.updatePosition(this, (int) Math.round(newPosX),
(int) Math.round(newPosY));
@@ -7969,9 +8045,9 @@
final int lineBottom = mLayout.getLineBottom(line);
final Rect bounds = sCursorControllerTempRect;
- bounds.left = (int) (mLayout.getPrimaryHorizontal(offset) - width / 2.0)
+ bounds.left = (int) (mLayout.getPrimaryHorizontal(offset) - mHotspotX)
+ TextView.this.mScrollX;
- bounds.top = (bottom ? lineBottom : lineTop) + TextView.this.mScrollY;
+ bounds.top = (bottom ? lineBottom : lineTop - mHeight) + TextView.this.mScrollY;
bounds.right = bounds.left + width;
bounds.bottom = bounds.top + height;
@@ -7994,8 +8070,7 @@
};
InsertionPointCursorController() {
- Resources res = mContext.getResources();
- mHandle = new HandleView(this, res.getDrawable(mTextSelectHandleRes));
+ mHandle = new HandleView(this, HandleView.CENTER);
}
public void show() {
@@ -8070,9 +8145,8 @@
};
SelectionModifierCursorController() {
- Resources res = mContext.getResources();
- mStartHandle = new HandleView(this, res.getDrawable(mTextSelectHandleLeftRes));
- mEndHandle = new HandleView(this, res.getDrawable(mTextSelectHandleRightRes));
+ mStartHandle = new HandleView(this, HandleView.LEFT);
+ mEndHandle = new HandleView(this, HandleView.RIGHT);
}
public void show() {
@@ -8113,31 +8187,25 @@
// Handle the case where start and end are swapped, making sure start <= end
if (handle == mStartHandle) {
- if (offset <= selectionEnd) {
- if (selectionStart == offset) {
- return; // no change, no need to redraw;
- }
- selectionStart = offset;
- } else {
- selectionStart = selectionEnd;
- selectionEnd = offset;
- HandleView temp = mStartHandle;
- mStartHandle = mEndHandle;
- mEndHandle = temp;
+ if (selectionStart == offset || offset > selectionEnd) {
+ return; // no change, no need to redraw;
}
+ // If the user "closes" the selection entirely they were probably trying to
+ // select a single character. Help them out.
+ if (offset == selectionEnd) {
+ offset = selectionEnd - 1;
+ }
+ selectionStart = offset;
} else {
- if (offset >= selectionStart) {
- if (selectionEnd == offset) {
- return; // no change, no need to redraw;
- }
- selectionEnd = offset;
- } else {
- selectionEnd = selectionStart;
- selectionStart = offset;
- HandleView temp = mStartHandle;
- mStartHandle = mEndHandle;
- mEndHandle = temp;
+ if (selectionEnd == offset || offset < selectionStart) {
+ return; // no change, no need to redraw;
}
+ // If the user "closes" the selection entirely they were probably trying to
+ // select a single character. Help them out.
+ if (offset == selectionStart) {
+ offset = selectionStart + 1;
+ }
+ selectionEnd = offset;
}
Selection.setSelection((Spannable) mText, selectionStart, selectionEnd);
@@ -8155,9 +8223,7 @@
return;
}
- boolean oneLineSelection = mLayout.getLineForOffset(selectionStart) ==
- mLayout.getLineForOffset(selectionEnd);
- mStartHandle.positionAtCursor(selectionStart, oneLineSelection);
+ mStartHandle.positionAtCursor(selectionStart, true);
mEndHandle.positionAtCursor(selectionEnd, true);
hideDelayed(DELAY_BEFORE_FADE_OUT);
}
@@ -8283,7 +8349,7 @@
final int previousLine = layout.getLineForOffset(previousOffset);
final int previousLineTop = layout.getLineTop(previousLine);
final int previousLineBottom = layout.getLineBottom(previousLine);
- final int hysteresisThreshold = (previousLineBottom - previousLineTop) / 6;
+ final int hysteresisThreshold = (previousLineBottom - previousLineTop) / 8;
// If new line is just before or after previous line and y position is less than
// hysteresisThreshold away from previous line, keep cursor on previous line.
@@ -8329,6 +8395,10 @@
private CursorController mSelectionModifierCursorController;
private ActionMode mSelectionActionMode;
private int mLastTouchOffset = -1;
+ // These are needed to desambiguate a long click. If the long click comes from ones of these, we
+ // select from the current cursor position. Otherwise, select from long pressed position.
+ private boolean mDPadCenterIsDown = false;
+ private boolean mEnterKeyIsDown = false;
// Created once and shared by different CursorController helper methods.
// Only one cursor controller is active at any time which prevent race conditions.
private static Rect sCursorControllerTempRect = new Rect();
diff --git a/core/java/com/android/internal/app/ShutdownThread.java b/core/java/com/android/internal/app/ShutdownThread.java
index e07c54f..8104ece 100644
--- a/core/java/com/android/internal/app/ShutdownThread.java
+++ b/core/java/com/android/internal/app/ShutdownThread.java
@@ -18,15 +18,17 @@
package com.android.internal.app;
import android.app.ActivityManagerNative;
+import android.app.AlertDialog;
+import android.app.Dialog;
import android.app.IActivityManager;
import android.app.ProgressDialog;
-import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.IBluetooth;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.IntentFilter;
import android.os.Handler;
import android.os.Power;
import android.os.PowerManager;
@@ -91,13 +93,20 @@
}
}
- Log.d(TAG, "Notifying thread to start radio shutdown");
+ final int longPressBehavior = context.getResources().getInteger(
+ com.android.internal.R.integer.config_longPressOnPowerBehavior);
+ final int resourceId = longPressBehavior == 2
+ ? com.android.internal.R.string.shutdown_confirm_question
+ : com.android.internal.R.string.shutdown_confirm;
+
+ Log.d(TAG, "Notifying thread to start shutdown longPressBehavior=" + longPressBehavior);
if (confirm) {
+ final CloseDialogReceiver closer = new CloseDialogReceiver(context);
final AlertDialog dialog = new AlertDialog.Builder(context)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle(com.android.internal.R.string.power_off)
- .setMessage(com.android.internal.R.string.shutdown_confirm)
+ .setMessage(resourceId)
.setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
beginShutdownSequence(context);
@@ -105,6 +114,8 @@
})
.setNegativeButton(com.android.internal.R.string.no, null)
.create();
+ closer.dialog = dialog;
+ dialog.setOnDismissListener(closer);
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
if (!context.getResources().getBoolean(
com.android.internal.R.bool.config_sf_slowBlur)) {
@@ -116,6 +127,27 @@
}
}
+ private static class CloseDialogReceiver extends BroadcastReceiver
+ implements DialogInterface.OnDismissListener {
+ private Context mContext;
+ public Dialog dialog;
+
+ CloseDialogReceiver(Context context) {
+ mContext = context;
+ IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+ context.registerReceiver(this, filter);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ dialog.cancel();
+ }
+
+ public void onDismiss(DialogInterface unused) {
+ mContext.unregisterReceiver(this);
+ }
+ }
+
/**
* Request a clean shutdown, waiting for subsystems to clean up their
* state etc. Must be called from a Looper thread in which its UI
diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java
index d517d4c..eaeb67f 100644
--- a/core/java/com/android/internal/view/menu/MenuBuilder.java
+++ b/core/java/com/android/internal/view/menu/MenuBuilder.java
@@ -29,6 +29,7 @@
import android.os.Parcelable;
import android.util.Log;
import android.util.SparseArray;
+import android.util.TypedValue;
import android.view.ContextThemeWrapper;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
@@ -77,16 +78,17 @@
private static final String VIEWS_TAG = "android:views";
+ private static final int THEME_SYSTEM_DEFAULT = 0;
+ private static final int THEME_APPLICATION = -1;
+ private static final int THEME_ALERT_DIALOG = -2;
+
// Order must be the same order as the TYPE_*
- // Special values:
- // 0: Use the system default theme
- // -1: Use the app's own theme
static final int THEME_RES_FOR_TYPE[] = new int[] {
com.android.internal.R.style.Theme_IconMenu,
com.android.internal.R.style.Theme_ExpandedMenu,
- com.android.internal.R.style.Theme_Light,
- -1,
- -1,
+ THEME_ALERT_DIALOG,
+ THEME_APPLICATION,
+ THEME_APPLICATION,
};
// Order must be the same order as the TYPE_*
@@ -205,7 +207,14 @@
private boolean mPreventDispatchingItemsChanged = false;
private boolean mOptionalIconsVisible = false;
-
+
+ private static int getAlertDialogTheme(Context context) {
+ TypedValue outValue = new TypedValue();
+ context.getTheme().resolveAttribute(com.android.internal.R.attr.alertDialogTheme,
+ outValue, true);
+ return outValue.resourceId;
+ }
+
private MenuType[] mMenuTypes;
class MenuType {
private int mMenuType;
@@ -223,9 +232,20 @@
LayoutInflater getInflater() {
// Create an inflater that uses the given theme for the Views it inflates
if (mInflater == null) {
+ Context wrappedContext;
int themeResForType = THEME_RES_FOR_TYPE[mMenuType];
- Context wrappedContext = themeResForType < 0 ? mContext :
- new ContextThemeWrapper(mContext, themeResForType);
+ switch (themeResForType) {
+ case THEME_APPLICATION:
+ wrappedContext = new ContextThemeWrapper(mContext, themeResForType);
+ break;
+ case THEME_ALERT_DIALOG:
+ wrappedContext = new ContextThemeWrapper(mContext,
+ getAlertDialogTheme(mContext));
+ break;
+ default:
+ wrappedContext = mContext;
+ break;
+ }
mInflater = (LayoutInflater) wrappedContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
diff --git a/core/java/com/android/internal/widget/WeightedLinearLayout.java b/core/java/com/android/internal/widget/WeightedLinearLayout.java
index 3d09f08..385a7c3 100644
--- a/core/java/com/android/internal/widget/WeightedLinearLayout.java
+++ b/core/java/com/android/internal/widget/WeightedLinearLayout.java
@@ -30,8 +30,10 @@
* the available space.
*/
public class WeightedLinearLayout extends LinearLayout {
- private float mMajorWeight;
- private float mMinorWeight;
+ private float mMajorWeightMin;
+ private float mMinorWeightMin;
+ private float mMajorWeightMax;
+ private float mMinorWeightMax;
public WeightedLinearLayout(Context context) {
super(context);
@@ -43,8 +45,10 @@
TypedArray a =
context.obtainStyledAttributes(attrs, styleable.WeightedLinearLayout);
- mMajorWeight = a.getFloat(styleable.WeightedLinearLayout_majorWeight, 0.0f);
- mMinorWeight = a.getFloat(styleable.WeightedLinearLayout_minorWeight, 0.0f);
+ mMajorWeightMin = a.getFloat(styleable.WeightedLinearLayout_majorWeightMin, 0.0f);
+ mMinorWeightMin = a.getFloat(styleable.WeightedLinearLayout_minorWeightMin, 0.0f);
+ mMajorWeightMax = a.getFloat(styleable.WeightedLinearLayout_majorWeightMax, 0.0f);
+ mMinorWeightMax = a.getFloat(styleable.WeightedLinearLayout_minorWeightMax, 0.0f);
a.recycle();
}
@@ -60,17 +64,20 @@
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
- int height = getMeasuredHeight();
boolean measure = false;
widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, EXACTLY);
- heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, EXACTLY);
- final float widthWeight = isPortrait ? mMinorWeight : mMajorWeight;
- if (widthMode == AT_MOST && widthWeight > 0.0f) {
- if (width < (screenWidth * widthWeight)) {
- widthMeasureSpec = MeasureSpec.makeMeasureSpec((int) (screenWidth * widthWeight),
- EXACTLY);
+ final float widthWeightMin = isPortrait ? mMinorWeightMin : mMajorWeightMin;
+ final float widthWeightMax = isPortrait ? mMinorWeightMax : mMajorWeightMax;
+ if (widthMode == AT_MOST) {
+ final int weightedMin = (int) (screenWidth * widthWeightMin);
+ final int weightedMax = (int) (screenWidth * widthWeightMin);
+ if (widthWeightMin > 0.0f && width < weightedMin) {
+ widthMeasureSpec = MeasureSpec.makeMeasureSpec(weightedMin, EXACTLY);
+ measure = true;
+ } else if (widthWeightMax > 0.0f && width > weightedMax) {
+ widthMeasureSpec = MeasureSpec.makeMeasureSpec(weightedMax, EXACTLY);
measure = true;
}
}
@@ -78,7 +85,7 @@
// TODO: Support height?
if (measure) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
diff --git a/core/res/res/drawable-hdpi/btn_check_off_disabled_focused_holo_dark.png b/core/res/res/drawable-hdpi/btn_check_off_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..c0f0d167
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_check_off_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_off_disabled_focused_holo_light.png b/core/res/res/drawable-hdpi/btn_check_off_disabled_focused_holo_light.png
new file mode 100644
index 0000000..ba03d28
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_check_off_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_off_disabled_holo_dark.png b/core/res/res/drawable-hdpi/btn_check_off_disabled_holo_dark.png
new file mode 100644
index 0000000..a320240
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_check_off_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_off_disabled_holo_light.png b/core/res/res/drawable-hdpi/btn_check_off_disabled_holo_light.png
new file mode 100644
index 0000000..7f48c54
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_check_off_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_off_focused_holo_dark.png b/core/res/res/drawable-hdpi/btn_check_off_focused_holo_dark.png
new file mode 100644
index 0000000..82b7ba7
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_check_off_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_off_focused_holo_light.png b/core/res/res/drawable-hdpi/btn_check_off_focused_holo_light.png
new file mode 100644
index 0000000..69ecf05
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_check_off_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_off_normal_holo_dark.png b/core/res/res/drawable-hdpi/btn_check_off_normal_holo_dark.png
new file mode 100644
index 0000000..b81d4f9
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_check_off_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_off_normal_holo_light.png b/core/res/res/drawable-hdpi/btn_check_off_normal_holo_light.png
new file mode 100644
index 0000000..b74055e
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_check_off_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_off_pressed_holo_dark.png b/core/res/res/drawable-hdpi/btn_check_off_pressed_holo_dark.png
index 9f9cb01..c18e18b 100644
--- a/core/res/res/drawable-hdpi/btn_check_off_pressed_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_check_off_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_off_pressed_holo_light.png b/core/res/res/drawable-hdpi/btn_check_off_pressed_holo_light.png
index 56425d2..258c3d3 100644
--- a/core/res/res/drawable-hdpi/btn_check_off_pressed_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_check_off_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_disabled_focused_holo_dark.png b/core/res/res/drawable-hdpi/btn_check_on_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..e63e5a5
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_check_on_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_disabled_focused_holo_light.png b/core/res/res/drawable-hdpi/btn_check_on_disabled_focused_holo_light.png
new file mode 100644
index 0000000..37415e0
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_check_on_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_disabled_holo_dark.png b/core/res/res/drawable-hdpi/btn_check_on_disabled_holo_dark.png
new file mode 100644
index 0000000..77a3115
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_check_on_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_disabled_holo_light.png b/core/res/res/drawable-hdpi/btn_check_on_disabled_holo_light.png
new file mode 100644
index 0000000..51993e3
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_check_on_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_focused_holo_dark.png b/core/res/res/drawable-hdpi/btn_check_on_focused_holo_dark.png
new file mode 100644
index 0000000..817adf7
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_check_on_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_focused_holo_light.png b/core/res/res/drawable-hdpi/btn_check_on_focused_holo_light.png
new file mode 100644
index 0000000..6459240
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_check_on_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_normal_holo_dark.png b/core/res/res/drawable-hdpi/btn_check_on_normal_holo_dark.png
new file mode 100644
index 0000000..bf4f3bb
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_check_on_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_normal_holo_light.png b/core/res/res/drawable-hdpi/btn_check_on_normal_holo_light.png
new file mode 100644
index 0000000..5a2a3c1
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_check_on_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_pressed_holo_dark.png b/core/res/res/drawable-hdpi/btn_check_on_pressed_holo_dark.png
index 91e5f14..1333cb1 100644
--- a/core/res/res/drawable-hdpi/btn_check_on_pressed_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_check_on_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_pressed_holo_light.png b/core/res/res/drawable-hdpi/btn_check_on_pressed_holo_light.png
index 0cf7ed2..4413328 100644
--- a/core/res/res/drawable-hdpi/btn_check_on_pressed_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_check_on_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_dark.9.png
index 3deb385..05d1668 100644
--- a/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_light.9.png
index de378a5..6f7eb42 100644
--- a/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_disabled_holo_dark.9.png
index 35f8b3d..2c814f0 100644
--- a/core/res/res/drawable-hdpi/btn_default_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_disabled_holo_light.9.png
index 3f45375..a88bdf6 100644
--- a/core/res/res/drawable-hdpi/btn_default_disabled_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_focused_holo_dark.9.png
index ea58bf7..9a61d82 100644
--- a/core/res/res/drawable-hdpi/btn_default_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_focused_holo_light.9.png
index b225aaff..56ca528 100644
--- a/core/res/res/drawable-hdpi/btn_default_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_normal_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_normal_holo_dark.9.png
index b5b1533..6600035 100644
--- a/core/res/res/drawable-hdpi/btn_default_normal_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_normal_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_normal_holo_light.9.png
index 81b8a75..11d31bb 100644
--- a/core/res/res/drawable-hdpi/btn_default_normal_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_pressed_holo_dark.9.png
index eb8d85a..8c58c37 100644
--- a/core/res/res/drawable-hdpi/btn_default_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_pressed_holo_light.9.png
index 6777ebf..d543c66 100644
--- a/core/res/res/drawable-hdpi/btn_default_pressed_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_disabled_off_holo_dark.png b/core/res/res/drawable-hdpi/btn_radio_disabled_off_holo_dark.png
index 2a7505b..4fdf5ce 100644
--- a/core/res/res/drawable-hdpi/btn_radio_disabled_off_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_radio_disabled_off_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_disabled_off_holo_light.png b/core/res/res/drawable-hdpi/btn_radio_disabled_off_holo_light.png
index bbb01f0..e70f8c3 100644
--- a/core/res/res/drawable-hdpi/btn_radio_disabled_off_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_radio_disabled_off_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_disabled_on_holo_dark.png b/core/res/res/drawable-hdpi/btn_radio_disabled_on_holo_dark.png
index b617a2a..c28d6cd 100644
--- a/core/res/res/drawable-hdpi/btn_radio_disabled_on_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_radio_disabled_on_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_disabled_on_holo_light.png b/core/res/res/drawable-hdpi/btn_radio_disabled_on_holo_light.png
index fd59f4a..ebf4da6 100644
--- a/core/res/res/drawable-hdpi/btn_radio_disabled_on_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_radio_disabled_on_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_focused_off_holo_dark.png b/core/res/res/drawable-hdpi/btn_radio_focused_off_holo_dark.png
index 5d17cde..9a5455c 100644
--- a/core/res/res/drawable-hdpi/btn_radio_focused_off_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_radio_focused_off_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_focused_off_holo_light.png b/core/res/res/drawable-hdpi/btn_radio_focused_off_holo_light.png
index b6b4bf1..9648df2 100644
--- a/core/res/res/drawable-hdpi/btn_radio_focused_off_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_radio_focused_off_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_focused_on_holo_dark.png b/core/res/res/drawable-hdpi/btn_radio_focused_on_holo_dark.png
index eab5039..cd59fab 100644
--- a/core/res/res/drawable-hdpi/btn_radio_focused_on_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_radio_focused_on_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_focused_on_holo_light.png b/core/res/res/drawable-hdpi/btn_radio_focused_on_holo_light.png
index b6b4bf1..4da6192 100644
--- a/core/res/res/drawable-hdpi/btn_radio_focused_on_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_radio_focused_on_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_normal_off_holo_dark.png b/core/res/res/drawable-hdpi/btn_radio_normal_off_holo_dark.png
index edf2296..f18c6da 100644
--- a/core/res/res/drawable-hdpi/btn_radio_normal_off_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_radio_normal_off_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_normal_off_holo_light.png b/core/res/res/drawable-hdpi/btn_radio_normal_off_holo_light.png
index 68afa4c..70afefc 100644
--- a/core/res/res/drawable-hdpi/btn_radio_normal_off_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_radio_normal_off_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_normal_on_holo_dark.png b/core/res/res/drawable-hdpi/btn_radio_normal_on_holo_dark.png
index c7df168..fdf1586 100644
--- a/core/res/res/drawable-hdpi/btn_radio_normal_on_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_radio_normal_on_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_normal_on_holo_light.png b/core/res/res/drawable-hdpi/btn_radio_normal_on_holo_light.png
index 5a9087b..457038a6 100644
--- a/core/res/res/drawable-hdpi/btn_radio_normal_on_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_radio_normal_on_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_pressed_off_holo_dark.png b/core/res/res/drawable-hdpi/btn_radio_pressed_off_holo_dark.png
index 500490d..aa10966 100644
--- a/core/res/res/drawable-hdpi/btn_radio_pressed_off_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_radio_pressed_off_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_pressed_off_holo_light.png b/core/res/res/drawable-hdpi/btn_radio_pressed_off_holo_light.png
index f6690c6..8eaf738 100644
--- a/core/res/res/drawable-hdpi/btn_radio_pressed_off_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_radio_pressed_off_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_pressed_on_holo_dark.png b/core/res/res/drawable-hdpi/btn_radio_pressed_on_holo_dark.png
index 933d2fe..674cc55 100644
--- a/core/res/res/drawable-hdpi/btn_radio_pressed_on_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_radio_pressed_on_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_pressed_on_holo_light.png b/core/res/res/drawable-hdpi/btn_radio_pressed_on_holo_light.png
index c07445a..b4f8800 100644
--- a/core/res/res/drawable-hdpi/btn_radio_pressed_on_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_radio_pressed_on_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_off_focused_holo_dark.png b/core/res/res/drawable-hdpi/btn_star_off_focused_holo_dark.png
new file mode 100644
index 0000000..15feef1
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_star_off_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_off_focused_holo_light.png b/core/res/res/drawable-hdpi/btn_star_off_focused_holo_light.png
new file mode 100644
index 0000000..0cff364
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_star_off_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_off_normal_holo_dark.png b/core/res/res/drawable-hdpi/btn_star_off_normal_holo_dark.png
new file mode 100644
index 0000000..f480729
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_star_off_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_off_normal_holo_light.png b/core/res/res/drawable-hdpi/btn_star_off_normal_holo_light.png
new file mode 100644
index 0000000..1c632e8
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_star_off_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_on_focused_holo_dark.png b/core/res/res/drawable-hdpi/btn_star_on_focused_holo_dark.png
new file mode 100644
index 0000000..2dd3d77
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_star_on_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_on_focused_holo_light.png b/core/res/res/drawable-hdpi/btn_star_on_focused_holo_light.png
new file mode 100644
index 0000000..7b10118
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_star_on_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_on_normal_holo_dark.png b/core/res/res/drawable-hdpi/btn_star_on_normal_holo_dark.png
new file mode 100644
index 0000000..2f863bb
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_star_on_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_on_normal_holo_light.png b/core/res/res/drawable-hdpi/btn_star_on_normal_holo_light.png
new file mode 100644
index 0000000..1220c20
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_star_on_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
index 128a8dd..5a8c8e5 100755
--- a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_light.9.png
index da05c23..2263153 100755
--- a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_dark.9.png
index da66a98..dbfa16a 100755
--- a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_light.9.png
index 3ac8417..47a43e9 100755
--- a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_dark.9.png
index fc9d493..2787a4b 100755
--- a/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_light.9.png
index 315ae3b..c8bf8b1 100755
--- a/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_dark.9.png
index ee9590c6..eb4f17a 100755
--- a/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_light.9.png
index cbc9da2c..42b434c 100755
--- a/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_dark.9.png
index 1792063..e362aa1 100755
--- a/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_light.9.png
index 097025b..cc61414 100755
--- a/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
index 5b92d7c6..8b813b9 100755
--- a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_light.9.png
index a244f45..54686cd 100755
--- a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_dark.9.png
index 9218f91..056f451 100755
--- a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_light.9.png
index 81802f8..2c4a6dd 100755
--- a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_dark.9.png
index 9dea983..127a9be 100755
--- a/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_light.9.png
index fc2374b..4853ef4 100755
--- a/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_dark.9.png
index 18bb6bd..d767185 100755
--- a/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_light.9.png
index de78a9f..00e6105 100755
--- a/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_dark.9.png
index 2269326..293cad3 100755
--- a/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_pressed_holo_light.9.png
new file mode 100644
index 0000000..6963a0e
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_toggle_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/cab_divider_holo_dark.png b/core/res/res/drawable-hdpi/cab_divider_holo_dark.png
index e6f61fc..e2c2119 100755
--- a/core/res/res/drawable-hdpi/cab_divider_holo_dark.png
+++ b/core/res/res/drawable-hdpi/cab_divider_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/cab_divider_holo_light.png b/core/res/res/drawable-hdpi/cab_divider_holo_light.png
index 2f97a29..51e2295 100755
--- a/core/res/res/drawable-hdpi/cab_divider_holo_light.png
+++ b/core/res/res/drawable-hdpi/cab_divider_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/cab_holo_dark.9.png b/core/res/res/drawable-hdpi/cab_holo_dark.9.png
index 662d63c..64e2052 100755
--- a/core/res/res/drawable-hdpi/cab_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/cab_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/cab_holo_light.9.png b/core/res/res/drawable-hdpi/cab_holo_light.9.png
index e8cbde1..4f2afcf 100755
--- a/core/res/res/drawable-hdpi/cab_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/cab_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/cab_ic_close_focused_holo.png b/core/res/res/drawable-hdpi/cab_ic_close_focused_holo.png
index 861e0a1..9d7f932 100755
--- a/core/res/res/drawable-hdpi/cab_ic_close_focused_holo.png
+++ b/core/res/res/drawable-hdpi/cab_ic_close_focused_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/cab_ic_close_normal_holo.png b/core/res/res/drawable-hdpi/cab_ic_close_normal_holo.png
index 036f362..641507d 100755
--- a/core/res/res/drawable-hdpi/cab_ic_close_normal_holo.png
+++ b/core/res/res/drawable-hdpi/cab_ic_close_normal_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/cab_ic_close_pressed_holo.png b/core/res/res/drawable-hdpi/cab_ic_close_pressed_holo.png
index be8c2ff..ebb0fc8 100755
--- a/core/res/res/drawable-hdpi/cab_ic_close_pressed_holo.png
+++ b/core/res/res/drawable-hdpi/cab_ic_close_pressed_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_bottom_holo_dark.9.png b/core/res/res/drawable-hdpi/dialog_bottom_holo_dark.9.png
new file mode 100644
index 0000000..83c0852
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dialog_bottom_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_bottom_holo_light.9.png b/core/res/res/drawable-hdpi/dialog_bottom_holo_light.9.png
new file mode 100644
index 0000000..c495216
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dialog_bottom_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_full_holo_dark.9.png b/core/res/res/drawable-hdpi/dialog_full_holo_dark.9.png
new file mode 100644
index 0000000..620adaa
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dialog_full_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_full_holo_light.9.png b/core/res/res/drawable-hdpi/dialog_full_holo_light.9.png
new file mode 100644
index 0000000..b03d6cd
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dialog_full_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_ic_close_focused_holo_dark.png b/core/res/res/drawable-hdpi/dialog_ic_close_focused_holo_dark.png
new file mode 100644
index 0000000..785ae6e
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dialog_ic_close_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_ic_close_focused_holo_light.png b/core/res/res/drawable-hdpi/dialog_ic_close_focused_holo_light.png
new file mode 100644
index 0000000..d96787b
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dialog_ic_close_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_ic_close_normal_holo_dark.png b/core/res/res/drawable-hdpi/dialog_ic_close_normal_holo_dark.png
new file mode 100644
index 0000000..d042a81
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dialog_ic_close_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_ic_close_normal_holo_light.png b/core/res/res/drawable-hdpi/dialog_ic_close_normal_holo_light.png
new file mode 100644
index 0000000..677cf3d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dialog_ic_close_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_ic_close_pressed_holo_dark.png b/core/res/res/drawable-hdpi/dialog_ic_close_pressed_holo_dark.png
new file mode 100644
index 0000000..9b13c5b
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dialog_ic_close_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_ic_close_pressed_holo_light.png b/core/res/res/drawable-hdpi/dialog_ic_close_pressed_holo_light.png
new file mode 100644
index 0000000..8e245fc
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dialog_ic_close_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_middle_holo_dark.9.png b/core/res/res/drawable-hdpi/dialog_middle_holo_dark.9.png
new file mode 100644
index 0000000..cffae3e
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dialog_middle_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_middle_holo_light.9.png b/core/res/res/drawable-hdpi/dialog_middle_holo_light.9.png
new file mode 100644
index 0000000..0394885
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dialog_middle_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_top_holo_dark.9.png b/core/res/res/drawable-hdpi/dialog_top_holo_dark.9.png
new file mode 100644
index 0000000..6746ce8
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dialog_top_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_top_holo_light.9.png b/core/res/res/drawable-hdpi/dialog_top_holo_light.9.png
new file mode 100644
index 0000000..bdcdc71
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dialog_top_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dropdown_disabled_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/dropdown_disabled_focused_holo_dark.9.png
new file mode 100644
index 0000000..519f522
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dropdown_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dropdown_disabled_focused_holo_light.9.png b/core/res/res/drawable-hdpi/dropdown_disabled_focused_holo_light.9.png
new file mode 100644
index 0000000..9c181d0
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dropdown_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dropdown_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/dropdown_disabled_holo_dark.9.png
new file mode 100644
index 0000000..6ca975f
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dropdown_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dropdown_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/dropdown_disabled_holo_light.9.png
new file mode 100644
index 0000000..7a20af7
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dropdown_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dropdown_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/dropdown_focused_holo_dark.9.png
new file mode 100644
index 0000000..a3dfb98
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dropdown_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dropdown_focused_holo_light.9.png b/core/res/res/drawable-hdpi/dropdown_focused_holo_light.9.png
new file mode 100644
index 0000000..766543c
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dropdown_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dropdown_ic_arrow_disabled_focused_holo_dark.png b/core/res/res/drawable-hdpi/dropdown_ic_arrow_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..53f02576
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dropdown_ic_arrow_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dropdown_ic_arrow_disabled_focused_holo_light.png b/core/res/res/drawable-hdpi/dropdown_ic_arrow_disabled_focused_holo_light.png
new file mode 100644
index 0000000..0daee9b
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dropdown_ic_arrow_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dropdown_ic_arrow_disabled_holo_dark.png b/core/res/res/drawable-hdpi/dropdown_ic_arrow_disabled_holo_dark.png
new file mode 100644
index 0000000..b659926
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dropdown_ic_arrow_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dropdown_ic_arrow_disabled_holo_light.png b/core/res/res/drawable-hdpi/dropdown_ic_arrow_disabled_holo_light.png
new file mode 100644
index 0000000..e22dbfd
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dropdown_ic_arrow_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dropdown_ic_arrow_focused_holo_dark.png b/core/res/res/drawable-hdpi/dropdown_ic_arrow_focused_holo_dark.png
new file mode 100644
index 0000000..0f65227
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dropdown_ic_arrow_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dropdown_ic_arrow_focused_holo_light.png b/core/res/res/drawable-hdpi/dropdown_ic_arrow_focused_holo_light.png
new file mode 100644
index 0000000..9c47d7e
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dropdown_ic_arrow_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dropdown_ic_arrow_normal_holo_dark.png b/core/res/res/drawable-hdpi/dropdown_ic_arrow_normal_holo_dark.png
new file mode 100644
index 0000000..06e5b47
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dropdown_ic_arrow_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dropdown_ic_arrow_normal_holo_light.png b/core/res/res/drawable-hdpi/dropdown_ic_arrow_normal_holo_light.png
new file mode 100644
index 0000000..d362ec1
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dropdown_ic_arrow_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dropdown_ic_arrow_pressed_holo_dark.png b/core/res/res/drawable-hdpi/dropdown_ic_arrow_pressed_holo_dark.png
new file mode 100644
index 0000000..d010995
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dropdown_ic_arrow_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dropdown_ic_arrow_pressed_holo_light.png b/core/res/res/drawable-hdpi/dropdown_ic_arrow_pressed_holo_light.png
new file mode 100644
index 0000000..b95f94b
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dropdown_ic_arrow_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dropdown_normal_holo_dark.9.png b/core/res/res/drawable-hdpi/dropdown_normal_holo_dark.9.png
new file mode 100644
index 0000000..a4ac317
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dropdown_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dropdown_normal_holo_light.9.png b/core/res/res/drawable-hdpi/dropdown_normal_holo_light.9.png
new file mode 100644
index 0000000..b4ab9ad
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dropdown_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dropdown_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/dropdown_pressed_holo_dark.9.png
new file mode 100644
index 0000000..f6382c8
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dropdown_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dropdown_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/dropdown_pressed_holo_light.9.png
new file mode 100644
index 0000000..c849e2f
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dropdown_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_moreoverflow_focused_holo_dark.png b/core/res/res/drawable-hdpi/ic_menu_moreoverflow_focused_holo_dark.png
new file mode 100644
index 0000000..061f80a
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_moreoverflow_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_moreoverflow_focused_holo_light.png b/core/res/res/drawable-hdpi/ic_menu_moreoverflow_focused_holo_light.png
new file mode 100644
index 0000000..d818806
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_moreoverflow_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_moreoverflow_normal_holo_dark.png b/core/res/res/drawable-hdpi/ic_menu_moreoverflow_normal_holo_dark.png
new file mode 100644
index 0000000..8563c1a8d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_moreoverflow_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_moreoverflow_normal_holo_light.png b/core/res/res/drawable-hdpi/ic_menu_moreoverflow_normal_holo_light.png
new file mode 100644
index 0000000..1cd2384
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_moreoverflow_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_divider_horizontal_holo_dark.9.png b/core/res/res/drawable-hdpi/list_divider_horizontal_holo_dark.9.png
new file mode 100644
index 0000000..0a4347f
--- /dev/null
+++ b/core/res/res/drawable-hdpi/list_divider_horizontal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_section_header_holo_dark.9.png b/core/res/res/drawable-hdpi/list_section_header_holo_dark.9.png
new file mode 100644
index 0000000..2030d3b
--- /dev/null
+++ b/core/res/res/drawable-hdpi/list_section_header_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_section_header_holo_light.9.png b/core/res/res/drawable-hdpi/list_section_header_holo_light.9.png
new file mode 100644
index 0000000..4ca2773
--- /dev/null
+++ b/core/res/res/drawable-hdpi/list_section_header_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_selector_activated_holo_dark.9.png b/core/res/res/drawable-hdpi/list_selector_activated_holo_dark.9.png
new file mode 100644
index 0000000..1a516c1
--- /dev/null
+++ b/core/res/res/drawable-hdpi/list_selector_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_selector_activated_holo_light.9.png b/core/res/res/drawable-hdpi/list_selector_activated_holo_light.9.png
new file mode 100644
index 0000000..f22217b
--- /dev/null
+++ b/core/res/res/drawable-hdpi/list_selector_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_selector_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/list_selector_disabled_holo_dark.9.png
new file mode 100644
index 0000000..f6fd30d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/list_selector_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_selector_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/list_selector_disabled_holo_light.9.png
new file mode 100644
index 0000000..ca8e9a2
--- /dev/null
+++ b/core/res/res/drawable-hdpi/list_selector_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_selector_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/list_selector_focused_holo_dark.9.png
new file mode 100644
index 0000000..c1f3d7d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/list_selector_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_selector_focused_holo_light.9.png b/core/res/res/drawable-hdpi/list_selector_focused_holo_light.9.png
new file mode 100644
index 0000000..99bb246
--- /dev/null
+++ b/core/res/res/drawable-hdpi/list_selector_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_selector_multiselect_holo_dark.9.png b/core/res/res/drawable-hdpi/list_selector_multiselect_holo_dark.9.png
new file mode 100644
index 0000000..f702fc8
--- /dev/null
+++ b/core/res/res/drawable-hdpi/list_selector_multiselect_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_selector_multiselect_holo_light.9.png b/core/res/res/drawable-hdpi/list_selector_multiselect_holo_light.9.png
new file mode 100644
index 0000000..e8f277d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/list_selector_multiselect_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_selector_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/list_selector_pressed_holo_dark.9.png
new file mode 100644
index 0000000..0ed5ba3
--- /dev/null
+++ b/core/res/res/drawable-hdpi/list_selector_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_selector_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/list_selector_pressed_holo_light.9.png
new file mode 100644
index 0000000..1471c17
--- /dev/null
+++ b/core/res/res/drawable-hdpi/list_selector_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/menu_dropdown_panel_holo_dark.9.png b/core/res/res/drawable-hdpi/menu_dropdown_panel_holo_dark.9.png
new file mode 100644
index 0000000..7ec3a33f
--- /dev/null
+++ b/core/res/res/drawable-hdpi/menu_dropdown_panel_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/menu_dropdown_panel_holo_light.9.png b/core/res/res/drawable-hdpi/menu_dropdown_panel_holo_light.9.png
new file mode 100644
index 0000000..da1fe94
--- /dev/null
+++ b/core/res/res/drawable-hdpi/menu_dropdown_panel_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickactions_arrowdown_left_holo_dark.9.png b/core/res/res/drawable-hdpi/quickactions_arrowdown_left_holo_dark.9.png
new file mode 100644
index 0000000..93a8417
--- /dev/null
+++ b/core/res/res/drawable-hdpi/quickactions_arrowdown_left_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickactions_arrowdown_left_holo_light.9.png b/core/res/res/drawable-hdpi/quickactions_arrowdown_left_holo_light.9.png
new file mode 100644
index 0000000..61e856a
--- /dev/null
+++ b/core/res/res/drawable-hdpi/quickactions_arrowdown_left_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickactions_arrowdown_right_holo_dark.9.png b/core/res/res/drawable-hdpi/quickactions_arrowdown_right_holo_dark.9.png
new file mode 100644
index 0000000..7632a16
--- /dev/null
+++ b/core/res/res/drawable-hdpi/quickactions_arrowdown_right_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickactions_arrowdown_right_holo_light.9.png b/core/res/res/drawable-hdpi/quickactions_arrowdown_right_holo_light.9.png
new file mode 100644
index 0000000..8e66ad1
--- /dev/null
+++ b/core/res/res/drawable-hdpi/quickactions_arrowdown_right_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickactions_arrowup_left_holo_dark.9.png b/core/res/res/drawable-hdpi/quickactions_arrowup_left_holo_dark.9.png
new file mode 100644
index 0000000..02618ca
--- /dev/null
+++ b/core/res/res/drawable-hdpi/quickactions_arrowup_left_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickactions_arrowup_left_holo_light.9.png b/core/res/res/drawable-hdpi/quickactions_arrowup_left_holo_light.9.png
new file mode 100644
index 0000000..939050d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/quickactions_arrowup_left_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickactions_arrowup_left_right_holo_dark.9.png b/core/res/res/drawable-hdpi/quickactions_arrowup_left_right_holo_dark.9.png
new file mode 100644
index 0000000..f5cf487
--- /dev/null
+++ b/core/res/res/drawable-hdpi/quickactions_arrowup_left_right_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickactions_arrowup_right_holo_light.9.png b/core/res/res/drawable-hdpi/quickactions_arrowup_right_holo_light.9.png
new file mode 100644
index 0000000..1237f26
--- /dev/null
+++ b/core/res/res/drawable-hdpi/quickactions_arrowup_right_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_holo.png b/core/res/res/drawable-hdpi/scrubber_control_holo.png
new file mode 100644
index 0000000..3a72307
--- /dev/null
+++ b/core/res/res/drawable-hdpi/scrubber_control_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_track_holo_dark.9.png b/core/res/res/drawable-hdpi/scrubber_track_holo_dark.9.png
new file mode 100644
index 0000000..e6d7123
--- /dev/null
+++ b/core/res/res/drawable-hdpi/scrubber_track_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_track_holo_light.9.png b/core/res/res/drawable-hdpi/scrubber_track_holo_light.9.png
new file mode 100644
index 0000000..f75bfa0
--- /dev/null
+++ b/core/res/res/drawable-hdpi/scrubber_track_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/text_select_handle_left.png b/core/res/res/drawable-hdpi/text_select_handle_left.png
old mode 100644
new mode 100755
index 271a6d0..3743d91
--- a/core/res/res/drawable-hdpi/text_select_handle_left.png
+++ b/core/res/res/drawable-hdpi/text_select_handle_left.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/text_select_handle_middle.png b/core/res/res/drawable-hdpi/text_select_handle_middle.png
old mode 100644
new mode 100755
Binary files differ
diff --git a/core/res/res/drawable-hdpi/text_select_handle_right.png b/core/res/res/drawable-hdpi/text_select_handle_right.png
old mode 100644
new mode 100755
index dfdf899..12a3dff
--- a/core/res/res/drawable-hdpi/text_select_handle_right.png
+++ b/core/res/res/drawable-hdpi/text_select_handle_right.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_off_disable_focused_holo_dark.png b/core/res/res/drawable-mdpi/btn_check_off_disable_focused_holo_dark.png
deleted file mode 100644
index 3fac4aa..0000000
--- a/core/res/res/drawable-mdpi/btn_check_off_disable_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_off_disable_focused_holo_light.png b/core/res/res/drawable-mdpi/btn_check_off_disable_focused_holo_light.png
deleted file mode 100644
index 3da9a46..0000000
--- a/core/res/res/drawable-mdpi/btn_check_off_disable_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_off_disable_holo_dark.png b/core/res/res/drawable-mdpi/btn_check_off_disable_holo_dark.png
deleted file mode 100644
index 3fac4aa..0000000
--- a/core/res/res/drawable-mdpi/btn_check_off_disable_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_off_disable_holo_light.png b/core/res/res/drawable-mdpi/btn_check_off_disable_holo_light.png
deleted file mode 100644
index 3da9a46..0000000
--- a/core/res/res/drawable-mdpi/btn_check_off_disable_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_off_disabled_focused_holo_dark.png b/core/res/res/drawable-mdpi/btn_check_off_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..7e58392
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_check_off_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_off_disabled_focused_holo_light.png b/core/res/res/drawable-mdpi/btn_check_off_disabled_focused_holo_light.png
new file mode 100644
index 0000000..d5c1f7c
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_check_off_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_off_disabled_holo_dark.png b/core/res/res/drawable-mdpi/btn_check_off_disabled_holo_dark.png
new file mode 100644
index 0000000..b6eec97
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_check_off_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_off_disabled_holo_light.png b/core/res/res/drawable-mdpi/btn_check_off_disabled_holo_light.png
new file mode 100644
index 0000000..1bc34b6
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_check_off_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_off_focused_holo_dark.png b/core/res/res/drawable-mdpi/btn_check_off_focused_holo_dark.png
new file mode 100644
index 0000000..894836f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_check_off_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_off_focused_holo_light.png b/core/res/res/drawable-mdpi/btn_check_off_focused_holo_light.png
new file mode 100644
index 0000000..ae81a5e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_check_off_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_off_normal_holo_dark.png b/core/res/res/drawable-mdpi/btn_check_off_normal_holo_dark.png
new file mode 100644
index 0000000..5434614
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_check_off_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_off_normal_holo_light.png b/core/res/res/drawable-mdpi/btn_check_off_normal_holo_light.png
new file mode 100644
index 0000000..0d43dc4
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_check_off_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_off_pressed_holo_dark.png b/core/res/res/drawable-mdpi/btn_check_off_pressed_holo_dark.png
index 0dcb9de..0f9f4f0 100644
--- a/core/res/res/drawable-mdpi/btn_check_off_pressed_holo_dark.png
+++ b/core/res/res/drawable-mdpi/btn_check_off_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_off_pressed_holo_light.png b/core/res/res/drawable-mdpi/btn_check_off_pressed_holo_light.png
index b25fdc4..77ad452 100644
--- a/core/res/res/drawable-mdpi/btn_check_off_pressed_holo_light.png
+++ b/core/res/res/drawable-mdpi/btn_check_off_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_on_disabled_focused_holo_dark.png b/core/res/res/drawable-mdpi/btn_check_on_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..28bf7f6
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_check_on_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_on_disabled_focused_holo_light.png b/core/res/res/drawable-mdpi/btn_check_on_disabled_focused_holo_light.png
new file mode 100644
index 0000000..bb2d314
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_check_on_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_on_disabled_holo_dark.png b/core/res/res/drawable-mdpi/btn_check_on_disabled_holo_dark.png
new file mode 100644
index 0000000..8cf4554
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_check_on_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_on_disabled_holo_light.png b/core/res/res/drawable-mdpi/btn_check_on_disabled_holo_light.png
new file mode 100644
index 0000000..ba37f93
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_check_on_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_on_focused_holo_dark.png b/core/res/res/drawable-mdpi/btn_check_on_focused_holo_dark.png
new file mode 100644
index 0000000..1fca094
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_check_on_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_on_focused_holo_light.png b/core/res/res/drawable-mdpi/btn_check_on_focused_holo_light.png
new file mode 100644
index 0000000..21c33f0
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_check_on_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_on_normal_holo_dark.png b/core/res/res/drawable-mdpi/btn_check_on_normal_holo_dark.png
new file mode 100644
index 0000000..e65c0b4
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_check_on_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_on_normal_holo_light.png b/core/res/res/drawable-mdpi/btn_check_on_normal_holo_light.png
new file mode 100644
index 0000000..9576bea
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_check_on_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_on_pressed_holo_dark.png b/core/res/res/drawable-mdpi/btn_check_on_pressed_holo_dark.png
index 0722cda..84733fb 100644
--- a/core/res/res/drawable-mdpi/btn_check_on_pressed_holo_dark.png
+++ b/core/res/res/drawable-mdpi/btn_check_on_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_on_pressed_holo_light.png b/core/res/res/drawable-mdpi/btn_check_on_pressed_holo_light.png
index 4de166e..67a15d2 100644
--- a/core/res/res/drawable-mdpi/btn_check_on_pressed_holo_light.png
+++ b/core/res/res/drawable-mdpi/btn_check_on_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_dark.9.png
index 9bc1ee8..15003be 100644
--- a/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_light.9.png
index cc643ea..573f197 100644
--- a/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_disabled_holo_dark.9.png
index 0586d52..953a553 100644
--- a/core/res/res/drawable-mdpi/btn_default_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_disabled_holo_light.9.png
index dd6c1a0..d79a61e 100644
--- a/core/res/res/drawable-mdpi/btn_default_disabled_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_focused_holo_dark.9.png
index e8f07cb..897676e 100644
--- a/core/res/res/drawable-mdpi/btn_default_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_focused_holo_light.9.png
index 0685f1e..b485925 100644
--- a/core/res/res/drawable-mdpi/btn_default_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_normal_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_normal_holo_dark.9.png
index 6b33fa4..1cdbf66 100644
--- a/core/res/res/drawable-mdpi/btn_default_normal_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_normal_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_normal_holo_light.9.png
index eb728ed..ab7eb54 100644
--- a/core/res/res/drawable-mdpi/btn_default_normal_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_pressed_holo_dark.9.png
index 4a15d9d..d95ef6d 100644
--- a/core/res/res/drawable-mdpi/btn_default_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_pressed_holo_light.9.png
index 6718ff7..60ed4fc 100644
--- a/core/res/res/drawable-mdpi/btn_default_pressed_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_disabled_off_holo_dark.png b/core/res/res/drawable-mdpi/btn_radio_disabled_off_holo_dark.png
index f21142e..f937182 100644
--- a/core/res/res/drawable-mdpi/btn_radio_disabled_off_holo_dark.png
+++ b/core/res/res/drawable-mdpi/btn_radio_disabled_off_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_disabled_off_holo_light.png b/core/res/res/drawable-mdpi/btn_radio_disabled_off_holo_light.png
index a1031fc..4c35fb3 100644
--- a/core/res/res/drawable-mdpi/btn_radio_disabled_off_holo_light.png
+++ b/core/res/res/drawable-mdpi/btn_radio_disabled_off_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_disabled_on_holo_dark.png b/core/res/res/drawable-mdpi/btn_radio_disabled_on_holo_dark.png
index 61243c5..af38a4f 100644
--- a/core/res/res/drawable-mdpi/btn_radio_disabled_on_holo_dark.png
+++ b/core/res/res/drawable-mdpi/btn_radio_disabled_on_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_disabled_on_holo_light.png b/core/res/res/drawable-mdpi/btn_radio_disabled_on_holo_light.png
index faa55e0..a368602 100644
--- a/core/res/res/drawable-mdpi/btn_radio_disabled_on_holo_light.png
+++ b/core/res/res/drawable-mdpi/btn_radio_disabled_on_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_focused_off_holo_dark.png b/core/res/res/drawable-mdpi/btn_radio_focused_off_holo_dark.png
index 0c645da..695d0b9 100644
--- a/core/res/res/drawable-mdpi/btn_radio_focused_off_holo_dark.png
+++ b/core/res/res/drawable-mdpi/btn_radio_focused_off_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_focused_off_holo_light.png b/core/res/res/drawable-mdpi/btn_radio_focused_off_holo_light.png
index 5efc321..6467bea 100644
--- a/core/res/res/drawable-mdpi/btn_radio_focused_off_holo_light.png
+++ b/core/res/res/drawable-mdpi/btn_radio_focused_off_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_focused_on_holo_dark.png b/core/res/res/drawable-mdpi/btn_radio_focused_on_holo_dark.png
index 96bcdc5..813a069 100644
--- a/core/res/res/drawable-mdpi/btn_radio_focused_on_holo_dark.png
+++ b/core/res/res/drawable-mdpi/btn_radio_focused_on_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_focused_on_holo_light.png b/core/res/res/drawable-mdpi/btn_radio_focused_on_holo_light.png
index 5efc321..fe80d69 100644
--- a/core/res/res/drawable-mdpi/btn_radio_focused_on_holo_light.png
+++ b/core/res/res/drawable-mdpi/btn_radio_focused_on_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_normal_off_holo_dark.png b/core/res/res/drawable-mdpi/btn_radio_normal_off_holo_dark.png
index 96413ef..5b6d906 100644
--- a/core/res/res/drawable-mdpi/btn_radio_normal_off_holo_dark.png
+++ b/core/res/res/drawable-mdpi/btn_radio_normal_off_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_normal_off_holo_light.png b/core/res/res/drawable-mdpi/btn_radio_normal_off_holo_light.png
index 1cb5432..e5132ef 100644
--- a/core/res/res/drawable-mdpi/btn_radio_normal_off_holo_light.png
+++ b/core/res/res/drawable-mdpi/btn_radio_normal_off_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_normal_on_holo_dark.png b/core/res/res/drawable-mdpi/btn_radio_normal_on_holo_dark.png
index 2e8404a..e216d35 100644
--- a/core/res/res/drawable-mdpi/btn_radio_normal_on_holo_dark.png
+++ b/core/res/res/drawable-mdpi/btn_radio_normal_on_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_normal_on_holo_light.png b/core/res/res/drawable-mdpi/btn_radio_normal_on_holo_light.png
index b3e14b1..ed3946a 100644
--- a/core/res/res/drawable-mdpi/btn_radio_normal_on_holo_light.png
+++ b/core/res/res/drawable-mdpi/btn_radio_normal_on_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_pressed_off_holo_dark.png b/core/res/res/drawable-mdpi/btn_radio_pressed_off_holo_dark.png
index 5f74c70..9ab32d1 100644
--- a/core/res/res/drawable-mdpi/btn_radio_pressed_off_holo_dark.png
+++ b/core/res/res/drawable-mdpi/btn_radio_pressed_off_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_pressed_off_holo_light.png b/core/res/res/drawable-mdpi/btn_radio_pressed_off_holo_light.png
index 408e50e..7175853 100644
--- a/core/res/res/drawable-mdpi/btn_radio_pressed_off_holo_light.png
+++ b/core/res/res/drawable-mdpi/btn_radio_pressed_off_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_pressed_on_holo_dark.png b/core/res/res/drawable-mdpi/btn_radio_pressed_on_holo_dark.png
index ff60bc2..a6fa7b6 100644
--- a/core/res/res/drawable-mdpi/btn_radio_pressed_on_holo_dark.png
+++ b/core/res/res/drawable-mdpi/btn_radio_pressed_on_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_pressed_on_holo_light.png b/core/res/res/drawable-mdpi/btn_radio_pressed_on_holo_light.png
index 2125c24..e7a634d 100644
--- a/core/res/res/drawable-mdpi/btn_radio_pressed_on_holo_light.png
+++ b/core/res/res/drawable-mdpi/btn_radio_pressed_on_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_star_off_focused_holo_dark.png b/core/res/res/drawable-mdpi/btn_star_off_focused_holo_dark.png
new file mode 100644
index 0000000..153e50d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_star_off_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_star_off_focused_holo_light.png b/core/res/res/drawable-mdpi/btn_star_off_focused_holo_light.png
new file mode 100644
index 0000000..379fd24
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_star_off_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_star_off_normal_holo_dark.png b/core/res/res/drawable-mdpi/btn_star_off_normal_holo_dark.png
new file mode 100644
index 0000000..fe35f1c
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_star_off_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_star_off_normal_holo_light.png b/core/res/res/drawable-mdpi/btn_star_off_normal_holo_light.png
new file mode 100644
index 0000000..002237f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_star_off_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_star_on_focused_holo_dark.png b/core/res/res/drawable-mdpi/btn_star_on_focused_holo_dark.png
new file mode 100644
index 0000000..0ad2583
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_star_on_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_star_on_focused_holo_light.png b/core/res/res/drawable-mdpi/btn_star_on_focused_holo_light.png
new file mode 100644
index 0000000..ce7c3b4
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_star_on_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_star_on_normal_holo_dark.png b/core/res/res/drawable-mdpi/btn_star_on_normal_holo_dark.png
new file mode 100644
index 0000000..ee93e88
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_star_on_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_star_on_normal_holo_light.png b/core/res/res/drawable-mdpi/btn_star_on_normal_holo_light.png
new file mode 100644
index 0000000..597fd9a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_star_on_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
index 7d1e16d..deecc51 100755
--- a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_light.9.png
index 92e86cd..76d4f05 100755
--- a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_dark.9.png
index 1cf473b..0ecd1ae 100755
--- a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_light.9.png
index d6f2125..a7015ee 100755
--- a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_dark.9.png
index 31f7f8c..71949b2 100755
--- a/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_light.9.png
index 82425d5..351f76b 100755
--- a/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_dark.9.png
index 16f19fc..44b9503 100755
--- a/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_light.9.png
index e2c7702..d70a1fc5 100755
--- a/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_dark.9.png
index d61470c..5f9d2b1 100755
--- a/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_light.9.png
index 4019fee..6723757 100755
--- a/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
index ba354e3..62b67a5 100755
--- a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_light.9.png
index 9391b2e..b8418bc 100755
--- a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_dark.9.png
index 601ff2c..f9a11a5 100755
--- a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_light.9.png
index 90c259a..e983c8a 100755
--- a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_dark.9.png
index 857c757..ed8407b 100755
--- a/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_light.9.png
index ef16a48..31f36b7 100755
--- a/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_dark.9.png
index d47ec8f..e023c44 100755
--- a/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_light.9.png
index 2951caf..e4008cf 100755
--- a/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_dark.9.png
index 141b4dd..56e1157 100755
--- a/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_pressed_holo_light.9.png
new file mode 100644
index 0000000..b6508fc
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_toggle_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/cab_divider_holo_dark.png b/core/res/res/drawable-mdpi/cab_divider_holo_dark.png
index 57cc8a4..317263a 100755
--- a/core/res/res/drawable-mdpi/cab_divider_holo_dark.png
+++ b/core/res/res/drawable-mdpi/cab_divider_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/cab_divider_holo_light.png b/core/res/res/drawable-mdpi/cab_divider_holo_light.png
index ec85701..824ad27 100755
--- a/core/res/res/drawable-mdpi/cab_divider_holo_light.png
+++ b/core/res/res/drawable-mdpi/cab_divider_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/cab_holo_dark.9.png b/core/res/res/drawable-mdpi/cab_holo_dark.9.png
index 6c85300..7daae1f 100755
--- a/core/res/res/drawable-mdpi/cab_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/cab_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/cab_holo_light.9.png b/core/res/res/drawable-mdpi/cab_holo_light.9.png
index c82352a..0e64c5c 100755
--- a/core/res/res/drawable-mdpi/cab_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/cab_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/cab_ic_close_focused_holo.png b/core/res/res/drawable-mdpi/cab_ic_close_focused_holo.png
index df170c4..59149e4 100755
--- a/core/res/res/drawable-mdpi/cab_ic_close_focused_holo.png
+++ b/core/res/res/drawable-mdpi/cab_ic_close_focused_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/cab_ic_close_normal_holo.png b/core/res/res/drawable-mdpi/cab_ic_close_normal_holo.png
index 9482ce7..b378885 100755
--- a/core/res/res/drawable-mdpi/cab_ic_close_normal_holo.png
+++ b/core/res/res/drawable-mdpi/cab_ic_close_normal_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/cab_ic_close_pressed_holo.png b/core/res/res/drawable-mdpi/cab_ic_close_pressed_holo.png
index d115d20..29b0407 100755
--- a/core/res/res/drawable-mdpi/cab_ic_close_pressed_holo.png
+++ b/core/res/res/drawable-mdpi/cab_ic_close_pressed_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_bottom_holo_dark.9.png b/core/res/res/drawable-mdpi/dialog_bottom_holo_dark.9.png
new file mode 100644
index 0000000..e3a30a9
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dialog_bottom_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_bottom_holo_light.9.png b/core/res/res/drawable-mdpi/dialog_bottom_holo_light.9.png
new file mode 100644
index 0000000..f7f344a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dialog_bottom_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_full_holo_dark.9.png b/core/res/res/drawable-mdpi/dialog_full_holo_dark.9.png
new file mode 100644
index 0000000..26bf28a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dialog_full_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_full_holo_light.9.png b/core/res/res/drawable-mdpi/dialog_full_holo_light.9.png
new file mode 100644
index 0000000..0edfe85
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dialog_full_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_ic_close_focused_holo_dark.png b/core/res/res/drawable-mdpi/dialog_ic_close_focused_holo_dark.png
new file mode 100644
index 0000000..4f08fb4
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dialog_ic_close_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_ic_close_focused_holo_light.png b/core/res/res/drawable-mdpi/dialog_ic_close_focused_holo_light.png
new file mode 100644
index 0000000..cc535bd
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dialog_ic_close_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_ic_close_normal_holo_dark.png b/core/res/res/drawable-mdpi/dialog_ic_close_normal_holo_dark.png
new file mode 100644
index 0000000..9d3e5b9
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dialog_ic_close_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_ic_close_normal_holo_light.png b/core/res/res/drawable-mdpi/dialog_ic_close_normal_holo_light.png
new file mode 100644
index 0000000..74aff55
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dialog_ic_close_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_ic_close_pressed_holo_dark.png b/core/res/res/drawable-mdpi/dialog_ic_close_pressed_holo_dark.png
new file mode 100644
index 0000000..c7f7699
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dialog_ic_close_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_ic_close_pressed_holo_light.png b/core/res/res/drawable-mdpi/dialog_ic_close_pressed_holo_light.png
new file mode 100644
index 0000000..a10f9a6
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dialog_ic_close_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_middle_holo_dark.9.png b/core/res/res/drawable-mdpi/dialog_middle_holo_dark.9.png
new file mode 100644
index 0000000..51e7ec3
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dialog_middle_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_middle_holo_light.9.png b/core/res/res/drawable-mdpi/dialog_middle_holo_light.9.png
new file mode 100644
index 0000000..c4b70625a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dialog_middle_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_top_holo_dark.9.png b/core/res/res/drawable-mdpi/dialog_top_holo_dark.9.png
new file mode 100644
index 0000000..7f97eae
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dialog_top_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_top_holo_light.9.png b/core/res/res/drawable-mdpi/dialog_top_holo_light.9.png
new file mode 100644
index 0000000..341bb4b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dialog_top_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dropdown_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/dropdown_disabled_focused_holo_dark.9.png
new file mode 100644
index 0000000..d9ad9d3
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dropdown_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dropdown_disabled_focused_holo_light.9.png b/core/res/res/drawable-mdpi/dropdown_disabled_focused_holo_light.9.png
new file mode 100644
index 0000000..3d82dc6
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dropdown_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dropdown_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/dropdown_disabled_holo_dark.9.png
new file mode 100644
index 0000000..15e2993
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dropdown_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dropdown_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/dropdown_disabled_holo_light.9.png
new file mode 100644
index 0000000..4831556
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dropdown_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dropdown_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/dropdown_focused_holo_dark.9.png
new file mode 100644
index 0000000..4021da8
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dropdown_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dropdown_focused_holo_light.9.png b/core/res/res/drawable-mdpi/dropdown_focused_holo_light.9.png
new file mode 100644
index 0000000..120fe9a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dropdown_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dropdown_ic_arrow_disabled_focused_holo_dark.png b/core/res/res/drawable-mdpi/dropdown_ic_arrow_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..d2b3557
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dropdown_ic_arrow_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dropdown_ic_arrow_disabled_focused_holo_light.png b/core/res/res/drawable-mdpi/dropdown_ic_arrow_disabled_focused_holo_light.png
new file mode 100644
index 0000000..cf50169
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dropdown_ic_arrow_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dropdown_ic_arrow_disabled_holo_dark.png b/core/res/res/drawable-mdpi/dropdown_ic_arrow_disabled_holo_dark.png
new file mode 100644
index 0000000..2663411
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dropdown_ic_arrow_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dropdown_ic_arrow_disabled_holo_light.png b/core/res/res/drawable-mdpi/dropdown_ic_arrow_disabled_holo_light.png
new file mode 100644
index 0000000..def24e4
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dropdown_ic_arrow_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dropdown_ic_arrow_focused_holo_dark.png b/core/res/res/drawable-mdpi/dropdown_ic_arrow_focused_holo_dark.png
new file mode 100644
index 0000000..9196b72
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dropdown_ic_arrow_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dropdown_ic_arrow_focused_holo_light.png b/core/res/res/drawable-mdpi/dropdown_ic_arrow_focused_holo_light.png
new file mode 100644
index 0000000..85372b9
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dropdown_ic_arrow_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dropdown_ic_arrow_normal_holo_dark.png b/core/res/res/drawable-mdpi/dropdown_ic_arrow_normal_holo_dark.png
new file mode 100644
index 0000000..566be42
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dropdown_ic_arrow_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dropdown_ic_arrow_normal_holo_light.png b/core/res/res/drawable-mdpi/dropdown_ic_arrow_normal_holo_light.png
new file mode 100644
index 0000000..e600500
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dropdown_ic_arrow_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dropdown_ic_arrow_pressed_holo_dark.png b/core/res/res/drawable-mdpi/dropdown_ic_arrow_pressed_holo_dark.png
new file mode 100644
index 0000000..ef21dc2
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dropdown_ic_arrow_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dropdown_ic_arrow_pressed_holo_light.png b/core/res/res/drawable-mdpi/dropdown_ic_arrow_pressed_holo_light.png
new file mode 100644
index 0000000..52fc112
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dropdown_ic_arrow_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dropdown_normal_holo_dark.9.png b/core/res/res/drawable-mdpi/dropdown_normal_holo_dark.9.png
new file mode 100644
index 0000000..a5da0cd
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dropdown_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dropdown_normal_holo_light.9.png b/core/res/res/drawable-mdpi/dropdown_normal_holo_light.9.png
new file mode 100644
index 0000000..6695af9
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dropdown_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dropdown_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/dropdown_pressed_holo_dark.9.png
new file mode 100644
index 0000000..e7e70fb
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dropdown_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dropdown_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/dropdown_pressed_holo_light.9.png
new file mode 100644
index 0000000..f760c88
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dropdown_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_dark.png b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_dark.png
new file mode 100644
index 0000000..6f87b11
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_light.png b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_light.png
new file mode 100644
index 0000000..04dac38
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_moreoverflow_normal_holo_dark.png b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_normal_holo_dark.png
new file mode 100644
index 0000000..5580af6
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_moreoverflow_normal_holo_light.png b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_normal_holo_light.png
new file mode 100644
index 0000000..fc2081a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_section_header_holo_dark.9.png b/core/res/res/drawable-mdpi/list_section_header_holo_dark.9.png
new file mode 100644
index 0000000..48dfea0
--- /dev/null
+++ b/core/res/res/drawable-mdpi/list_section_header_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_section_header_holo_light.9.png b/core/res/res/drawable-mdpi/list_section_header_holo_light.9.png
new file mode 100644
index 0000000..36a046b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/list_section_header_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_selector_activated_holo_dark.9.png b/core/res/res/drawable-mdpi/list_selector_activated_holo_dark.9.png
new file mode 100644
index 0000000..66bc259
--- /dev/null
+++ b/core/res/res/drawable-mdpi/list_selector_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_selector_activated_holo_light.9.png b/core/res/res/drawable-mdpi/list_selector_activated_holo_light.9.png
new file mode 100644
index 0000000..c5822b1
--- /dev/null
+++ b/core/res/res/drawable-mdpi/list_selector_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_selector_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/list_selector_disabled_holo_dark.9.png
new file mode 100644
index 0000000..92da2f0
--- /dev/null
+++ b/core/res/res/drawable-mdpi/list_selector_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_selector_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/list_selector_disabled_holo_light.9.png
new file mode 100644
index 0000000..42cb646
--- /dev/null
+++ b/core/res/res/drawable-mdpi/list_selector_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_selector_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/list_selector_focused_holo_dark.9.png
new file mode 100644
index 0000000..eb4555d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/list_selector_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_selector_focused_holo_light.9.png b/core/res/res/drawable-mdpi/list_selector_focused_holo_light.9.png
new file mode 100644
index 0000000..d799fbf
--- /dev/null
+++ b/core/res/res/drawable-mdpi/list_selector_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_selector_multiselect_holo_dark.9.png b/core/res/res/drawable-mdpi/list_selector_multiselect_holo_dark.9.png
new file mode 100644
index 0000000..2c3647e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/list_selector_multiselect_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_selector_multiselect_holo_light.9.png b/core/res/res/drawable-mdpi/list_selector_multiselect_holo_light.9.png
new file mode 100644
index 0000000..860c58e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/list_selector_multiselect_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_selector_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/list_selector_pressed_holo_dark.9.png
new file mode 100644
index 0000000..bf36a43
--- /dev/null
+++ b/core/res/res/drawable-mdpi/list_selector_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_selector_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/list_selector_pressed_holo_light.9.png
new file mode 100644
index 0000000..0f0be2a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/list_selector_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/menu_dropdown_panel_holo_dark.9.png b/core/res/res/drawable-mdpi/menu_dropdown_panel_holo_dark.9.png
new file mode 100644
index 0000000..7d5c10c
--- /dev/null
+++ b/core/res/res/drawable-mdpi/menu_dropdown_panel_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/menu_dropdown_panel_holo_light.9.png b/core/res/res/drawable-mdpi/menu_dropdown_panel_holo_light.9.png
new file mode 100644
index 0000000..a0d3094d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/menu_dropdown_panel_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickactions_arrowdown_left_holo_dark.9.png b/core/res/res/drawable-mdpi/quickactions_arrowdown_left_holo_dark.9.png
new file mode 100644
index 0000000..ece6551
--- /dev/null
+++ b/core/res/res/drawable-mdpi/quickactions_arrowdown_left_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickactions_arrowdown_left_holo_light.9.png b/core/res/res/drawable-mdpi/quickactions_arrowdown_left_holo_light.9.png
new file mode 100644
index 0000000..819656f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/quickactions_arrowdown_left_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickactions_arrowdown_right_holo_dark.9.png b/core/res/res/drawable-mdpi/quickactions_arrowdown_right_holo_dark.9.png
new file mode 100644
index 0000000..8e95970
--- /dev/null
+++ b/core/res/res/drawable-mdpi/quickactions_arrowdown_right_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickactions_arrowdown_right_holo_light.9.png b/core/res/res/drawable-mdpi/quickactions_arrowdown_right_holo_light.9.png
new file mode 100644
index 0000000..d5bef51
--- /dev/null
+++ b/core/res/res/drawable-mdpi/quickactions_arrowdown_right_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickactions_arrowup_left_holo_dark.9.png b/core/res/res/drawable-mdpi/quickactions_arrowup_left_holo_dark.9.png
new file mode 100644
index 0000000..543e341
--- /dev/null
+++ b/core/res/res/drawable-mdpi/quickactions_arrowup_left_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickactions_arrowup_left_holo_light.9.png b/core/res/res/drawable-mdpi/quickactions_arrowup_left_holo_light.9.png
new file mode 100644
index 0000000..e40e91d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/quickactions_arrowup_left_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickactions_arrowup_left_right_holo_dark.9.png b/core/res/res/drawable-mdpi/quickactions_arrowup_left_right_holo_dark.9.png
new file mode 100644
index 0000000..a4617e7
--- /dev/null
+++ b/core/res/res/drawable-mdpi/quickactions_arrowup_left_right_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickactions_arrowup_right_holo_light.9.png b/core/res/res/drawable-mdpi/quickactions_arrowup_right_holo_light.9.png
new file mode 100644
index 0000000..1e8e7a06
--- /dev/null
+++ b/core/res/res/drawable-mdpi/quickactions_arrowup_right_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_control_holo.png b/core/res/res/drawable-mdpi/scrubber_control_holo.png
new file mode 100644
index 0000000..135b2aa
--- /dev/null
+++ b/core/res/res/drawable-mdpi/scrubber_control_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_track_holo_dark.9.png b/core/res/res/drawable-mdpi/scrubber_track_holo_dark.9.png
new file mode 100644
index 0000000..7b48cf9
--- /dev/null
+++ b/core/res/res/drawable-mdpi/scrubber_track_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_track_holo_light.9.png b/core/res/res/drawable-mdpi/scrubber_track_holo_light.9.png
new file mode 100644
index 0000000..7c84ac9
--- /dev/null
+++ b/core/res/res/drawable-mdpi/scrubber_track_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_check_holo_dark.xml b/core/res/res/drawable/btn_check_holo_dark.xml
index fd85d72..a163c2e 100644
--- a/core/res/res/drawable/btn_check_holo_dark.xml
+++ b/core/res/res/drawable/btn_check_holo_dark.xml
@@ -50,16 +50,16 @@
<!-- Disabled states -->
<item android:state_checked="true" android:state_window_focused="false"
- android:drawable="@drawable/btn_check_on_disable_holo_dark" />
+ android:drawable="@drawable/btn_check_on_disabled_holo_dark" />
<item android:state_checked="false" android:state_window_focused="false"
- android:drawable="@drawable/btn_check_off_disable_holo_dark" />
+ android:drawable="@drawable/btn_check_off_disabled_holo_dark" />
<item android:state_checked="true" android:state_focused="true"
- android:drawable="@drawable/btn_check_on_disable_focused_holo_dark" />
+ android:drawable="@drawable/btn_check_on_disabled_focused_holo_dark" />
<item android:state_checked="false" android:state_focused="true"
- android:drawable="@drawable/btn_check_off_disable_focused_holo_dark" />
+ android:drawable="@drawable/btn_check_off_disabled_focused_holo_dark" />
- <item android:state_checked="false" android:drawable="@drawable/btn_check_off_disable_holo_dark" />
- <item android:state_checked="true" android:drawable="@drawable/btn_check_on_disable_holo_dark" />
+ <item android:state_checked="false" android:drawable="@drawable/btn_check_off_disabled_holo_dark" />
+ <item android:state_checked="true" android:drawable="@drawable/btn_check_on_disabled_holo_dark" />
</selector>
diff --git a/core/res/res/drawable/btn_check_holo_light.xml b/core/res/res/drawable/btn_check_holo_light.xml
index 4fb16fa..5c49456 100644
--- a/core/res/res/drawable/btn_check_holo_light.xml
+++ b/core/res/res/drawable/btn_check_holo_light.xml
@@ -50,16 +50,16 @@
<!-- Disabled states -->
<item android:state_checked="true" android:state_window_focused="false"
- android:drawable="@drawable/btn_check_on_disable_holo_light" />
+ android:drawable="@drawable/btn_check_on_disabled_holo_light" />
<item android:state_checked="false" android:state_window_focused="false"
- android:drawable="@drawable/btn_check_off_disable_holo_light" />
+ android:drawable="@drawable/btn_check_off_disabled_holo_light" />
<item android:state_checked="true" android:state_focused="true"
- android:drawable="@drawable/btn_check_on_disable_focused_holo_light" />
+ android:drawable="@drawable/btn_check_on_disabled_focused_holo_light" />
<item android:state_checked="false" android:state_focused="true"
- android:drawable="@drawable/btn_check_off_disable_focused_holo_light" />
+ android:drawable="@drawable/btn_check_off_disabled_focused_holo_light" />
- <item android:state_checked="false" android:drawable="@drawable/btn_check_off_disable_holo_light" />
- <item android:state_checked="true" android:drawable="@drawable/btn_check_on_disable_holo_light" />
+ <item android:state_checked="false" android:drawable="@drawable/btn_check_off_disabled_holo_light" />
+ <item android:state_checked="true" android:drawable="@drawable/btn_check_on_disabled_holo_light" />
</selector>
diff --git a/core/res/res/drawable/ic_menu_moreoverflow_holo_dark.xml b/core/res/res/drawable/ic_menu_moreoverflow_holo_dark.xml
new file mode 100644
index 0000000..4691edf
--- /dev/null
+++ b/core/res/res/drawable/ic_menu_moreoverflow_holo_dark.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_focused="true" android:drawable="@drawable/ic_menu_moreoverflow_focused_holo_dark" />
+ <item android:drawable="@drawable/ic_menu_moreoverflow_normal_holo_dark" />
+</selector>
diff --git a/core/res/res/drawable/ic_menu_moreoverflow_holo_light.xml b/core/res/res/drawable/ic_menu_moreoverflow_holo_light.xml
new file mode 100644
index 0000000..5c52ff4
--- /dev/null
+++ b/core/res/res/drawable/ic_menu_moreoverflow_holo_light.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_focused="true" android:drawable="@drawable/ic_menu_moreoverflow_focused_holo_light" />
+ <item android:drawable="@drawable/ic_menu_moreoverflow_normal_holo_light" />
+</selector>
diff --git a/core/res/res/drawable/list_selector_holo_dark.xml b/core/res/res/drawable/list_selector_holo_dark.xml
new file mode 100644
index 0000000..ee59904
--- /dev/null
+++ b/core/res/res/drawable/list_selector_holo_dark.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item android:state_window_focused="false" android:drawable="@color/transparent" />
+
+ <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
+ <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/list_selector_disabled_holo_dark" />
+ <item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/list_selector_disabled_holo_dark" />
+ <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/list_selector_background_transition" />
+ <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/list_selector_background_transition" />
+ <item android:state_focused="true" android:drawable="@drawable/list_selector_focused_holo_dark" />
+ <item android:drawable="@drawable/list_selector_focused_holo_dark" />
+
+</selector>
diff --git a/core/res/res/drawable/list_selector_holo_light.xml b/core/res/res/drawable/list_selector_holo_light.xml
new file mode 100644
index 0000000..2dc39f6
--- /dev/null
+++ b/core/res/res/drawable/list_selector_holo_light.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item android:state_window_focused="false" android:drawable="@color/transparent" />
+
+ <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
+ <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/list_selector_disabled_holo_light" />
+ <item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/list_selector_disabled_holo_light" />
+ <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/list_selector_background_transition" />
+ <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/list_selector_background_transition" />
+ <item android:state_focused="true" android:drawable="@drawable/list_selector_focused_holo_light" />
+ <item android:drawable="@drawable/list_selector_focused_holo_light" />
+
+</selector>
diff --git a/core/res/res/drawable/scrubber_progress_horizontal_holo_dark.xml b/core/res/res/drawable/scrubber_progress_horizontal_holo_dark.xml
new file mode 100644
index 0000000..90172a5
--- /dev/null
+++ b/core/res/res/drawable/scrubber_progress_horizontal_holo_dark.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item android:id="@android:id/background"
+ android:drawable="@android:drawable/scrubber_track_holo_dark" />
+ <item android:id="@android:id/secondaryProgress"
+ android:drawable="@android:drawable/scrubber_track_holo_dark" />
+ <item android:id="@android:id/progress"
+ android:drawable="@android:drawable/scrubber_track_holo_dark" />
+</layer-list>
diff --git a/core/res/res/drawable/scrubber_progress_horizontal_holo_light.xml b/core/res/res/drawable/scrubber_progress_horizontal_holo_light.xml
new file mode 100644
index 0000000..5fc9697
--- /dev/null
+++ b/core/res/res/drawable/scrubber_progress_horizontal_holo_light.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item android:id="@android:id/background"
+ android:drawable="@android:drawable/scrubber_track_holo_light" />
+ <item android:id="@android:id/secondaryProgress"
+ android:drawable="@android:drawable/scrubber_track_holo_light" />
+ <item android:id="@android:id/progress"
+ android:drawable="@android:drawable/scrubber_track_holo_light" />
+</layer-list>
diff --git a/core/res/res/layout-xlarge/alert_dialog.xml b/core/res/res/layout-xlarge/alert_dialog.xml
new file mode 100644
index 0000000..5291e9d
--- /dev/null
+++ b/core/res/res/layout-xlarge/alert_dialog.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/layout/alert_dialog.xml
+**
+** Copyright 2006, 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.
+*/
+-->
+
+<com.android.internal.widget.WeightedLinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/parentPanel"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingTop="9dip"
+ android:paddingBottom="3dip"
+ android:paddingLeft="3dip"
+ android:paddingRight="1dip"
+ android:majorWeightMin="0.45"
+ android:minorWeightMin="0.72"
+ android:majorWeightMax="0.45"
+ android:minorWeightMax="0.72">
+
+ <LinearLayout android:id="@+id/topPanel"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="54dip"
+ android:orientation="vertical">
+ <LinearLayout android:id="@+id/title_template"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:layout_marginTop="6dip"
+ android:layout_marginBottom="9dip"
+ android:layout_marginLeft="10dip"
+ android:layout_marginRight="10dip">
+ <ImageView android:id="@+id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top"
+ android:paddingTop="6dip"
+ android:paddingRight="10dip"
+ android:src="@drawable/ic_dialog_info" />
+ <com.android.internal.widget.DialogTitle android:id="@+id/alertTitle"
+ style="?android:attr/textAppearanceLarge"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+ </LinearLayout>
+ <ImageView android:id="@+id/titleDivider"
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:visibility="gone"
+ android:scaleType="fitXY"
+ android:gravity="fill_horizontal"
+ android:src="@android:drawable/divider_horizontal_dark" />
+ <!-- If the client uses a customTitle, it will be added here. -->
+ </LinearLayout>
+
+ <LinearLayout android:id="@+id/contentPanel"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="vertical">
+ <ScrollView android:id="@+id/scrollView"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="2dip"
+ android:paddingBottom="12dip"
+ android:paddingLeft="14dip"
+ android:paddingRight="10dip">
+ <TextView android:id="@+id/message"
+ style="?android:attr/textAppearanceMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="5dip" />
+ </ScrollView>
+ </LinearLayout>
+
+ <FrameLayout android:id="@+id/customPanel"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1">
+ <FrameLayout android:id="@+android:id/custom"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="5dip"
+ android:paddingBottom="5dip" />
+ </FrameLayout>
+
+ <LinearLayout android:id="@+id/buttonPanel"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="54dip"
+ android:orientation="vertical" >
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:paddingTop="4dip"
+ android:paddingLeft="2dip"
+ android:paddingRight="2dip"
+ android:measureWithLargestChild="true">
+ <LinearLayout android:id="@+id/leftSpacer"
+ android:layout_weight="0.25"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:visibility="gone" />
+ <Button android:id="@+id/button1"
+ android:layout_width="0dip"
+ android:layout_gravity="left"
+ android:layout_weight="1"
+ android:maxLines="2"
+ android:layout_height="wrap_content" />
+ <Button android:id="@+id/button3"
+ android:layout_width="0dip"
+ android:layout_gravity="center_horizontal"
+ android:layout_weight="1"
+ android:maxLines="2"
+ android:layout_height="wrap_content" />
+ <Button android:id="@+id/button2"
+ android:layout_width="0dip"
+ android:layout_gravity="right"
+ android:layout_weight="1"
+ android:maxLines="2"
+ android:layout_height="wrap_content" />
+ <LinearLayout android:id="@+id/rightSpacer"
+ android:layout_width="0dip"
+ android:layout_weight="0.25"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:visibility="gone" />
+ </LinearLayout>
+ </LinearLayout>
+</com.android.internal.widget.WeightedLinearLayout>
diff --git a/core/res/res/layout/alert_dialog.xml b/core/res/res/layout/alert_dialog.xml
index b746d28..541d84d 100644
--- a/core/res/res/layout/alert_dialog.xml
+++ b/core/res/res/layout/alert_dialog.xml
@@ -28,8 +28,9 @@
android:paddingBottom="3dip"
android:paddingLeft="3dip"
android:paddingRight="1dip"
- android:majorWeight="0.65"
- android:minorWeight="0.9">
+ android:majorWeightMin="0.65"
+ android:minorWeightMin="0.9"
+ android:majorWeightMax="0.65">
<LinearLayout android:id="@+id/topPanel"
android:layout_width="match_parent"
diff --git a/core/res/res/layout/fragment_bread_crumb_item.xml b/core/res/res/layout/fragment_bread_crumb_item.xml
index 408f6e8..517c570 100644
--- a/core/res/res/layout/fragment_bread_crumb_item.xml
+++ b/core/res/res/layout/fragment_bread_crumb_item.xml
@@ -19,7 +19,7 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
- android:textAppearance="?android:attr/textAppearanceMediumInverse"
+ android:textAppearance="?android:attr/textAppearanceMedium"
android:drawableLeft="@drawable/nav_divider"
android:paddingLeft="12dp"
android:drawablePadding="12dp"
diff --git a/core/res/res/layout/list_menu_item_layout.xml b/core/res/res/layout/list_menu_item_layout.xml
index 39c88722..57091a1 100644
--- a/core/res/res/layout/list_menu_item_layout.xml
+++ b/core/res/res/layout/list_menu_item_layout.xml
@@ -36,7 +36,7 @@
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
- android:textAppearance="?android:attr/textAppearanceLargeInverse"
+ android:textAppearance="?android:attr/textAppearanceLarge"
android:singleLine="true"
android:duplicateParentState="true"
android:ellipsize="marquee"
@@ -48,7 +48,7 @@
android:layout_height="wrap_content"
android:layout_below="@id/title"
android:layout_alignParentLeft="true"
- android:textAppearance="?android:attr/textAppearanceSmallInverse"
+ android:textAppearance="?android:attr/textAppearanceSmall"
android:singleLine="true"
android:duplicateParentState="true" />
diff --git a/core/res/res/values-xlarge/config.xml b/core/res/res/values-xlarge/config.xml
index 7e5a27b..813651e 100644
--- a/core/res/res/values-xlarge/config.xml
+++ b/core/res/res/values-xlarge/config.xml
@@ -25,6 +25,9 @@
<string name="config_statusBarComponent">com.android.systemui/com.android.systemui.statusbar.tablet.TabletStatusBarService</string>
<bool name="config_statusBarCanHide">false</bool>
+ <!-- see comment in values/config.xml -->
+ <integer name="config_longPressOnPowerBehavior">2</integer>
+
<!-- Show sliding tab before lockscreen -->
<bool name="config_enableSlidingTabFirst">false</bool>
<!-- Enable lockscreen rotation -->
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 33d3eeb..d9f0039 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -551,6 +551,10 @@
anchor for positioning the cursor within text. -->
<attr name="textSelectHandle" format="reference" />
+ <!-- Theme to use for dialogs spawned from this theme. -->
+ <attr name="dialogTheme" format="reference" />
+ <!-- Theme to use for alert dialogs spawned from this theme. -->
+ <attr name="alertDialogTheme" format="reference" />
</declare-styleable>
<!-- **************************************************************** -->
@@ -2605,8 +2609,10 @@
<!-- @hide -->
<declare-styleable name="WeightedLinearLayout">
- <attr name="majorWeight" format="float" />
- <attr name="minorWeight" format="float" />
+ <attr name="majorWeightMin" format="float" />
+ <attr name="minorWeightMin" format="float" />
+ <attr name="majorWeightMax" format="float" />
+ <attr name="minorWeightMax" format="float" />
</declare-styleable>
<!-- ========================= -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 71967d4a..d353db6 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -221,6 +221,13 @@
closed. The default is 0. -->
<integer name="config_lidNavigationAccessibility">0</integer>
+ <!-- Control the behavior when the user long presses the power button.
+ 0 - Nothing
+ 1 - Global actions menu
+ 2 - Power off (with confirmation)
+ -->
+ <integer name="config_longPressOnPowerBehavior">1</integer>
+
<!-- Indicate whether the SD card is accessible without removing the battery. -->
<bool name="config_batterySdCardAccessibility">false</bool>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 2c3c4fc..ae25715 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1366,6 +1366,8 @@
<public type="attr" name="listDividerAlertDialog" />
<public type="attr" name="textColorAlertDialogListItem" />
<public type="attr" name="loopViews" />
+ <public type="attr" name="dialogTheme" />
+ <public type="attr" name="alertDialogTheme" />
<public type="anim" name="animator_fade_in" />
<public type="anim" name="animator_fade_out" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 521a739..0172827 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -280,9 +280,16 @@
<!-- Shutdown Progress Dialog. This is shown if the user chooses to power off the phone. -->
<string name="shutdown_progress">Shutting down\u2026</string>
- <!-- Shutdown Confirmation Dialog. When the user chooses to power off the phone, there will be a confirmation dialog. This is the message. -->
+ <!-- Shutdown Confirmation Dialog. When the user chooses to power off the phone, there will
+ be a confirmation dialog. This is the message. -->
<string name="shutdown_confirm">Your phone will shut down.</string>
+ <!-- Shutdown Confirmation Dialog. When the user chooses to power off the phone, it asks
+ the user if they'd like to shut down. This is the message. This is used instead of
+ shutdown_confirm when the system is configured to use long press to go directly to the
+ power off dialog instead of the global actions menu. -->
+ <string name="shutdown_confirm_question">Would you like to shut down?</string>
+
<!-- Recent Tasks dialog: title
TODO: this should move to SystemUI.apk, but the code for the old
recent dialog is still in the framework
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 0f653f1..8f7ace9 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1091,12 +1091,15 @@
</style>
<style name="TextAppearance.Holo.Widget.PopupMenu" parent="TextAppearance.Widget.PopupMenu">
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
</style>
- <style name="TextAppearance.Holo.Widget.PopupMenu.Large" parent="TextAppearance.Widget.PopupMenu.Large">
+ <style name="TextAppearance.Holo.Widget.PopupMenu.Large">
+ <item name="android:textSize">22sp</item>
</style>
- <style name="TextAppearance.Holo.Widget.PopupMenu.Small" parent="TextAppearance.Widget.PopupMenu.Small">
+ <style name="TextAppearance.Holo.Widget.PopupMenu.Small">
+ <item name="android:textSize">14sp</item>
</style>
<style name="TextAppearance.Holo.Widget.ActionBar.Title"
@@ -1261,6 +1264,7 @@
</style>
<style name="Widget.Holo.TextView.ListSeparator" parent="Widget.TextView.ListSeparator">
+ <item name="android:background">@android:drawable/list_section_header_holo_dark</item>
</style>
<style name="Widget.Holo.TextSelectHandle" parent="Widget.TextSelectHandle">
@@ -1335,7 +1339,15 @@
<style name="Widget.Holo.ProgressBar.Large.Inverse" parent="Widget.ProgressBar.Large.Inverse">
</style>
- <style name="Widget.Holo.SeekBar" parent="Widget.SeekBar">
+ <style name="Widget.Holo.SeekBar">
+ <item name="android:indeterminateOnly">false</item>
+ <item name="android:progressDrawable">@android:drawable/scrubber_progress_horizontal_holo_dark</item>
+ <item name="android:indeterminateDrawable">@android:drawable/scrubber_progress_horizontal_holo_dark</item>
+ <item name="android:minHeight">16dip</item>
+ <item name="android:maxHeight">16dip</item>
+ <item name="android:thumb">@android:drawable/scrubber_control_holo</item>
+ <item name="android:thumbOffset">16dip</item>
+ <item name="android:focusable">true</item>
</style>
<style name="Widget.Holo.RatingBar" parent="Widget.RatingBar">
@@ -1357,6 +1369,12 @@
</style>
<style name="Widget.Holo.Spinner" parent="Widget.Spinner.DropDown">
+ <item name="android:dropDownSelector">@android:drawable/list_selector_holo_dark</item>
+ <item name="android:popupBackground">@android:drawable/menu_dropdown_panel_holo_dark</item>
+ <item name="android:dropDownVerticalOffset">0dip</item>
+ <item name="android:dropDownHorizontalOffset">0dip</item>
+ <item name="android:dropDownWidth">wrap_content</item>
+ <item name="android:popupPromptView">@android:layout/simple_dropdown_hint</item>
</style>
<style name="Widget.Holo.Spinner.DropDown">
@@ -1405,15 +1423,21 @@
</style>
<style name="Widget.Holo.ListPopupWindow" parent="Widget.ListPopupWindow">
+ <item name="android:dropDownSelector">@android:drawable/list_selector_holo_dark</item>
+ <item name="android:popupBackground">@android:drawable/menu_dropdown_panel_holo_dark</item>
+ <item name="android:dropDownVerticalOffset">0dip</item>
+ <item name="android:dropDownHorizontalOffset">0dip</item>
+ <item name="android:dropDownWidth">wrap_content</item>
</style>
- <style name="Widget.Holo.PopupMenu" parent="Widget.PopupMenu">
+ <style name="Widget.Holo.PopupMenu" parent="Widget.Holo.ListPopupWindow">
</style>
<style name="Widget.Holo.ActionButton" parent="Widget.ActionButton">
</style>
<style name="Widget.Holo.ActionButton.Overflow" parent="Widget.ActionButton.Overflow">
+ <item name="android:src">@android:drawable/ic_menu_moreoverflow_holo_dark</item>
</style>
<style name="Widget.Holo.ActionBarView_TabView" parent="Widget.ActionBarView_TabView">
@@ -1441,6 +1465,7 @@
<style name="Widget.Holo.ActionBar" parent="Widget.ActionBar">
<item name="android:titleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionBar.Title</item>
<item name="android:subtitleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionBar.Subtitle</item>
+ <item name="android:background">@null</item>
</style>
<!-- Light widget styles -->
@@ -1472,6 +1497,7 @@
</style>
<style name="Widget.Holo.Light.TextView.ListSeparator" parent="Widget.TextView.ListSeparator">
+ <item name="android:background">@android:drawable/list_section_header_holo_light</item>
</style>
<style name="Widget.Holo.Light.TextSelectHandle" parent="Widget.TextSelectHandle">
@@ -1546,7 +1572,9 @@
<style name="Widget.Holo.Light.ProgressBar.Large.Inverse" parent="Widget.ProgressBar.Large.Inverse">
</style>
- <style name="Widget.Holo.Light.SeekBar" parent="Widget.SeekBar">
+ <style name="Widget.Holo.Light.SeekBar" parent="Widget.Holo.SeekBar">
+ <item name="android:progressDrawable">@android:drawable/scrubber_progress_horizontal_holo_light</item>
+ <item name="android:indeterminateDrawable">@android:drawable/scrubber_progress_horizontal_holo_light</item>
</style>
<style name="Widget.Holo.Light.RatingBar" parent="Widget.RatingBar">
@@ -1568,6 +1596,12 @@
</style>
<style name="Widget.Holo.Light.Spinner" parent="Widget.Spinner.DropDown">
+ <item name="android:dropDownSelector">@android:drawable/list_selector_holo_light</item>
+ <item name="android:popupBackground">@android:drawable/menu_dropdown_panel_holo_light</item>
+ <item name="android:dropDownVerticalOffset">0dip</item>
+ <item name="android:dropDownHorizontalOffset">0dip</item>
+ <item name="android:dropDownWidth">wrap_content</item>
+ <item name="android:popupPromptView">@android:layout/simple_dropdown_hint</item>
</style>
<style name="Widget.Holo.Light.Spinner.DropDown">
@@ -1616,15 +1650,21 @@
</style>
<style name="Widget.Holo.Light.ListPopupWindow" parent="Widget.ListPopupWindow">
+ <item name="android:dropDownSelector">@android:drawable/list_selector_holo_light</item>
+ <item name="android:popupBackground">@android:drawable/menu_dropdown_panel_holo_light</item>
+ <item name="android:dropDownVerticalOffset">0dip</item>
+ <item name="android:dropDownHorizontalOffset">0dip</item>
+ <item name="android:dropDownWidth">wrap_content</item>
</style>
- <style name="Widget.Holo.Light.PopupMenu" parent="Widget.PopupMenu">
+ <style name="Widget.Holo.Light.PopupMenu" parent="Widget.Holo.Light.ListPopupWindow">
</style>
<style name="Widget.Holo.Light.ActionButton" parent="Widget.ActionButton">
</style>
<style name="Widget.Holo.Light.ActionButton.Overflow" parent="Widget.ActionButton.Overflow">
+ <item name="android:src">@android:drawable/ic_menu_moreoverflow_holo_light</item>
</style>
<style name="Widget.Holo.Light.ActionBarView_TabView" parent="Widget.ActionBarView_TabView">
@@ -1648,6 +1688,7 @@
<style name="Widget.Holo.Light.ActionBar" parent="Widget.ActionBar">
<item name="android:titleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionBar.Title</item>
<item name="android:subtitleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionBar.Subtitle</item>
+ <item name="android:background">@null</item>
</style>
<!-- Animation Styles -->
@@ -1664,16 +1705,29 @@
<!-- Dialog styles -->
<style name="AlertDialog.Holo" parent="AlertDialog">
- <item name="fullDark">@android:drawable/dialog_full_holo</item>
- <item name="topDark">@android:drawable/dialog_top_holo</item>
- <item name="centerDark">@android:drawable/dialog_middle_holo</item>
- <item name="bottomDark">@android:drawable/dialog_bottom_holo</item>
- <item name="fullBright">@android:drawable/dialog_full_holo</item>
- <item name="topBright">@android:drawable/dialog_top_holo</item>
- <item name="centerBright">@android:drawable/dialog_middle_holo</item>
- <item name="bottomBright">@android:drawable/dialog_bottom_holo</item>
- <item name="bottomMedium">@android:drawable/dialog_bottom_holo</item>
- <item name="centerMedium">@android:drawable/dialog_middle_holo</item>
+ <item name="fullDark">@android:drawable/dialog_full_holo_dark</item>
+ <item name="topDark">@android:drawable/dialog_top_holo_dark</item>
+ <item name="centerDark">@android:drawable/dialog_middle_holo_dark</item>
+ <item name="bottomDark">@android:drawable/dialog_bottom_holo_dark</item>
+ <item name="fullBright">@android:drawable/dialog_full_holo_dark</item>
+ <item name="topBright">@android:drawable/dialog_top_holo_dark</item>
+ <item name="centerBright">@android:drawable/dialog_middle_holo_dark</item>
+ <item name="bottomBright">@android:drawable/dialog_bottom_holo_dark</item>
+ <item name="bottomMedium">@android:drawable/dialog_bottom_holo_dark</item>
+ <item name="centerMedium">@android:drawable/dialog_middle_holo_dark</item>
+ </style>
+
+ <style name="AlertDialog.Holo.Light">
+ <item name="fullDark">@android:drawable/dialog_full_holo_light</item>
+ <item name="topDark">@android:drawable/dialog_top_holo_light</item>
+ <item name="centerDark">@android:drawable/dialog_middle_holo_light</item>
+ <item name="bottomDark">@android:drawable/dialog_bottom_holo_light</item>
+ <item name="fullBright">@android:drawable/dialog_full_holo_light</item>
+ <item name="topBright">@android:drawable/dialog_top_holo_light</item>
+ <item name="centerBright">@android:drawable/dialog_middle_holo_light</item>
+ <item name="bottomBright">@android:drawable/dialog_bottom_holo_light</item>
+ <item name="bottomMedium">@android:drawable/dialog_bottom_holo_light</item>
+ <item name="centerMedium">@android:drawable/dialog_middle_holo_light</item>
</style>
<!-- Window title -->
@@ -1694,4 +1748,10 @@
<item name="android:textAppearance">@style/TextAppearance.Holo.DialogWindowTitle</item>
</style>
+ <style name="DialogWindowTitle.Holo.Light">
+ <item name="android:maxLines">1</item>
+ <item name="android:scrollHorizontally">true</item>
+ <item name="android:textAppearance">@style/TextAppearance.Holo.Light.DialogWindowTitle</item>
+ </style>
+
</resources>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 21d91ba..8daa802 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -137,6 +137,8 @@
<!-- Dialog attributes -->
<item name="alertDialogStyle">@android:style/AlertDialog</item>
+ <item name="dialogTheme">@android:style/Theme.Dialog</item>
+ <item name="alertDialogTheme">@android:style/Theme.Dialog.Alert</item>
<!-- Panel attributes -->
<item name="panelBackground">@android:drawable/menu_background</item>
@@ -156,8 +158,8 @@
<item name="scrollbarTrackVertical">@null</item>
<!-- Text selection handle attributes -->
- <item name="textSelectHandleLeft">@android:drawable/text_select_handle_middle</item>
- <item name="textSelectHandleRight">@android:drawable/text_select_handle_middle</item>
+ <item name="textSelectHandleLeft">@android:drawable/text_select_handle_left</item>
+ <item name="textSelectHandleRight">@android:drawable/text_select_handle_right</item>
<item name="textSelectHandle">@android:drawable/text_select_handle_middle</item>
<item name="textSelectHandleWindowStyle">@android:style/Widget.TextSelectHandle</item>
@@ -689,9 +691,9 @@
<item name="listChoiceIndicatorSingle">@android:drawable/btn_radio_holo_dark</item>
<item name="listChoiceIndicatorMultiple">@android:drawable/btn_check_holo_dark</item>
- <item name="listChoiceBackgroundIndicator">@android:drawable/list_selected_background</item>
+ <item name="listChoiceBackgroundIndicator">@android:drawable/list_selector_holo_dark</item>
- <item name="activatedBackgroundIndicator">@android:drawable/activated_background</item>
+ <item name="activatedBackgroundIndicator">@android:drawable/list_selector_activated_holo_dark</item>
<item name="listDividerAlertDialog">@android:drawable/divider_horizontal_holo_dark</item>
@@ -715,7 +717,7 @@
<item name="windowNoTitle">false</item>
<item name="windowFullscreen">false</item>
<item name="windowIsFloating">false</item>
- <item name="windowContentOverlay">@android:drawable/title_bar_shadow</item>
+ <item name="windowContentOverlay">@null</item>
<item name="windowShowWallpaper">false</item>
<item name="windowTitleStyle">@android:style/WindowTitle.Holo</item>
<item name="windowTitleSize">25dip</item>
@@ -727,6 +729,8 @@
<!-- Dialog attributes -->
<item name="alertDialogStyle">@android:style/AlertDialog.Holo</item>
+ <item name="dialogTheme">@android:style/Theme.Holo.Dialog</item>
+ <item name="alertDialogTheme">@android:style/Theme.Holo.Dialog.Alert</item>
<!-- Panel attributes -->
<item name="panelBackground">@android:drawable/menu_background</item>
@@ -907,15 +911,15 @@
<item name="listPreferredItemHeight">64dip</item>
<!-- @hide -->
<item name="searchResultListItemHeight">58dip</item>
- <item name="listDivider">@drawable/divider_horizontal_holo_dark</item>
+ <item name="listDivider">@drawable/divider_horizontal_holo_light</item>
<item name="listSeparatorTextViewStyle">@android:style/Widget.Holo.Light.TextView.ListSeparator</item>
- <item name="listChoiceIndicatorSingle">@android:drawable/btn_radio</item>
- <item name="listChoiceIndicatorMultiple">@android:drawable/btn_check</item>
+ <item name="listChoiceIndicatorSingle">@android:drawable/btn_radio_holo_light</item>
+ <item name="listChoiceIndicatorMultiple">@android:drawable/btn_check_holo_light</item>
- <item name="listChoiceBackgroundIndicator">@android:drawable/list_selected_background</item>
+ <item name="listChoiceBackgroundIndicator">@android:drawable/list_selector_holo_light</item>
- <item name="activatedBackgroundIndicator">@android:drawable/activated_background</item>
+ <item name="activatedBackgroundIndicator">@android:drawable/list_selector_activated_holo_light</item>
<item name="expandableListPreferredItemPaddingLeft">40dip</item>
<item name="expandableListPreferredChildPaddingLeft">
@@ -928,7 +932,7 @@
<item name="expandableListPreferredChildIndicatorRight">
?android:attr/expandableListPreferredItemIndicatorRight</item>
- <item name="listDividerAlertDialog">@android:drawable/divider_horizontal_holo_dark</item>
+ <item name="listDividerAlertDialog">@android:drawable/divider_horizontal_holo_light</item>
<!-- Gallery attributes -->
<item name="galleryItemBackground">@android:drawable/gallery_item_background</item>
@@ -939,7 +943,7 @@
<item name="windowNoTitle">false</item>
<item name="windowFullscreen">false</item>
<item name="windowIsFloating">false</item>
- <item name="windowContentOverlay">@android:drawable/title_bar_shadow</item>
+ <item name="windowContentOverlay">@null</item>
<item name="windowShowWallpaper">false</item>
<item name="windowTitleStyle">@android:style/WindowTitle.Holo</item>
<item name="windowTitleSize">25dip</item>
@@ -950,7 +954,9 @@
<item name="windowActionModeOverlay">false</item>
<!-- Dialog attributes -->
- <item name="alertDialogStyle">@android:style/AlertDialog.Holo</item>
+ <item name="alertDialogStyle">@android:style/AlertDialog.Holo.Light</item>
+ <item name="dialogTheme">@android:style/Theme.Holo.Light.Dialog</item>
+ <item name="alertDialogTheme">@android:style/Theme.Holo.Light.Dialog.Alert</item>
<!-- Panel attributes -->
<item name="panelBackground">@android:drawable/menu_background</item>
@@ -1024,8 +1030,8 @@
<item name="quickContactBadgeStyleSmallWindowSmall">@android:style/Widget.Holo.QuickContactBadgeSmall.WindowSmall</item>
<item name="quickContactBadgeStyleSmallWindowMedium">@android:style/Widget.Holo.QuickContactBadgeSmall.WindowMedium</item>
<item name="quickContactBadgeStyleSmallWindowLarge">@android:style/Widget.Holo.QuickContactBadgeSmall.WindowLarge</item>
- <item name="listPopupWindowStyle">@android:style/Widget.Holo.ListPopupWindow</item>
- <item name="popupMenuStyle">@android:style/Widget.Holo.PopupMenu</item>
+ <item name="listPopupWindowStyle">@android:style/Widget.Holo.Light.ListPopupWindow</item>
+ <item name="popupMenuStyle">@android:style/Widget.Holo.Light.PopupMenu</item>
<!-- Preference styles -->
<item name="preferenceScreenStyle">@android:style/Preference.PreferenceScreen</item>
@@ -1101,7 +1107,7 @@
<style name="Theme.Holo.Dialog">
<item name="android:windowFrame">@null</item>
<item name="android:windowTitleStyle">@android:style/DialogWindowTitle.Holo</item>
- <item name="android:windowBackground">@android:drawable/dialog_full_holo</item>
+ <item name="android:windowBackground">@android:drawable/dialog_full_holo_dark</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Holo.Dialog</item>
@@ -1138,4 +1144,40 @@
<item name="windowContentOverlay">@null</item>
</style>
+ <!-- Light holo dialog themes -->
+
+ <!-- Holo light theme for dialog windows and activities, which is used by the
+ {@link android.app.Dialog} class. This changes the window to be
+ floating (not fill the entire screen), and puts a frame around its
+ contents. You can set this theme on an activity if you would like to
+ make an activity that looks like a Dialog.
+ This is the default Dialog theme for applications targeting Honeycomb
+ or newer. -->
+ <style name="Theme.Holo.Light.Dialog">
+ <item name="android:windowFrame">@null</item>
+ <item name="android:windowTitleStyle">@android:style/DialogWindowTitle.Holo.Light</item>
+ <item name="android:windowBackground">@android:drawable/dialog_full_holo_light</item>
+ <item name="android:windowIsFloating">true</item>
+ <item name="android:windowContentOverlay">@null</item>
+ <item name="android:windowAnimationStyle">@android:style/Animation.Holo.Dialog</item>
+ <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
+ <item name="android:windowActionBar">false</item>
+
+ <item name="android:colorBackgroundCacheHint">@null</item>
+
+ <item name="textAppearance">@android:style/TextAppearance.Holo.Light</item>
+ <item name="textAppearanceInverse">@android:style/TextAppearance.Holo.Light.Inverse</item>
+ </style>
+
+ <!-- Holo light theme for alert dialog windows, which is used by the
+ {@link android.app.AlertDialog} class. This is basically a dialog
+ but sets the background to empty so it can do two-tone backgrounds.
+ For applications targeting Honeycomb or newer, this is the default
+ AlertDialog theme. -->
+ <style name="Theme.Holo.Light.Dialog.Alert">
+ <item name="windowBackground">@android:color/transparent</item>
+ <item name="windowTitleStyle">@android:style/DialogWindowTitle.Holo.Light</item>
+ <item name="windowContentOverlay">@null</item>
+ </style>
+
</resources>
diff --git a/core/tests/coretests/res/raw/test1.obb b/core/tests/coretests/res/raw/test1.obb
new file mode 100644
index 0000000..170e36f
--- /dev/null
+++ b/core/tests/coretests/res/raw/test1.obb
Binary files differ
diff --git a/core/tests/coretests/res/raw/test1_nosig.obb b/core/tests/coretests/res/raw/test1_nosig.obb
new file mode 100644
index 0000000..5c3573f7
--- /dev/null
+++ b/core/tests/coretests/res/raw/test1_nosig.obb
Binary files differ
diff --git a/core/tests/coretests/res/raw/test1_wrongpackage.obb b/core/tests/coretests/res/raw/test1_wrongpackage.obb
new file mode 100644
index 0000000..2e02eaa
--- /dev/null
+++ b/core/tests/coretests/res/raw/test1_wrongpackage.obb
Binary files differ
diff --git a/core/tests/coretests/src/com/android/server/MountServiceTests.java b/core/tests/coretests/src/com/android/server/MountServiceTests.java
new file mode 100644
index 0000000..83e9d18
--- /dev/null
+++ b/core/tests/coretests/src/com/android/server/MountServiceTests.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2010 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.frameworks.coretests.R;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
+import android.os.Environment;
+import android.os.FileUtils;
+import android.os.storage.OnObbStateChangeListener;
+import android.os.storage.StorageManager;
+import android.test.AndroidTestCase;
+import android.test.ComparisonFailure;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+
+import java.io.File;
+import java.io.InputStream;
+
+public class MountServiceTests extends AndroidTestCase {
+ private static final String TAG = "MountServiceTests";
+
+ private static final long MAX_WAIT_TIME = 25*1000;
+ private static final long WAIT_TIME_INCR = 5*1000;
+
+ private static final String OBB_MOUNT_PREFIX = "/mnt/obb/";
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ private static void assertStartsWith(String message, String prefix, String actual) {
+ if (!actual.startsWith(prefix)) {
+ throw new ComparisonFailure(message, prefix, actual);
+ }
+ }
+
+ private interface CompletableTask {
+ public boolean isDone();
+ }
+
+ private static class ObbObserver extends OnObbStateChangeListener implements CompletableTask {
+ public String path;
+ public String state;
+ boolean done = false;
+
+ @Override
+ public void onObbStateChange(String path, String state) {
+ synchronized (this) {
+ this.path = path;
+ this.state = state;
+ done = true;
+ notifyAll();
+ }
+ }
+
+ public void reset() {
+ this.path = null;
+ this.state = null;
+ done = false;
+ }
+
+ public boolean isDone() {
+ return done;
+ }
+ }
+
+ private boolean waitForCompletion(CompletableTask task) {
+ long waitTime = 0;
+ synchronized (task) {
+ while (!task.isDone() && waitTime < MAX_WAIT_TIME) {
+ try {
+ task.wait(WAIT_TIME_INCR);
+ waitTime += WAIT_TIME_INCR;
+ } catch (InterruptedException e) {
+ Log.i(TAG, "Interrupted during sleep", e);
+ }
+ }
+ }
+
+ return task.isDone();
+ }
+ private File getFilePath(String name) {
+ final File filesDir = mContext.getFilesDir();
+ final File outFile = new File(filesDir, name);
+ return outFile;
+ }
+
+ private void copyRawToFile(int rawResId, File outFile) {
+ Resources res = mContext.getResources();
+ InputStream is = null;
+ try {
+ is = res.openRawResource(rawResId);
+ } catch (NotFoundException e) {
+ fail("Failed to load resource with id: " + rawResId);
+ }
+ FileUtils.setPermissions(outFile.getPath(), FileUtils.S_IRWXU | FileUtils.S_IRWXG
+ | FileUtils.S_IRWXO, -1, -1);
+ assertTrue(FileUtils.copyToFile(is, outFile));
+ FileUtils.setPermissions(outFile.getPath(), FileUtils.S_IRWXU | FileUtils.S_IRWXG
+ | FileUtils.S_IRWXO, -1, -1);
+ }
+
+ private StorageManager getStorageManager() {
+ return (StorageManager) getContext().getSystemService(Context.STORAGE_SERVICE);
+ }
+
+ private void mountObb(StorageManager sm, final int resource, final File file,
+ String expectedState) {
+ copyRawToFile(resource, file);
+
+ ObbObserver observer = new ObbObserver();
+ assertTrue("mountObb call on " + file.getPath() + " should succeed",
+ sm.mountObb(file.getPath(), null, observer));
+
+ assertTrue("Mount should have completed",
+ waitForCompletion(observer));
+
+ assertEquals("Actual file and resolved file should be the same",
+ file.getPath(), observer.path);
+
+ assertEquals(expectedState, observer.state);
+ }
+
+ private String checkMountedPath(StorageManager sm, File file) {
+ final String mountPath = sm.getMountedObbPath(file.getPath());
+ assertStartsWith("Path should be in " + OBB_MOUNT_PREFIX,
+ OBB_MOUNT_PREFIX,
+ mountPath);
+ return mountPath;
+ }
+
+ private void unmountObb(StorageManager sm, final File outFile) {
+ ObbObserver observer = new ObbObserver();
+ assertTrue("unmountObb call on test1.obb should succeed",
+ sm.unmountObb(outFile.getPath(), false, observer));
+
+ assertTrue("Unmount should have completed",
+ waitForCompletion(observer));
+ }
+
+ @LargeTest
+ public void testMountAndUnmountObbNormal() {
+ StorageManager sm = getStorageManager();
+
+ final File outFile = getFilePath("test1.obb");
+
+ mountObb(sm, R.raw.test1, outFile, Environment.MEDIA_MOUNTED);
+
+ final String mountPath = checkMountedPath(sm, outFile);
+ final File mountDir = new File(mountPath);
+
+ assertTrue("OBB mounted path should be a directory",
+ mountDir.isDirectory());
+
+ unmountObb(sm, outFile);
+ }
+
+ @LargeTest
+ public void testAttemptMountNonObb() {
+ StorageManager sm = getStorageManager();
+
+ final File outFile = getFilePath("test1_nosig.obb");
+
+ mountObb(sm, R.raw.test1_nosig, outFile, Environment.MEDIA_BAD_REMOVAL);
+
+ assertFalse("OBB should not be mounted",
+ sm.isObbMounted(outFile.getPath()));
+
+ assertNull("OBB's mounted path should be null",
+ sm.getMountedObbPath(outFile.getPath()));
+ }
+
+ @LargeTest
+ public void testAttemptMountObbWrongPackage() {
+ StorageManager sm = getStorageManager();
+
+ final File outFile = getFilePath("test1_wrongpackage.obb");
+
+ mountObb(sm, R.raw.test1_wrongpackage, outFile, Environment.MEDIA_BAD_REMOVAL);
+
+ assertFalse("OBB should not be mounted",
+ sm.isObbMounted(outFile.getPath()));
+
+ assertNull("OBB's mounted path should be null",
+ sm.getMountedObbPath(outFile.getPath()));
+ }
+}
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 9793748..da8c927 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -278,6 +278,10 @@
</li>
</ul>
</li>
+ <li><a href="<?cs var:toroot?>guide/topics/admin/device-admin.html">
+ <span class="en">Device Administration</span></a>
+ <span class="new">new!</span>
+ </li>
</ul>
</li>
diff --git a/docs/html/guide/topics/admin/device-admin.jd b/docs/html/guide/topics/admin/device-admin.jd
new file mode 100644
index 0000000..4d9a14f
--- /dev/null
+++ b/docs/html/guide/topics/admin/device-admin.jd
@@ -0,0 +1,494 @@
+page.title=Android Device Administration API
+@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>In this document</h2>
+ <ol>
+<li><a href="#overview">Device Administration API Overview</a>
+ <ol>
+ <li><a href="#policies">Policies</a></li>
+ </ol>
+ </li>
+ <li><a href="#how">How Does It Work?</a></li>
+ <li><a href="#sample">Sample Application</a></li>
+ <li><a href="#developing">Developing a Device Administration Application</a>
+ <ol>
+ <li><a href="#manifest">Creating the Manifest</a></li>
+ <li><a href="#code">Implementing the Code</a>
+ </li>
+ </ol>
+ </ol>
+ </div>
+</div>
+
+<p>Android 2.2 introduces support for enterprise applications by offering the
+Android Device Administration API. The Device Administration API provides device
+administration features at the system level. These APIs allow you to create
+security-aware applications that are useful in enterprise settings, in which IT
+professionals require rich control over employee devices. For example, the
+built-in Android Email application has leveraged the new APIs to improve
+Exchange support. Through the Email application, Exchange administrators can
+enforce password policies — including alphanumeric passwords or numeric
+PINs — across devices. Administrators can also remotely wipe (that is,
+restore factory defaults on) lost or stolen handsets. Exchange users can sync
+their email and calendar data.</p>
+
+<p>This document is intended for developers who want to develop enterprise
+solutions for Android-powered devices. It discusses the various features
+provided by the Device Administration API to provide stronger security for
+employee devices that are powered by Android.</p>
+<h2 id="overview">Device Administration API Overview</h2>
+<p>Here are examples of the types of applications that might use the Device Administration API:</p>
+<ul>
+ <li>Email clients.</li>
+ <li>Security applications that do remote wipe.</li>
+ <li>Device management services and applications.</li>
+</ul>
+
+<h3 id="how">How Does it Work?</h3>
+<p>You use the Device Administration API to write device admin applications that users
+install on their devices. The device admin application enforces the desired
+policies. Here's how it works:</p> <ul>
+ <li>A system administrator writes a device admin application that enforces
+remote/local device security policies. These policies could be hard-coded into
+the app, or the application could dynamically fetch policies from a third-party
+server. </li>
+<li>The application is installed on users' devices. Android does
+not currently have an automated provisioning solution. Some of the ways a sysadmin might
+distribute the application to users are as follows:
+<ul>
+<li>Android Market.</li>
+<li>Enabling non-market installation.</li>
+<li>Distributing the application through other means, such as email or websites.</li>
+
+</ul>
+
+
+</li>
+ <li>The system prompts the user to enable the device admin application. How
+and when this happens depends on how the application is implemented.</li>
+<li>Once users enable the device admin application, they are subject to
+its policies. Complying with those policies typically confers benefits, such as
+access to sensitive systems and data.</li>
+</ul>
+<p>If users do not enable the device admin app, it remains on the device, but in an inactive state. Users will not be subject to its policies, and they will conversely not get any of the application's benefits—for example, they may not be able to sync data.</p>
+<p>If a user fails to comply with the policies (for example, if a user sets a
+password that violates the guidelines), it is up to the application to decide
+how to handle this. However, typically this will result in the user not being
+able to sync data.</p>
+<p>If a device attempts to connect to a server that requires policies not
+supported in the Device Administration API, the connection will not
+be allowed. The Device Administration API does not currently allow partial
+provisioning. In other words, if a device (for example, a legacy device) does
+not support all of the stated policies, there is no way to allow the
+device to connect.</p>
+<p>If a device contains multiple enabled admin applications, the strictest policy is
+enforced. There is no way to target a particular admin
+application.</p>
+<p>To uninstall an existing device admin application, users need to
+first unregister the application as an administrator. </p>
+
+<h3 id ="policies">Policies</h3>
+<p>In an enterprise setting, it's often the case that employee devices must
+adhere to a strict set of policies that govern the use of the device. The
+Device Administration API supports the policies listed in Table 1.
+Note that the Device Administration API currently only supports passwords for screen
+lock:</p>
+<p class="table-caption"><strong>Table 1.</strong> Policies supported by the Device Administration API.</p>
+<table border="1">
+ <tr>
+ <th>Policy</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>Password enabled</td>
+ <td>Requires that devices ask for PIN or passwords.</td>
+ </tr>
+ <tr>
+ <td>Minimum password length</td>
+ <td>Set the required number of characters for the password. For example, you
+can require PIN or passwords to have at least six characters. </td> </tr>
+ <tr>
+ <td>Alphanumeric password required</td>
+ <td>Requires that passwords have a
+combination of letters and numbers. They may include symbolic characters.
+ </td>
+ </tr>
+ <tr>
+ <td>Maximum failed password attempts </td>
+ <td>Specifies how many times a user can enter the wrong password before the
+device wipes its data. The Device Administration API also allows administrators to
+remotely reset the device to factory defaults. This secures data in case the
+device is lost or stolen.</td>
+ </tr>
+ <tr>
+ <td>Maximum inactivity time lock</td>
+ <td>Sets the length of time since the user last touched the screen or
+pressed a button before the device locks the screen. When this happens, users
+need to enter their PIN or passwords again before they can use their devices and
+access data. The value can be between 1 and 60 minutes.</td> </tr>
+</table>
+<h4>Other Features</h4>
+<p>In addition to supporting the policies listed in the above table, the Device
+Administration API lets you do the following:</p> <ul>
+ <li>Prompt user to set a new password.</li>
+ <li>Lock device immediately.</li>
+ <li>Wipe the device's data (that is, restore the device to its factory defaults).</li>
+</ul>
+
+
+<h2 id="sample">Sample Application</h2>
+<p>The examples used in this document are based on the <a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/
+android/apis/app/DeviceAdminSample.html">Device Administration API
+sample</a>, which is included in the SDK samples. For information on downloading and
+installing the SDK samples, see <a
+href="{@docRoot}resources/samples/get.html">
+Getting the Samples</a>. Here is the <a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/
+android/apis/app/DeviceAdminSample.html">complete code</a> for
+the sample. </p>
+<p>The
+sample application offers a demo of device admin features. It presents users
+with a user interface that lets them enable the device admin application. Once
+they've enabled the application, they can use the buttons in the user interface
+to do the following:</p>
+<ul>
+ <li>Set password quality.</li>
+ <li>Specify the minimum length for the user's password.</li>
+ <li>Set the password. If the password does not conform to the specified
+policies, the system returns an error.</li>
+ <li>Set how many failed password attempts can occur before the device is wiped
+(that is, restored to factory settings).</li>
+ <li>Set the maximum amount of inactive time that can elapse before the device
+locks.</li>
+ <li>Make the device lock immediately.</li>
+ <li>Wipe the device's data (that is, restore factory settings).</li>
+</ul>
+
+<img src="{@docRoot}images/admin/device-admin-app.png"/>
+<p class="img-caption"><strong>Figure 1.</strong> Screenshot of the Sample Application</p>
+
+<h2 id="developing">Developing a Device Administration Application</h2>
+
+<p>System administrators can use the Device Administration API to write an application
+that enforces remote/local device security policy enforcement. This section
+summarizes the steps involved in creating a device administration
+application.</p>
+<h3 id="manifest">Creating the Manifest</h3>
+<p>To use the Device Administration API, the application's
+manifest must include the following:</p>
+<ul>
+ <li>A subclass of {@link android.app.admin.DeviceAdminReceiver} that includes the following:
+ <ul>
+ <li>The {@link android.Manifest.permission#BIND_DEVICE_ADMIN} permission.</li>
+ <li>The ability to respond to the {@link android.app.admin.DeviceAdminReceiver#ACTION_DEVICE_ADMIN_ENABLED}
+intent, expressed in the manifest as an intent filter.</li>
+ </ul>
+ </li>
+ <li>A declaration of security policies used in metadata.</li>
+</ul>
+<p>Here is an excerpt from the Device Administration sample manifest:</p>
+<pre><activity android:name=".app.DeviceAdminSample$Controller"
+ android:label="@string/activity_sample_device_admin">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.SAMPLE_CODE" />
+ </intent-filter>
+</activity>
+
+<receiver android:name=".app.DeviceAdminSample"
+ android:label="@string/sample_device_admin"
+ android:description="@string/sample_device_admin_description"
+ android:permission="android.permission.BIND_DEVICE_ADMIN">
+ <meta-data android:name="android.app.device_admin"
+ android:resource="@xml/device_admin_sample" />
+ <intent-filter>
+ <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+ </intent-filter>
+</receiver></pre>
+
+ <p>Note that:</p>
+<ul>
+ <li>The activity in the sample application is an {@link android.app.Activity}
+subclass called <code>Controller</code>. The syntax
+<code>".app.DeviceAdminSample$Controller"</code> indicates that
+<code>Controller</code> is an inner class that is nested inside the
+<code>DeviceAdminSample</code> class. Note that an Activity does not need to be
+an inner class; it just is in this example.</li>
+
+<li>The following attributes refer to string resources that for the sample application reside in
+<code>ApiDemos/res/values/strings.xml</code>. For more information about resources, see
+<a
+href="{@docRoot}guide/topics/resources/index.html">Application Resources</a>.
+<ul>
+<li><code>android:label="@string/activity_sample_device_admin"</code> refers to the
+user-readable label for the activity.</li>
+
+<li><code>android:label="@string/sample_device_admin"</code> refers to the
+user-readable label for the permission.</li>
+
+<li><code>android:description="@string/sample_device_admin_description"</code> refers to
+the user-readable description of the permission. A descripton is typically longer and more
+informative than
+a label.</li>
+</ul>
+
+
+<li><code>android:permission="android.permission.BIND_DEVICE_ADMIN"
+</code> is a permission that a {@link android.app.admin.DeviceAdminReceiver} subclass must
+have, to ensure that only the system can interact with the receiver (no application can be granted this permission). This
+prevents other applications from abusing your device admin app.</li>
+<li><code>android.app.action.DEVICE_ADMIN_ENABLED</code> is the the primary
+action that a {@link android.app.admin.DeviceAdminReceiver} subclass must handle to be
+allowed to manage a device. This is set to the receiver when the user enables
+the device admin app. Your code typically handles this in
+{@link android.app.admin.DeviceAdminReceiver#onEnabled onEnabled()}. To be supported, the receiver must also
+require the {@link android.Manifest.permission#BIND_DEVICE_ADMIN} permission so that other applications
+cannot abuse it. </li>
+<li>When a user enables the device admin application, that gives the receiver
+permission to perform actions in response to the broadcast of particular system
+events. When suitable event arises, the application can impose a policy. For
+example, if the user attempts to set a new password that doesn't meet the policy
+requirements, the application can prompt the user to pick a different password
+that does meet the requirements.</li>
+
+ <li><code>android:resource="@xml/device_admin_sample"</code>
+declares the security policies used in metadata. The metadata provides additional
+information specific to the device administrator, as parsed by the {@link
+android.app.admin.DeviceAdminInfo} class. Here are the contents of
+<code>device_admin_sample.xml</code>:</li>
+</ul>
+<pre><device-admin xmlns:android="http://schemas.android.com/apk/res/android">
+ <uses-policies>
+ <limit-password />
+ <watch-login />
+ <reset-password />
+ <force-lock />
+ <wipe-data />
+ </uses-policies>
+</device-admin>
+</pre>
+<p> In designing your device administration application, you don't need to
+include all of the policies, just the ones that are relevant for your app.
+</p>
+For more discussion of the manifest file, see the <a
+href="{@docRoot}guide/topics/manifest/manifest-intro.html">Android Developers Guide</a>.
+<h2 id="code">Implementing the Code</h2>
+<p>The Device Administration API includes the following classes:</p>
+<dl>
+ <dt>{@link android.app.admin.DeviceAdminReceiver}</dt>
+ <dd>Base class for implementing a device administration component. This class provides
+a convenience for interpreting the raw intent actions that are sent by the
+system. Your Device Administration application must include a
+{@link android.app.admin.DeviceAdminReceiver} subclass.</dd>
+ <dt>{@link android.app.admin.DevicePolicyManager}</dt>
+<dd>A class for managing policies enforced on a device. Most clients of
+this class must have published a {@link android.app.admin.DeviceAdminReceiver} that the user
+has currently enabled. The {@link android.app.admin.DevicePolicyManager} manages policies for
+one or more {@link android.app.admin.DeviceAdminReceiver} instances</dd>
+ <dt>{@link android.app.admin.DeviceAdminInfo}</dt>
+<dd>This class is used to specify metadata
+for a device administrator component.</dd>
+</dl>
+<p>These classes provide the foundation for a fully functional device administration application.
+The rest of this section describes how you use the {@link
+android.app.admin.DeviceAdminReceiver} and
+{@link android.app.admin.DevicePolicyManager} APIs to write a device admin application.</p>
+<h4 id="receiver">Subclassing DeviceAdminReceiver</h4>
+<p>To create a device admin application, you must subclass
+{@link android.app.admin.DeviceAdminReceiver}. The {@link android.app.admin.DeviceAdminReceiver} class
+consists of a series of callbacks that are triggered when particular events
+occur.</p>
+<p>In its {@link android.app.admin.DeviceAdminReceiver} subclass, the sample application
+simply displays a {@link android.widget.Toast} notification in response to particular
+events. For example:</p>
+<pre>public class DeviceAdminSample extends DeviceAdminReceiver {
+
+...
+ @Override
+ public void onEnabled(Context context, Intent intent) {
+ showToast(context, "Sample Device Admin: enabled");
+ }
+
+ @Override
+ public CharSequence onDisableRequested(Context context, Intent intent) {
+ return "This is an optional message to warn the user about disabling.";
+ }
+
+ @Override
+ public void onDisabled(Context context, Intent intent) {
+ showToast(context, "Sample Device Admin: disabled");
+ }
+
+ @Override
+ public void onPasswordChanged(Context context, Intent intent) {
+ showToast(context, "Sample Device Admin: pw changed");
+ }
+
+ void showToast(Context context, CharSequence msg) {
+ Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
+ }
+...
+}</pre>
+<h4 id="enabling">Enabling the Application</h4>
+<p>One of the major events a device admin application has to handle is the user
+enabling the application. The user must explicitly enable the application for
+the policies to be enforced. If the user chooses not to enable the application
+it will still be present on the device, but its policies will not be enforced, and the user will not
+get any of the application's benefits.</p>
+<p>The process of enabling the application begins when the user performs an
+action that triggers the {@link android.app.admin.DevicePolicyManager#ACTION_ADD_DEVICE_ADMIN}
+intent. In the
+sample application, this happens when the user clicks the <strong>Enable
+Admin</strong> button. </p>
+<p>When the user clicks the <strong>Enable Admin</strong> button, the display
+changes to prompt the user to enable the device admin application, as shown in <strong>Figure 2</strong>.</p>
+
+<img src="{@docRoot}images/admin/device-admin-activate-prompt.png"/>
+<p class="img-caption"><strong>Figure 2.</strong> Sample Application: Activating the Application</p>
+<p>Below is the code that gets executed when the user clicks the <strong>Enable
+Admin</strong> button shown in <strong>Figure 1</strong>. </p>
+
+<pre> private OnClickListener mEnableListener = new OnClickListener() {
+ public void onClick(View v) {
+ // Launch the activity to have the user enable our admin.
+ Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
+ intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
+ mDeviceAdminSample);
+ intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
+ "Additional text explaining why this needs to be added.");
+ startActivityForResult(intent, RESULT_ENABLE);
+ }
+};
+
+...
+// This code checks whether the device admin app was successfully enabled.
+@Override
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ switch (requestCode) {
+ case RESULT_ENABLE:
+ if (resultCode == Activity.RESULT_OK) {
+ Log.i("DeviceAdminSample", "Administration enabled!");
+ } else {
+ Log.i("DeviceAdminSample", "Administration enable FAILED!");
+ }
+ return;
+ }
+ super.onActivityResult(requestCode, resultCode, data);
+}</pre>
+
+<p>The line
+<code>intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
+mDeviceAdminSample)</code> states that <code>mDeviceAdminSample</code> (which is
+a {@link android.app.admin.DeviceAdminReceiver} component) is the target policy.
+This line invokes the user interface shown in <strong>Figure 2</strong>, which guides users through
+adding the device administrator to the system (or allows them to reject it).</p>
+
+<p>When the application needs to perform an operation that is contingent on the
+device admin application being enabled, it confirms that the application is
+active. To do this it uses the {@link android.app.admin.DevicePolicyManager} method
+{@link android.app.admin.DevicePolicyManager#isAdminActive(android.content.ComponentName) isAdminActive()}. Notice that the {@link android.app.admin.DevicePolicyManager}
+method {@link android.app.admin.DevicePolicyManager#isAdminActive(android.content.ComponentName) isAdminActive()} takes a {@link android.app.admin.DeviceAdminReceiver}
+component as its argument:</p>
+<pre>
+DevicePolicyManager mDPM;
+...
+boolean active = mDPM.isAdminActive(mDeviceAdminSample);
+if (active) {
+ // Admin app is active, so do some admin stuff
+ ...
+} else {
+ // do something else
+}
+</pre>
+<h3 id="admin_ops">Managing Policies</h3>
+<p>{@link android.app.admin.DevicePolicyManager} is a public class for managing policies
+enforced on a device. {@link android.app.admin.DevicePolicyManager} manages policies for one
+or more {@link android.app.admin.DeviceAdminReceiver} instances. </p>
+<p>You get a handle to the {@link android.app.admin.DevicePolicyManager} as follows: </p>
+<pre>DevicePolicyManager mDPM =
+(DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);<br
+/></pre>
+<p>This section describes how to use {@link android.app.admin.DevicePolicyManager} to perform
+ administrative tasks:</p>
+<ul>
+ <li><a href="#pwd">Set password policies</a></li>
+ <li><a href="#lock">Set device lock</a></li>
+ <li><a href="#wipe">Perform data wipe</a></li>
+</ul>
+<h4 id="pwd">Set password policies</h4>
+<p>{@link android.app.admin.DevicePolicyManager} includes APIs for setting and enforcing the
+device password policy. In the Device Administration API, the password only applies to
+screen lock. This section describes common password-related tasks.</p>
+<h5>Set a password for the device</h5>
+<p>This code displays a user interface prompting the user to set a password:</p>
+<pre>Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
+startActivity(intent);
+</pre>
+<h5>Set the password quality</h5>
+<p>The password quality can be one of the following {@link android.app.admin.DevicePolicyManager} constants: </p>
+<dl>
+ <dt>{@link android.app.admin.DevicePolicyManager#PASSWORD_QUALITY_ALPHABETIC}</dt><dd>The user must enter a
+password containing at least alphabetic (or other symbol) characters.</dd>
+ <dt>{@link android.app.admin.DevicePolicyManager#PASSWORD_QUALITY_ALPHANUMERIC}</dt><dd>The user must enter a
+password containing at least <em>both</em> numeric <em>and</em> alphabetic (or
+other symbol) characters.</dd>
+ <dt>{@link android.app.admin.DevicePolicyManager#PASSWORD_QUALITY_NUMERIC}</dt><dd>The user must enter a password
+containing at least numeric characters.</dd>
+ <dt>{@link android.app.admin.DevicePolicyManager#PASSWORD_QUALITY_SOMETHING}</dt><dd>The policy requires some kind
+of password, but doesn't care what it is.</dd>
+ <dt>{@link android.app.admin.DevicePolicyManager#PASSWORD_QUALITY_UNSPECIFIED}</dt><dd>
+ The policy has no requirements for the password. </dd>
+</dl>
+<p>For example, this is how you would set the password policy to require an alphanumeric password:</p>
+<pre>
+DevicePolicyManager mDPM;
+ComponentName mDeviceAdminSample;
+...
+mDPM.setPasswordQuality(mDeviceAdminSample, DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC);
+</pre>
+<h5>Set the minimum password length</h5>
+<p>You can specify that a password must be at least the specified minimum
+length. For example:</p>
+<pre>DevicePolicyManager mDPM;
+ComponentName mDeviceAdminSample;
+int pwLength;
+...
+mDPM.setPasswordMinimumLength(mDeviceAdminSample, pwLength);
+</pre>
+<h5>Set maximum failed password attempts</h5>
+<p>You can set the maximum number of allowed failed password attempts before the
+device is wiped (that is, reset to factory settings). For example:</p>
+<pre>DevicePolicyManager mDPM;
+ComponentName mDeviceAdminSample;
+int maxFailedPw;
+ ...
+mDPM.setMaximumFailedPasswordsForWipe(mDeviceAdminSample, maxFailedPw);</pre>
+<h4 id="lock">Set device lock</h4>
+<p>You can set the maximum period of user inactivity that can occur before the
+device locks. For example:</p>
+<pre>
+DevicePolicyManager mDPM;
+ComponentName mDeviceAdminSample;
+...
+long timeMs = 1000L*Long.parseLong(mTimeout.getText().toString());
+mDPM.setMaximumTimeToLock(mDeviceAdminSample, timeMs);
+</pre>
+<p>You can also programmatically tell the device to lock immediately:</p>
+<pre>
+DevicePolicyManager mDPM;
+mDPM.lockNow();</pre>
+<h4 id="wipe">Perform data wipe</h4>
+<p>You can use the {@link android.app.admin.DevicePolicyManager} method
+{@link android.app.admin.DevicePolicyManager#wipeData wipeData()} to reset the device to factory settings. This is useful
+if the device is lost or stolen. Often the decision to wipe the device is the
+result of certain conditions being met. For example, you can use
+{@link android.app.admin.DevicePolicyManager#setMaximumFailedPasswordsForWipe setMaximumFailedPasswordsForWipe()} to state that a device should be
+wiped after a specific number of failed password attempts.</p>
+<p>You wipe data as follows:</p>
+<pre>
+DevicePolicyManager mDPM;
+mDPM.wipeData(0);</pre>
+<p>The {@link android.app.admin.DevicePolicyManager#wipeData wipeData()} method takes as its parameter a bit mask of
+additional options. Currently the value must be 0. </p>
diff --git a/docs/html/images/admin/device-admin-activate-prompt.png b/docs/html/images/admin/device-admin-activate-prompt.png
new file mode 100755
index 0000000..fd001bd
--- /dev/null
+++ b/docs/html/images/admin/device-admin-activate-prompt.png
Binary files differ
diff --git a/docs/html/images/admin/device-admin-app.png b/docs/html/images/admin/device-admin-app.png
new file mode 100755
index 0000000..d966a28
--- /dev/null
+++ b/docs/html/images/admin/device-admin-app.png
Binary files differ
diff --git a/libs/rs/rsScript.cpp b/libs/rs/rsScript.cpp
index 43bb09e..0e76dae 100644
--- a/libs/rs/rsScript.cpp
+++ b/libs/rs/rsScript.cpp
@@ -24,10 +24,37 @@
mAllocFile = __FILE__;
mAllocLine = __LINE__;
memset(&mEnviroment, 0, sizeof(mEnviroment));
+
+ mSlots = NULL;
+ mTypes = NULL;
}
Script::~Script()
{
+ if(mSlots) {
+ delete [] mSlots;
+ mSlots = NULL;
+ }
+ if(mTypes) {
+ delete [] mTypes;
+ mTypes = NULL;
+ }
+}
+
+void Script::initSlots() {
+ if(mEnviroment.mFieldCount > 0) {
+ mSlots = new ObjectBaseRef<Allocation>[mEnviroment.mFieldCount];
+ mTypes = new ObjectBaseRef<const Type>[mEnviroment.mFieldCount];
+ }
+}
+
+void Script::setSlot(uint32_t slot, Allocation *a) {
+ if(slot >= mEnviroment.mFieldCount) {
+ LOGE("Script::setSlot unable to set allocation, invalid slot index");
+ return;
+ }
+
+ mSlots[slot].set(a);
}
void Script::setVar(uint32_t slot, const void *val, uint32_t len)
@@ -51,7 +78,7 @@
{
Script *s = static_cast<Script *>(vs);
Allocation *a = static_cast<Allocation *>(va);
- s->mSlots[slot].set(a);
+ s->setSlot(slot, a);
//LOGE("rsi_ScriptBindAllocation %i %p %p", slot, a, a->getPtr());
}
@@ -61,15 +88,6 @@
s->mEnviroment.mTimeZone = timeZone;
}
-void rsi_ScriptSetType(Context * rsc, RsType vt, uint32_t slot, bool writable, const char *name)
-{
- ScriptCState *ss = &rsc->mScriptC;
- const Type *t = static_cast<const Type *>(vt);
- ss->mConstantBufferTypes[slot].set(t);
- ss->mSlotWritable[slot] = writable;
- LOGE("rsi_ScriptSetType");
-}
-
void rsi_ScriptInvoke(Context *rsc, RsScript vs, uint32_t slot)
{
Script *s = static_cast<Script *>(vs);
diff --git a/libs/rs/rsScript.h b/libs/rs/rsScript.h
index 0a20344..c73bb5e 100644
--- a/libs/rs/rsScript.h
+++ b/libs/rs/rsScript.h
@@ -29,8 +29,6 @@
class ProgramRaster;
class ProgramStore;
-#define MAX_SCRIPT_BANKS 32
-
class Script : public ObjectBase
{
public:
@@ -61,10 +59,8 @@
};
Enviroment_t mEnviroment;
- ObjectBaseRef<Allocation> mSlots[MAX_SCRIPT_BANKS];
- ObjectBaseRef<const Type> mTypes[MAX_SCRIPT_BANKS];
- bool mSlotWritable[MAX_SCRIPT_BANKS];
-
+ void initSlots();
+ void setSlot(uint32_t slot, Allocation *a);
void setVar(uint32_t slot, const void *val, uint32_t len);
virtual void runForEach(Context *rsc,
@@ -76,6 +72,10 @@
virtual void Invoke(Context *rsc, uint32_t slot, const void *data, uint32_t len) = 0;
virtual void setupScript(Context *rsc) = 0;
virtual uint32_t run(Context *) = 0;
+protected:
+ ObjectBaseRef<Allocation> *mSlots;
+ ObjectBaseRef<const Type> *mTypes;
+
};
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index c6418be..d961fed 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -365,11 +365,6 @@
void ScriptCState::clear(Context *rsc)
{
rsAssert(rsc);
- for (uint32_t ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
- mConstantBufferTypes[ct].clear();
- mSlotWritable[ct] = false;
- }
-
mScript.clear();
mScript.set(new ScriptC(rsc));
}
@@ -428,6 +423,7 @@
else {
s->mEnviroment.mFieldAddress = (void **) calloc(s->mEnviroment.mFieldCount, sizeof(void *));
bccGetExportVars(s->mBccScript, NULL, s->mEnviroment.mFieldCount, (BCCvoid **) s->mEnviroment.mFieldAddress);
+ s->initSlots();
}
s->mEnviroment.mFragment.set(rsc->getDefaultProgramFragment());
@@ -532,10 +528,6 @@
ss->runCompiler(rsc, s.get());
s->incUserRef();
s->setContext(rsc);
- for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
- s->mTypes[ct].set(ss->mConstantBufferTypes[ct].get());
- s->mSlotWritable[ct] = ss->mSlotWritable[ct];
- }
ss->clear(rsc);
return s.get();
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
index 7ec80aa..e5b5ba9 100644
--- a/libs/rs/rsScriptC.h
+++ b/libs/rs/rsScriptC.h
@@ -81,11 +81,6 @@
ObjectBaseRef<ScriptC> mScript;
- ObjectBaseRef<const Type> mConstantBufferTypes[MAX_SCRIPT_BANKS];
- //String8 mSlotNames[MAX_SCRIPT_BANKS];
- bool mSlotWritable[MAX_SCRIPT_BANKS];
- //String8 mInvokableNames[MAX_SCRIPT_BANKS];
-
void init(Context *rsc);
void clear(Context *rsc);
diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp
index 8cdb48a..33776c3 100644
--- a/libs/rs/rsType.cpp
+++ b/libs/rs/rsType.cpp
@@ -31,6 +31,8 @@
mAllocLine = __LINE__;
mLODs = 0;
mLODCount = 0;
+ mAttribs = NULL;
+ mAttribsSize = 0;
clear();
}
@@ -44,6 +46,11 @@
}
if (mLODs) {
delete [] mLODs;
+ mLODs = NULL;
+ }
+ if(mAttribs) {
+ delete [] mAttribs;
+ mAttribs = NULL;
}
}
@@ -145,6 +152,21 @@
void Type::makeGLComponents()
{
+ // Count the number of gl attrs to initialize
+ mAttribsSize = 0;
+ for (uint32_t ct=0; ct < getElement()->getFieldCount(); ct++) {
+ if(getElement()->getFieldName(ct)[0] != '#') {
+ mAttribsSize ++;
+ }
+ }
+ if(mAttribs) {
+ delete [] mAttribs;
+ mAttribs = NULL;
+ }
+ if(mAttribsSize) {
+ mAttribs = new VertexArray::Attrib[mAttribsSize];
+ }
+
uint32_t userNum = 0;
for (uint32_t ct=0; ct < getElement()->getFieldCount(); ct++) {
const Component &c = getElement()->getField(ct)->getComponent();
@@ -160,11 +182,8 @@
String8 tmp(RS_SHADER_ATTR);
tmp.append(getElement()->getFieldName(ct));
mAttribs[userNum].name.setTo(tmp.string());
- userNum ++;
- if(userNum == RS_MAX_ATTRIBS) {
- return;
- }
+ userNum ++;
}
}
@@ -172,7 +191,13 @@
void Type::enableGLVertexBuffer(VertexArray *va) const
{
uint32_t stride = mElement->getSizeBytes();
- for (uint32_t ct=0; ct < RS_MAX_ATTRIBS; ct++) {
+ for (uint32_t ct=0; ct < mAttribsSize; ct++) {
+ // Load up to RS_MAX_ATTRIBS inputs
+ // TODO: grow vertexarray dynamically
+ if(ct >= RS_MAX_ATTRIBS) {
+ LOGE("More GL attributes than we can handle");
+ break;
+ }
if (mAttribs[ct].size) {
va->add(mAttribs[ct], stride);
}
diff --git a/libs/rs/rsType.h b/libs/rs/rsType.h
index b5548c0..9099bf1 100644
--- a/libs/rs/rsType.h
+++ b/libs/rs/rsType.h
@@ -119,7 +119,8 @@
LOD *mLODs;
uint32_t mLODCount;
- VertexArray::Attrib mAttribs[RS_MAX_ATTRIBS];
+ VertexArray::Attrib *mAttribs;
+ uint32_t mAttribsSize;
void makeGLComponents();
private:
diff --git a/libs/rs/scriptc/rs_core.rsh b/libs/rs/scriptc/rs_core.rsh
index 99fc166..9950184 100644
--- a/libs/rs/scriptc/rs_core.rsh
+++ b/libs/rs/scriptc/rs_core.rsh
@@ -1,6 +1,30 @@
#ifndef __RS_CORE_RSH__
#define __RS_CORE_RSH__
+// Debugging, print to the LOG a description string and a value.
+extern void __attribute__((overloadable))
+ rsDebug(const char *, float);
+extern void __attribute__((overloadable))
+ rsDebug(const char *, float, float);
+extern void __attribute__((overloadable))
+ rsDebug(const char *, float, float, float);
+extern void __attribute__((overloadable))
+ rsDebug(const char *, float, float, float, float);
+extern void __attribute__((overloadable))
+ rsDebug(const char *, const rs_matrix4x4 *);
+extern void __attribute__((overloadable))
+ rsDebug(const char *, const rs_matrix3x3 *);
+extern void __attribute__((overloadable))
+ rsDebug(const char *, const rs_matrix2x2 *);
+extern void __attribute__((overloadable))
+ rsDebug(const char *, int);
+extern void __attribute__((overloadable))
+ rsDebug(const char *, uint);
+extern void __attribute__((overloadable))
+ rsDebug(const char *, const void *);
+#define RS_DEBUG(a) rsDebug(#a, a)
+#define RS_DEBUG_MARKER rsDebug(__FILE__, __LINE__)
+
static void __attribute__((overloadable)) rsDebug(const char *s, float2 v) {
rsDebug(s, v.x, v.y);
}
diff --git a/libs/rs/scriptc/rs_math.rsh b/libs/rs/scriptc/rs_math.rsh
index 5720b05..d059997 100644
--- a/libs/rs/scriptc/rs_math.rsh
+++ b/libs/rs/scriptc/rs_math.rsh
@@ -1,34 +1,6 @@
#ifndef __RS_MATH_RSH__
#define __RS_MATH_RSH__
-// Debugging, print to the LOG a description string and a value.
-extern void __attribute__((overloadable))
- rsDebug(const char *, float);
-extern void __attribute__((overloadable))
- rsDebug(const char *, float, float);
-extern void __attribute__((overloadable))
- rsDebug(const char *, float, float, float);
-extern void __attribute__((overloadable))
- rsDebug(const char *, float, float, float, float);
-extern void __attribute__((overloadable))
- rsDebug(const char *, const rs_matrix4x4 *);
-extern void __attribute__((overloadable))
- rsDebug(const char *, const rs_matrix3x3 *);
-extern void __attribute__((overloadable))
- rsDebug(const char *, const rs_matrix2x2 *);
-extern void __attribute__((overloadable))
- rsDebug(const char *, int);
-extern void __attribute__((overloadable))
- rsDebug(const char *, uint);
-extern void __attribute__((overloadable))
- rsDebug(const char *, const void *);
-#define RS_DEBUG(a) rsDebug(#a, a)
-#define RS_DEBUG_MARKER rsDebug(__FILE__, __LINE__)
-
-
-#include "rs_cl.rsh"
-#include "rs_core.rsh"
-
extern void __attribute__((overloadable))
rsSetObject(rs_element *dst, rs_element src);
extern void __attribute__((overloadable))
diff --git a/libs/rs/scriptc/rs_types.rsh b/libs/rs/scriptc/rs_types.rsh
index dd42972..212eb83 100644
--- a/libs/rs/scriptc/rs_types.rsh
+++ b/libs/rs/scriptc/rs_types.rsh
@@ -1,3 +1,5 @@
+#ifndef __RS_TYPES_RSH__
+#define __RS_TYPES_RSH__
typedef char int8_t;
typedef short int16_t;
@@ -72,3 +74,4 @@
#define RS_PACKED __attribute__((packed, aligned(4)))
+#endif
diff --git a/media/java/android/media/MtpCursor.java b/media/java/android/media/MtpCursor.java
index ff8799a..9b5ab95 100644
--- a/media/java/android/media/MtpCursor.java
+++ b/media/java/android/media/MtpCursor.java
@@ -50,6 +50,9 @@
public MtpCursor(MtpClient client, int queryType, int deviceID, long storageID, long objectID,
String[] projection) {
+ if (client == null) {
+ throw new NullPointerException("client null in MtpCursor constructor");
+ }
mColumns = projection;
HashMap<String, Integer> map;
diff --git a/media/java/android/media/videoeditor/VideoEditorFactory.java b/media/java/android/media/videoeditor/VideoEditorFactory.java
index 0a377e2..41eed16 100755
--- a/media/java/android/media/videoeditor/VideoEditorFactory.java
+++ b/media/java/android/media/videoeditor/VideoEditorFactory.java
@@ -63,6 +63,12 @@
if (!dir.exists()) {
if (!dir.mkdirs()) {
throw new FileNotFoundException("Cannot create project path: " + projectPath);
+ } else {
+ // Create the file which hides the media files
+ // from the media scanner
+ if (!new File(dir, ".nomedia").createNewFile()) {
+ throw new FileNotFoundException("Cannot create file .nomedia");
+ }
}
}
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_default.png
new file mode 100644
index 0000000..bf33c946
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_default.png
Binary files differ
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml
index 6aee011..494dfa8 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml
@@ -28,11 +28,11 @@
>
<ImageView
- class="com.android.systemui.statusbar.tablet.NotificationIconArea$MoreView"
android:id="@+id/expand"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_sysbar_open"
+ android:background="@drawable/ic_sysbar_icon_bg"
android:paddingLeft="6dip"
android:onClick="notificationIconsClicked"
/>
@@ -100,8 +100,18 @@
android:background="@drawable/sysbar_hidenotification_handle"
android:layout_marginLeft="8dip"
/>
+ <com.android.systemui.statusbar.tablet.InputMethodButton
+ android:id="@+id/imeButton"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_marginLeft="8dip"
+ android:src="@drawable/ic_sysbar_ime_default"
+ android:background="@drawable/ic_sysbar_icon_bg"
+ android:visibility="visible"
+ />
</com.android.systemui.statusbar.tablet.NotificationIconArea>
+
<FrameLayout
android:id="@+id/ticker"
android:layout_width="wrap_content"
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsActivity.java b/packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsActivity.java
index 16a3c17..faea3fc 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsActivity.java
@@ -51,7 +51,6 @@
import android.graphics.drawable.Drawable;
import android.graphics.PixelFormat;
import android.os.Bundle;
-import android.os.Handler;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
@@ -176,7 +175,6 @@
}
private class LocalCarouselViewHelper extends CarouselViewHelper {
- private Paint mPaint = new Paint();
private DetailTextureParameters mDetailParams = new DetailTextureParameters(10.0f, 20.0f);
public LocalCarouselViewHelper(Context context) {
@@ -315,7 +313,9 @@
} else {
info.matrix = null;
}
- mCarouselView.setTextureForItem(info.position, compositeBitmap(info));
+ // Force Carousel to request new textures for this item.
+ mCarouselView.setTextureForItem(info.position, null);
+ mCarouselView.setDetailTextureForItem(info.position, 0, 0, 0, 0, null);
} else {
if (DBG) Log.v(TAG, "Can't find view for id " + id);
}
@@ -351,10 +351,12 @@
final View decorView = getWindow().getDecorView();
getWindow().getDecorView().setBackgroundColor(0x80000000);
- setContentView(R.layout.recent_apps_activity);
-
if (mCarouselView == null) {
+ long t = System.currentTimeMillis();
+ setContentView(R.layout.recent_apps_activity);
+ long elapsed = System.currentTimeMillis() - t;
+ Log.v(TAG, "Recents layout took " + elapsed + "ms to load");
mLoadingBitmap = BitmapFactory.decodeResource(res, R.drawable.recent_rez_border);
mCarouselView = (CarouselView)findViewById(R.id.carousel);
mHelper = new LocalCarouselViewHelper(this);
@@ -423,7 +425,6 @@
if (DBG) Log.v(TAG, "*** RUNNING THUMBNAIL WAS NULL ***");
}
}
- mCarouselView.createCards(mActivityDescriptions.size());
}
private void updateRecentTasks() {
@@ -491,6 +492,14 @@
private void showCarousel(boolean show) {
if (show) {
+ mCarouselView.createCards(mActivityDescriptions.size());
+ for (int i = 1; i < mActivityDescriptions.size(); i++) {
+ // Force Carousel to update textures. Note we don't do this for the first item,
+ // since it will be updated when mThumbnailReceiver returns a thumbnail.
+ // TODO: only do this for apps that have changed.
+ mCarouselView.setTextureForItem(i, null);
+ mCarouselView.setDetailTextureForItem(i, 0, 0, 0, 0, null);
+ }
// Make carousel visible
mNoRecentsView.setVisibility(View.GONE);
mCarouselView.setVisibility(View.VISIBLE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
new file mode 100644
index 0000000..ba682b7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.tablet;
+
+import android.content.Context;
+import android.util.Slog;
+import android.view.View;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+import android.view.inputmethod.InputMethodManager;
+
+import com.android.server.InputMethodManagerService;
+
+public class InputMethodButton extends ImageView {
+
+ // other services we wish to talk to
+ InputMethodManager mImm;
+
+ public InputMethodButton(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ // IME hookup
+ mImm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+
+ // TODO: read the current icon & visibility state directly from the service
+
+ // TODO: register for notifications about changes to visibility & subtype from service
+
+ setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mImm.showInputMethodSubtypePicker();
+ }
+ });
+ }
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java
index 29df28e..d024dd0 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java
@@ -46,6 +46,7 @@
import android.widget.TextView;
import android.view.View;
import android.view.Window;
+import android.view.WindowManager;
import android.util.Log;
import java.util.List;
@@ -102,6 +103,11 @@
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setProgressBarIndeterminateVisibility(true);
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
+ if (Environment.isExternalStorageRemovable()) {
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
+ }
+
setTitle(getString(com.android.internal.R.string.usb_storage_activity_title));
setContentView(com.android.internal.R.layout.usb_storage_activity);
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index 3583ab9..1383354 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -214,6 +214,9 @@
}
class WaveViewMethods implements WaveView.OnTriggerListener {
+ private static final int WAIT_FOR_ANIMATION_TIMEOUT = 500;
+ private static final int STAY_ON_WHILE_GRABBED_TIMEOUT = 30000;
+
/** {@inheritDoc} */
public void onTrigger(View v, int whichHandle) {
if (whichHandle == WaveView.OnTriggerListener.CENTER_HANDLE) {
@@ -222,13 +225,17 @@
public void run() {
mCallback.goToUnlockScreen();
}
- }, 500);
+ }, WAIT_FOR_ANIMATION_TIMEOUT);
}
}
/** {@inheritDoc} */
public void onGrabbedStateChange(View v, int grabbedState) {
- mCallback.pokeWakelock();
+ if (grabbedState == WaveView.OnTriggerListener.CENTER_HANDLE) {
+ mCallback.pokeWakelock(STAY_ON_WHILE_GRABBED_TIMEOUT);
+ } else {
+ mCallback.pokeWakelock();
+ }
}
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 33685ba..68e0e32 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -47,6 +47,7 @@
import android.provider.Settings;
import com.android.internal.R;
+import com.android.internal.app.ShutdownThread;
import com.android.internal.policy.PolicyManager;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.telephony.ITelephony;
@@ -128,6 +129,10 @@
static final boolean DEBUG_LAYOUT = false;
static final boolean SHOW_STARTING_ANIMATIONS = true;
static final boolean SHOW_PROCESSES_ON_ALT_MENU = false;
+
+ static final int LONG_PRESS_POWER_NOTHING = 0;
+ static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
+ static final int LONG_PRESS_POWER_SHUT_OFF = 2;
// wallpaper is at the bottom, though the window manager may move it.
static final int WALLPAPER_LAYER = 2;
@@ -224,6 +229,7 @@
boolean mDeskDockEnablesAccelerometer;
int mLidKeyboardAccessibility;
int mLidNavigationAccessibility;
+ int mLongPressOnPowerBehavior = -1;
boolean mScreenOn = false;
boolean mOrientationSensorEnabled = false;
int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -467,10 +473,27 @@
Runnable mPowerLongPress = new Runnable() {
public void run() {
- mShouldTurnOffOnKeyUp = false;
- performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
- sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
- showGlobalActionsDialog();
+ // The context isn't read
+ if (mLongPressOnPowerBehavior < 0) {
+ mLongPressOnPowerBehavior = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_longPressOnPowerBehavior);
+ }
+ switch (mLongPressOnPowerBehavior) {
+ case LONG_PRESS_POWER_NOTHING:
+ break;
+ case LONG_PRESS_POWER_GLOBAL_ACTIONS:
+ mShouldTurnOffOnKeyUp = false;
+ performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
+ sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
+ showGlobalActionsDialog();
+ break;
+ case LONG_PRESS_POWER_SHUT_OFF:
+ mShouldTurnOffOnKeyUp = false;
+ performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
+ sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
+ ShutdownThread.shutdown(mContext, true);
+ break;
+ }
}
};
diff --git a/policy/src/com/android/internal/policy/impl/PowerDialog.java b/policy/src/com/android/internal/policy/impl/PowerDialog.java
deleted file mode 100644
index de35bd7..0000000
--- a/policy/src/com/android/internal/policy/impl/PowerDialog.java
+++ /dev/null
@@ -1,182 +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.internal.policy.impl;
-
-import com.android.internal.R;
-
-import android.app.Dialog;
-import android.app.StatusBarManager;
-import android.content.Context;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.LocalPowerManager;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-
-import com.android.internal.app.ShutdownThread;
-import com.android.internal.telephony.ITelephony;
-import android.view.KeyEvent;
-import android.util.Log;
-import android.view.View;
-import android.view.WindowManager;
-import android.view.View.OnClickListener;
-import android.view.View.OnKeyListener;
-import android.widget.Button;
-
-/**
- * @deprecated use {@link GlobalActions} instead.
- */
-public class PowerDialog extends Dialog implements OnClickListener,
- OnKeyListener {
- private static final String TAG = "PowerDialog";
-
- static private StatusBarManager sStatusBar;
- private Button mKeyguard;
- private Button mPower;
- private Button mRadioPower;
- private Button mSilent;
-
- private LocalPowerManager mPowerManager;
-
- public PowerDialog(Context context, LocalPowerManager powerManager) {
- super(context);
- mPowerManager = powerManager;
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- Context context = getContext();
-
- if (sStatusBar == null) {
- sStatusBar = (StatusBarManager)context.getSystemService(Context.STATUS_BAR_SERVICE);
- }
-
- setContentView(com.android.internal.R.layout.power_dialog);
-
- getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
- if (!getContext().getResources().getBoolean(
- com.android.internal.R.bool.config_sf_slowBlur)) {
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,
- WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
- }
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
- WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
-
- setTitle(context.getText(R.string.power_dialog));
-
- mKeyguard = (Button) findViewById(R.id.keyguard);
- mPower = (Button) findViewById(R.id.off);
- mRadioPower = (Button) findViewById(R.id.radio_power);
- mSilent = (Button) findViewById(R.id.silent);
-
- if (mKeyguard != null) {
- mKeyguard.setOnKeyListener(this);
- mKeyguard.setOnClickListener(this);
- }
- if (mPower != null) {
- mPower.setOnClickListener(this);
- }
- if (mRadioPower != null) {
- mRadioPower.setOnClickListener(this);
- }
- if (mSilent != null) {
- mSilent.setOnClickListener(this);
- // XXX: HACK for now hide the silent until we get mute support
- mSilent.setVisibility(View.GONE);
- }
-
- CharSequence text;
-
- // set the keyguard button's text
- text = context.getText(R.string.screen_lock);
- mKeyguard.setText(text);
- mKeyguard.requestFocus();
-
- try {
- ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
- if (phone != null) {
- text = phone.isRadioOn() ? context
- .getText(R.string.turn_off_radio) : context
- .getText(R.string.turn_on_radio);
- }
- } catch (RemoteException ex) {
- // ignore it
- }
-
- mRadioPower.setText(text);
- }
-
- public void onClick(View v) {
- this.dismiss();
- if (v == mPower) {
- // shutdown by making sure radio and power are handled accordingly.
- ShutdownThread.shutdown(getContext(), true);
- } else if (v == mRadioPower) {
- try {
- ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
- if (phone != null) {
- phone.toggleRadioOnOff();
- }
- } catch (RemoteException ex) {
- // ignore it
- }
- } else if (v == mSilent) {
- // do something
- } else if (v == mKeyguard) {
- if (v.isInTouchMode()) {
- // only in touch mode for the reasons explained in onKey.
- this.dismiss();
- mPowerManager.goToSleep(SystemClock.uptimeMillis() + 1);
- }
- }
- }
-
- public boolean onKey(View v, int keyCode, KeyEvent event) {
- // The activate keyguard button needs to put the device to sleep on the
- // key up event. If we try to put it to sleep on the click or down
- // action
- // the the up action will cause the device to wake back up.
-
- // Log.i(TAG, "keyCode: " + keyCode + " action: " + event.getAction());
- if (keyCode != KeyEvent.KEYCODE_DPAD_CENTER
- || event.getAction() != KeyEvent.ACTION_UP) {
- // Log.i(TAG, "getting out of dodge...");
- return false;
- }
-
- // Log.i(TAG, "Clicked mKeyguard! dimissing dialog");
- this.dismiss();
- // Log.i(TAG, "onKey: turning off the screen...");
- // XXX: This is a hack for now
- mPowerManager.goToSleep(event.getEventTime() + 1);
- return true;
- }
-
- public void show() {
- super.show();
- Log.d(TAG, "show... disabling expand");
- sStatusBar.disable(StatusBarManager.DISABLE_EXPAND);
- }
-
- public void dismiss() {
- super.dismiss();
- Log.d(TAG, "dismiss... reenabling expand");
- sStatusBar.disable(StatusBarManager.DISABLE_NONE);
- }
-}
diff --git a/services/java/com/android/server/AlarmManagerService.java b/services/java/com/android/server/AlarmManagerService.java
index e088417..4e2f1e3 100644
--- a/services/java/com/android/server/AlarmManagerService.java
+++ b/services/java/com/android/server/AlarmManagerService.java
@@ -38,9 +38,11 @@
import android.text.format.Time;
import android.util.EventLog;
import android.util.Slog;
+import android.util.TimeUtils;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
@@ -456,25 +458,28 @@
synchronized (mLock) {
pw.println("Current Alarm Manager state:");
if (mRtcWakeupAlarms.size() > 0 || mRtcAlarms.size() > 0) {
+ final long now = System.currentTimeMillis();
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
pw.println(" ");
pw.print(" Realtime wakeup (now=");
- pw.print(System.currentTimeMillis()); pw.println("):");
+ pw.print(sdf.format(new Date(now))); pw.println("):");
if (mRtcWakeupAlarms.size() > 0) {
- dumpAlarmList(pw, mRtcWakeupAlarms, " ", "RTC_WAKEUP");
+ dumpAlarmList(pw, mRtcWakeupAlarms, " ", "RTC_WAKEUP", now);
}
if (mRtcAlarms.size() > 0) {
- dumpAlarmList(pw, mRtcAlarms, " ", "RTC");
+ dumpAlarmList(pw, mRtcAlarms, " ", "RTC", now);
}
}
if (mElapsedRealtimeWakeupAlarms.size() > 0 || mElapsedRealtimeAlarms.size() > 0) {
+ final long now = SystemClock.elapsedRealtime();
pw.println(" ");
pw.print(" Elapsed realtime wakeup (now=");
- pw.print(SystemClock.elapsedRealtime()); pw.println("):");
+ TimeUtils.formatDuration(now, pw); pw.println("):");
if (mElapsedRealtimeWakeupAlarms.size() > 0) {
- dumpAlarmList(pw, mElapsedRealtimeWakeupAlarms, " ", "ELAPSED_WAKEUP");
+ dumpAlarmList(pw, mElapsedRealtimeWakeupAlarms, " ", "ELAPSED_WAKEUP", now);
}
if (mElapsedRealtimeAlarms.size() > 0) {
- dumpAlarmList(pw, mElapsedRealtimeAlarms, " ", "ELAPSED");
+ dumpAlarmList(pw, mElapsedRealtimeAlarms, " ", "ELAPSED", now);
}
}
@@ -499,12 +504,13 @@
}
}
- private static final void dumpAlarmList(PrintWriter pw, ArrayList<Alarm> list, String prefix, String label) {
+ private static final void dumpAlarmList(PrintWriter pw, ArrayList<Alarm> list,
+ String prefix, String label, long now) {
for (int i=list.size()-1; i>=0; i--) {
Alarm a = list.get(i);
pw.print(prefix); pw.print(label); pw.print(" #"); pw.print(i);
pw.print(": "); pw.println(a);
- a.dump(pw, prefix + " ");
+ a.dump(pw, prefix + " ", now);
}
}
@@ -619,10 +625,9 @@
return sb.toString();
}
- public void dump(PrintWriter pw, String prefix)
- {
+ public void dump(PrintWriter pw, String prefix, long now) {
pw.print(prefix); pw.print("type="); pw.print(type);
- pw.print(" when="); pw.print(when);
+ pw.print(" when="); TimeUtils.formatDuration(when, now, pw);
pw.print(" repeatInterval="); pw.print(repeatInterval);
pw.print(" count="); pw.println(count);
pw.print(prefix); pw.print("operation="); pw.println(operation);
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index dc4194c..70bde01 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -84,6 +84,7 @@
import java.text.Collator;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
@@ -1567,14 +1568,15 @@
int lastInputMethodSubtypeId = getSelectedInputMethodSubtypeId(lastInputMethodId);
if (DEBUG) Slog.v(TAG, "Current IME: " + lastInputMethodId);
- final List<InputMethodInfo> immis = getEnabledInputMethodList();
- ArrayList<Integer> subtypeIds = new ArrayList<Integer>();
-
- if (immis == null) {
- return;
- }
-
synchronized (mMethodMap) {
+ final List<Pair<InputMethodInfo, ArrayList<String>>> immis =
+ mSettings.getEnabledInputMethodAndSubtypeListLocked();
+ ArrayList<Integer> subtypeIds = new ArrayList<Integer>();
+
+ if (immis == null || immis.size() == 0) {
+ return;
+ }
+
hideInputMethodMenuLocked();
int N = immis.size();
@@ -1583,32 +1585,38 @@
new TreeMap<CharSequence, Pair<InputMethodInfo, Integer>>(Collator.getInstance());
for (int i = 0; i < N; ++i) {
- InputMethodInfo property = immis.get(i);
+ InputMethodInfo property = immis.get(i).first;
+ final ArrayList<String> enabledSubtypeIds = immis.get(i).second;
+ HashSet<String> enabledSubtypeSet = new HashSet<String>();
+ for (String s : enabledSubtypeIds) {
+ enabledSubtypeSet.add(s);
+ }
if (property == null) {
continue;
}
- // TODO: Show only enabled subtypes
ArrayList<InputMethodSubtype> subtypes = property.getSubtypes();
CharSequence label = property.loadLabel(pm);
- if (showSubtypes && subtypes.size() > 0) {
+ if (showSubtypes && enabledSubtypeSet.size() > 0) {
for (int j = 0; j < subtypes.size(); ++j) {
InputMethodSubtype subtype = subtypes.get(j);
- CharSequence title;
- int nameResId = subtype.getNameResId();
- int modeResId = subtype.getModeResId();
- if (nameResId != 0) {
- title = pm.getText(property.getPackageName(), nameResId,
- property.getServiceInfo().applicationInfo);
- } else {
- CharSequence language = subtype.getLocale();
- CharSequence mode = modeResId == 0 ? null
- : pm.getText(property.getPackageName(), modeResId,
- property.getServiceInfo().applicationInfo);
- // TODO: Use more friendly Title and UI
- title = label + "," + (mode == null ? "" : mode) + ","
- + (language == null ? "" : language);
+ if (enabledSubtypeSet.contains(String.valueOf(subtype.hashCode()))) {
+ CharSequence title;
+ int nameResId = subtype.getNameResId();
+ int modeResId = subtype.getModeResId();
+ if (nameResId != 0) {
+ title = pm.getText(property.getPackageName(), nameResId,
+ property.getServiceInfo().applicationInfo);
+ } else {
+ CharSequence language = subtype.getLocale();
+ CharSequence mode = modeResId == 0 ? null
+ : pm.getText(property.getPackageName(), modeResId,
+ property.getServiceInfo().applicationInfo);
+ // TODO: Use more friendly Title and UI
+ title = label + "," + (mode == null ? "" : mode) + ","
+ + (language == null ? "" : language);
+ }
+ imMap.put(title, new Pair<InputMethodInfo, Integer>(property, j));
}
- imMap.put(title, new Pair<InputMethodInfo, Integer>(property, j));
}
} else {
imMap.put(label,
@@ -1678,6 +1686,20 @@
}
});
+ if (showSubtypes) {
+ mDialogBuilder.setPositiveButton(com.android.internal.R.string.more_item_label,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ showInputMethodAndSubtypeEnabler();
+ }
+ });
+ }
+ mDialogBuilder.setNegativeButton(com.android.internal.R.string.cancel,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ hideInputMethodMenu();
+ }
+ });
mSwitchingDialog = mDialogBuilder.create();
mSwitchingDialog.getWindow().setType(
WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG);
@@ -1864,6 +1886,12 @@
getEnabledInputMethodsAndSubtypeListLocked());
}
+ public List<Pair<InputMethodInfo, ArrayList<String>>>
+ getEnabledInputMethodAndSubtypeListLocked() {
+ return createEnabledInputMethodAndSubtypeListLocked(
+ getEnabledInputMethodsAndSubtypeListLocked());
+ }
+
// At the initial boot, the settings for input methods are not set,
// so we need to enable IME in that case.
public void enableAllIMEsIfThereIsNoEnabledIME() {
@@ -1960,6 +1988,20 @@
return res;
}
+ private List<Pair<InputMethodInfo, ArrayList<String>>>
+ createEnabledInputMethodAndSubtypeListLocked(
+ List<Pair<String, ArrayList<String>>> imsList) {
+ final ArrayList<Pair<InputMethodInfo, ArrayList<String>>> res
+ = new ArrayList<Pair<InputMethodInfo, ArrayList<String>>>();
+ for (Pair<String, ArrayList<String>> ims : imsList) {
+ InputMethodInfo info = mMethodMap.get(ims.first);
+ if (info != null) {
+ res.add(new Pair<InputMethodInfo, ArrayList<String>>(info, ims.second));
+ }
+ }
+ return res;
+ }
+
private void putEnabledInputMethodsStr(String str) {
Settings.Secure.putString(mResolver, Settings.Secure.ENABLED_INPUT_METHODS, str);
mEnabledInputMethodsStrCache = str;
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 7870b06..c7997fe 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -172,8 +172,6 @@
this.token = token;
this.callerUid = callerUid;
mounted = false;
-
- getBinder().linkToDeath(this, 0);
}
// OBB source filename
@@ -198,7 +196,11 @@
mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(OBB_RUN_ACTION, action));
}
- public void cleanUp() {
+ public void link() throws RemoteException {
+ getBinder().linkToDeath(this, 0);
+ }
+
+ public void unlink() {
getBinder().unlinkToDeath(this, 0);
}
@@ -1672,14 +1674,39 @@
Slog.i(TAG, "Send to OBB handler: " + action.toString());
}
- private void addObbState(ObbState obbState) {
+ private void addObbState(ObbState obbState) throws RemoteException {
synchronized (mObbMounts) {
- List<ObbState> obbStates = mObbMounts.get(obbState.getBinder());
+ final IBinder binder = obbState.getBinder();
+ List<ObbState> obbStates = mObbMounts.get(binder);
+ final boolean unique;
+
if (obbStates == null) {
obbStates = new ArrayList<ObbState>();
- mObbMounts.put(obbState.getBinder(), obbStates);
+ mObbMounts.put(binder, obbStates);
+ unique = true;
+ } else {
+ unique = obbStates.contains(obbState);
}
- obbStates.add(obbState);
+
+ if (unique) {
+ obbStates.add(obbState);
+ try {
+ obbState.link();
+ } catch (RemoteException e) {
+ /*
+ * The binder died before we could link it, so clean up our
+ * state and return failure.
+ */
+ obbStates.remove(obbState);
+ if (obbStates.isEmpty()) {
+ mObbMounts.remove(binder);
+ }
+
+ // Rethrow the error so mountObb can get it
+ throw e;
+ }
+ }
+
mObbPathToStateMap.put(obbState.filename, obbState);
// Track the number of OBBs used by this UID.
@@ -1695,14 +1722,17 @@
private void removeObbState(ObbState obbState) {
synchronized (mObbMounts) {
- final List<ObbState> obbStates = mObbMounts.get(obbState.getBinder());
+ final IBinder binder = obbState.getBinder();
+ final List<ObbState> obbStates = mObbMounts.get(binder);
if (obbStates != null) {
- obbStates.remove(obbState);
+ if (obbStates.remove(obbState)) {
+ obbState.unlink();
+ }
+ if (obbStates.isEmpty()) {
+ mObbMounts.remove(binder);
+ }
}
- if (obbStates == null || obbStates.isEmpty()) {
- mObbMounts.remove(obbState.getBinder());
- obbState.cleanUp();
- }
+
mObbPathToStateMap.remove(obbState.filename);
// Track the number of OBBs used by this UID.
@@ -1721,7 +1751,7 @@
}
}
- private void replaceObbState(ObbState oldObbState, ObbState newObbState) {
+ private void replaceObbState(ObbState oldObbState, ObbState newObbState) throws RemoteException {
synchronized (mObbMounts) {
removeObbState(oldObbState);
addObbState(newObbState);
@@ -1756,15 +1786,9 @@
action.handleError();
return;
}
-
- mActions.add(action);
- break;
}
- // Once we bind to the service, the first
- // pending request will be processed.
mActions.add(action);
- mObbActionHandler.sendEmptyMessage(OBB_MCS_BOUND);
break;
}
case OBB_MCS_BOUND: {
@@ -1834,6 +1858,7 @@
if (DEBUG_OBB)
Slog.i(TAG, "OBB_MCS_GIVE_UP");
mActions.remove(0);
+ mObbActionHandler.sendEmptyMessage(OBB_MCS_BOUND);
break;
}
}
@@ -1892,6 +1917,7 @@
if (DEBUG_OBB)
Slog.d(TAG, "Error handling OBB action", e);
handleError();
+ mObbActionHandler.sendEmptyMessage(OBB_MCS_UNBIND);
}
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d008c90..3084c16 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -2998,84 +2998,6 @@
}
}
- final void decPersistentCountLocked(ProcessRecord app) {
- app.persistentActivities--;
- if (app.persistentActivities > 0) {
- // Still more of 'em...
- return;
- }
- if (app.persistent) {
- // Ah, but the application itself is persistent. Whatever!
- return;
- }
-
- // App is no longer persistent... make sure it and the ones
- // following it in the LRU list have the correc oom_adj.
- updateOomAdjLocked();
- }
-
- public void setPersistent(IBinder token, boolean isPersistent) {
- if (checkCallingPermission(android.Manifest.permission.PERSISTENT_ACTIVITY)
- != PackageManager.PERMISSION_GRANTED) {
- String msg = "Permission Denial: setPersistent() from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid()
- + " requires " + android.Manifest.permission.PERSISTENT_ACTIVITY;
- Slog.w(TAG, msg);
- throw new SecurityException(msg);
- }
-
- synchronized(this) {
- int index = mMainStack.indexOfTokenLocked(token);
- if (index < 0) {
- return;
- }
- ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
- ProcessRecord app = r.app;
-
- if (localLOGV) Slog.v(
- TAG, "Setting persistence " + isPersistent + ": " + r);
-
- if (isPersistent) {
- if (r.persistent) {
- // Okay okay, I heard you already!
- if (localLOGV) Slog.v(TAG, "Already persistent!");
- return;
- }
- r.persistent = true;
- app.persistentActivities++;
- if (localLOGV) Slog.v(TAG, "Num persistent now: " + app.persistentActivities);
- if (app.persistentActivities > 1) {
- // We aren't the first...
- if (localLOGV) Slog.v(TAG, "Not the first!");
- return;
- }
- if (app.persistent) {
- // This would be redundant.
- if (localLOGV) Slog.v(TAG, "App is persistent!");
- return;
- }
-
- // App is now persistent... make sure it and the ones
- // following it now have the correct oom_adj.
- final long origId = Binder.clearCallingIdentity();
- updateOomAdjLocked();
- Binder.restoreCallingIdentity(origId);
-
- } else {
- if (!r.persistent) {
- // Okay okay, I heard you already!
- return;
- }
- r.persistent = false;
- final long origId = Binder.clearCallingIdentity();
- decPersistentCountLocked(app);
- Binder.restoreCallingIdentity(origId);
-
- }
- }
- }
-
public boolean clearApplicationUserData(final String packageName,
final IPackageDataObserver observer) {
int uid = Binder.getCallingUid();
@@ -11765,11 +11687,6 @@
adj = FOREGROUND_APP_ADJ;
schedGroup = Process.THREAD_GROUP_DEFAULT;
app.adjType = "instrumentation";
- } else if (app.persistentActivities > 0) {
- // Special persistent activities... shouldn't be used these days.
- adj = FOREGROUND_APP_ADJ;
- schedGroup = Process.THREAD_GROUP_DEFAULT;
- app.adjType = "persistent";
} else if (app.curReceiver != null ||
(mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
// An app that is currently receiving a broadcast also
@@ -12493,8 +12410,7 @@
final ProcessRecord app = mLruProcesses.get(i);
if (app.persistent || app.services.size() != 0
- || app.curReceiver != null
- || app.persistentActivities > 0) {
+ || app.curReceiver != null) {
// Don't count processes holding services against our
// maximum process count.
if (localLOGV) Slog.v(
@@ -12559,8 +12475,7 @@
// Quit the application only if we have a state saved for
// all of its activities.
boolean canQuit = !app.persistent && app.curReceiver == null
- && app.services.size() == 0
- && app.persistentActivities == 0;
+ && app.services.size() == 0;
int NUMA = app.activities.size();
int j;
if (Config.LOGV) Slog.v(
@@ -12624,7 +12539,7 @@
// We can finish this one if we have its icicle saved and
// it is not persistent.
if ((r.haveState || !r.stateNotNeeded) && !r.visible
- && r.stopped && !r.persistent && !r.finishing) {
+ && r.stopped && !r.finishing) {
final int origSize = mMainStack.mLRUActivities.size();
r.stack.destroyActivityLocked(r, true);
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index 6bd89cc..47be6a2 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -96,7 +96,6 @@
int configChangeFlags; // which config values have changed
boolean keysPaused; // has key dispatching been paused for it?
boolean inHistory; // are we in the history stack?
- boolean persistent; // requested to be persistent?
int launchMode; // the launch mode activity attribute.
boolean visible; // does this activity's window need to be shown?
boolean waitingVisible; // true if waiting for a new act to become vis
@@ -161,7 +160,6 @@
pw.print(" finishing="); pw.println(finishing);
pw.print(prefix); pw.print("keysPaused="); pw.print(keysPaused);
pw.print(" inHistory="); pw.print(inHistory);
- pw.print(" persistent="); pw.print(persistent);
pw.print(" immersive="); pw.print(immersive);
pw.print(" launchMode="); pw.println(launchMode);
pw.print(prefix); pw.print("fullscreen="); pw.print(fullscreen);
@@ -215,7 +213,6 @@
configDestroy = false;
keysPaused = false;
inHistory = false;
- persistent = false;
visible = true;
waitingVisible = false;
nowVisible = false;
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 9ed1242..016ddcd 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -3151,9 +3151,6 @@
mService.mHandler.sendEmptyMessage(
ActivityManagerService.CANCEL_HEAVY_NOTIFICATION_MSG);
}
- if (r.persistent) {
- mService.decPersistentCountLocked(r.app);
- }
if (r.app.activities.size() == 0) {
// No longer have activities, so update location in
// LRU list.
@@ -3452,54 +3449,49 @@
return true;
}
- // If the activity isn't persistent, there is a chance we will
- // need to restart it.
- if (!r.persistent) {
-
- // Figure out what has changed between the two configurations.
- int changes = oldConfig.diff(newConfig);
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
- Slog.v(TAG, "Checking to restart " + r.info.name + ": changed=0x"
- + Integer.toHexString(changes) + ", handles=0x"
- + Integer.toHexString(r.info.configChanges)
- + ", newConfig=" + newConfig);
+ // Figure out what has changed between the two configurations.
+ int changes = oldConfig.diff(newConfig);
+ if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
+ Slog.v(TAG, "Checking to restart " + r.info.name + ": changed=0x"
+ + Integer.toHexString(changes) + ", handles=0x"
+ + Integer.toHexString(r.info.configChanges)
+ + ", newConfig=" + newConfig);
+ }
+ if ((changes&(~r.info.configChanges)) != 0) {
+ // Aha, the activity isn't handling the change, so DIE DIE DIE.
+ r.configChangeFlags |= changes;
+ r.startFreezingScreenLocked(r.app, globalChanges);
+ if (r.app == null || r.app.thread == null) {
+ if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
+ "Switch is destroying non-running " + r);
+ destroyActivityLocked(r, true);
+ } else if (r.state == ActivityState.PAUSING) {
+ // A little annoying: we are waiting for this activity to
+ // finish pausing. Let's not do anything now, but just
+ // flag that it needs to be restarted when done pausing.
+ if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
+ "Switch is skipping already pausing " + r);
+ r.configDestroy = true;
+ return true;
+ } else if (r.state == ActivityState.RESUMED) {
+ // Try to optimize this case: the configuration is changing
+ // and we need to restart the top, resumed activity.
+ // Instead of doing the normal handshaking, just say
+ // "restart!".
+ if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
+ "Switch is restarting resumed " + r);
+ relaunchActivityLocked(r, r.configChangeFlags, true);
+ r.configChangeFlags = 0;
+ } else {
+ if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
+ "Switch is restarting non-resumed " + r);
+ relaunchActivityLocked(r, r.configChangeFlags, false);
+ r.configChangeFlags = 0;
}
- if ((changes&(~r.info.configChanges)) != 0) {
- // Aha, the activity isn't handling the change, so DIE DIE DIE.
- r.configChangeFlags |= changes;
- r.startFreezingScreenLocked(r.app, globalChanges);
- if (r.app == null || r.app.thread == null) {
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
- "Switch is destroying non-running " + r);
- destroyActivityLocked(r, true);
- } else if (r.state == ActivityState.PAUSING) {
- // A little annoying: we are waiting for this activity to
- // finish pausing. Let's not do anything now, but just
- // flag that it needs to be restarted when done pausing.
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
- "Switch is skipping already pausing " + r);
- r.configDestroy = true;
- return true;
- } else if (r.state == ActivityState.RESUMED) {
- // Try to optimize this case: the configuration is changing
- // and we need to restart the top, resumed activity.
- // Instead of doing the normal handshaking, just say
- // "restart!".
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
- "Switch is restarting resumed " + r);
- relaunchActivityLocked(r, r.configChangeFlags, true);
- r.configChangeFlags = 0;
- } else {
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
- "Switch is restarting non-resumed " + r);
- relaunchActivityLocked(r, r.configChangeFlags, false);
- r.configChangeFlags = 0;
- }
-
- // All done... tell the caller we weren't able to keep this
- // activity around.
- return false;
- }
+
+ // All done... tell the caller we weren't able to keep this
+ // activity around.
+ return false;
}
// Default case: the activity can handle this new configuration, so
diff --git a/services/java/com/android/server/am/BroadcastRecord.java b/services/java/com/android/server/am/BroadcastRecord.java
index bac21b1..b268efa 100644
--- a/services/java/com/android/server/am/BroadcastRecord.java
+++ b/services/java/com/android/server/am/BroadcastRecord.java
@@ -84,8 +84,8 @@
pw.print(prefix); pw.print("extras: "); pw.println(bundle.toString());
}
}
- pw.print(prefix); pw.print("caller="); pw.print(callerPackage); pw.println(" ");
- pw.println(callerApp != null ? callerApp.toShortString() : "null");
+ pw.print(prefix); pw.print("caller="); pw.print(callerPackage); pw.print(" ");
+ pw.print(callerApp != null ? callerApp.toShortString() : "null");
pw.print(" pid="); pw.print(callingPid);
pw.print(" uid="); pw.println(callingUid);
if (requiredPermission != null) {
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index 404c6be..353ff6d 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -115,7 +115,6 @@
Dialog anrDialog; // dialog being displayed due to app not resp.
boolean removed; // has app package been removed from device?
boolean debugging; // was app launched for debugging?
- int persistentActivities; // number of activities that are persistent
boolean waitedForDebugger; // has process show wait for debugger dialog?
Dialog waitDialog; // current wait for debugger dialog
@@ -181,8 +180,7 @@
pw.print(" foregroundServices="); pw.print(foregroundServices);
pw.print(" forcingToForeground="); pw.println(forcingToForeground);
pw.print(prefix); pw.print("persistent="); pw.print(persistent);
- pw.print(" removed="); pw.print(removed);
- pw.print(" persistentActivities="); pw.println(persistentActivities);
+ pw.print(" removed="); pw.println(removed);
pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq);
pw.print(" lruSeq="); pw.println(lruSeq);
if (!keeping) {
@@ -259,7 +257,6 @@
curAdj = setAdj = -100;
persistent = false;
removed = false;
- persistentActivities = 0;
}
public void setPid(int _pid) {
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index bfac346..0623f5b 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -113,7 +113,7 @@
private String[] mDnsServers;
private static final String DNS_DEFAULT_SERVER1 = "8.8.8.8";
- private static final String DNS_DEFAULT_SERVER2 = "4.2.2.2";
+ private static final String DNS_DEFAULT_SERVER2 = "8.8.4.4";
// resampled each time we turn on tethering - used as cache for settings/config-val
private boolean mDunRequired; // configuration info - must use DUN apn on 3g
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index ff887e4..4af274b 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -84,7 +84,9 @@
status_t HWComposer::commit() const {
int err = mHwc->set(mHwc, mDpy, mSur, mList);
- mList->flags &= ~HWC_GEOMETRY_CHANGED;
+ if (mList) {
+ mList->flags &= ~HWC_GEOMETRY_CHANGED;
+ }
return (status_t)err;
}
diff --git a/services/surfaceflinger/MessageQueue.cpp b/services/surfaceflinger/MessageQueue.cpp
index d668e88..4fb1e61 100644
--- a/services/surfaceflinger/MessageQueue.cpp
+++ b/services/surfaceflinger/MessageQueue.cpp
@@ -91,17 +91,21 @@
mMessages.remove(cur);
break;
}
- if (timeout>=0 && timeoutTime < now) {
- // we timed-out, return a NULL message
- result = 0;
- break;
- }
nextEventTime = result->when;
result = 0;
}
- if (timeout >= 0 && nextEventTime > 0) {
- if (nextEventTime > timeoutTime) {
+ if (timeout >= 0) {
+ if (timeoutTime < now) {
+ // we timed-out, return a NULL message
+ result = 0;
+ break;
+ }
+ if (nextEventTime > 0) {
+ if (nextEventTime > timeoutTime) {
+ nextEventTime = timeoutTime;
+ }
+ } else {
nextEventTime = timeoutTime;
}
}
diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java
index 09b7d05..7a026fa 100644
--- a/telephony/java/com/android/internal/telephony/CallManager.java
+++ b/telephony/java/com/android/internal/telephony/CallManager.java
@@ -1468,13 +1468,27 @@
*
*/
public Call getActiveFgCall() {
- for (Call call : mForegroundCalls) {
- if (call.getState() != Call.State.IDLE) {
+ Call call = getFirstNonIdleCall(mForegroundCalls);
+ if (call == null) {
+ call = (mDefaultPhone == null)
+ ? null
+ : mDefaultPhone.getForegroundCall();
+ }
+ return call;
+ }
+
+ // Returns the first call that is not in IDLE state. If both active calls
+ // and disconnecting/disconnected calls exist, return the first active call.
+ private Call getFirstNonIdleCall(List<Call> calls) {
+ Call result = null;
+ for (Call call : calls) {
+ if (!call.isIdle()) {
return call;
+ } else if (call.getState() != Call.State.IDLE) {
+ if (result == null) result = call;
}
}
- return (mDefaultPhone == null) ?
- null : mDefaultPhone.getForegroundCall();
+ return result;
}
/**
@@ -1491,13 +1505,13 @@
* Complete background calls list can be get by getBackgroundCalls()
*/
public Call getFirstActiveBgCall() {
- for (Call call : mBackgroundCalls) {
- if (call.getState() != Call.State.IDLE) {
- return call;
- }
+ Call call = getFirstNonIdleCall(mBackgroundCalls);
+ if (call == null) {
+ call = (mDefaultPhone == null)
+ ? null
+ : mDefaultPhone.getBackgroundCall();
}
- return (mDefaultPhone == null) ?
- null : mDefaultPhone.getBackgroundCall();
+ return call;
}
/**
@@ -1514,13 +1528,13 @@
* Complete ringing calls list can be get by getRingingCalls()
*/
public Call getFirstActiveRingingCall() {
- for (Call call : mRingingCalls) {
- if (!call.isIdle()) {
- return call;
- }
+ Call call = getFirstNonIdleCall(mRingingCalls);
+ if (call == null) {
+ call = (mDefaultPhone == null)
+ ? null
+ : mDefaultPhone.getRingingCall();
}
- return (mDefaultPhone == null) ?
- null : mDefaultPhone.getRingingCall();
+ return call;
}
/**
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
index 6ed9295..878d30c 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
@@ -810,7 +810,10 @@
} catch (SipException e) {
throw new CallStateException("hangup(): " + e);
} finally {
- mAdapter.onCallEnded(DisconnectCause.LOCAL);
+ mAdapter.onCallEnded(((mState == Call.State.INCOMING)
+ || (mState == Call.State.WAITING))
+ ? DisconnectCause.INCOMING_REJECTED
+ : DisconnectCause.LOCAL);
}
}
}
diff --git a/tests/CoreTests/android/core/NIOTest.java b/tests/CoreTests/android/core/NIOTest.java
index fd279ca..9476d07 100644
--- a/tests/CoreTests/android/core/NIOTest.java
+++ b/tests/CoreTests/android/core/NIOTest.java
@@ -40,27 +40,31 @@
}
@SmallTest
- public void testNIO() throws Exception {
- ByteBuffer b;
-
+ public void testNIO_byte_array() throws Exception {
// Test byte array-based buffer
- b = ByteBuffer.allocate(12);
- byteBufferTest(b);
+ byteBufferTest(ByteBuffer.allocate(12));
+ }
+ public void testNIO_direct() throws Exception {
// Test native heap-allocated buffer
- b = ByteBuffer.allocateDirect(12);
- byteBufferTest(b);
+ byteBufferTest(ByteBuffer.allocateDirect(12));
+ }
+ public void testNIO_short_array() throws Exception {
// Test short array-based buffer
short[] shortArray = new short[8];
ShortBuffer sb = ShortBuffer.wrap(shortArray);
shortBufferTest(sb);
+ }
+ public void testNIO_int_array() throws Exception {
// Test int array-based buffer
int[] intArray = new int[8];
IntBuffer ib = IntBuffer.wrap(intArray);
intBufferTest(ib);
+ }
+ public void testNIO_float_array() throws Exception {
// Test float array-based buffer
float[] floatArray = new float[8];
FloatBuffer fb = FloatBuffer.wrap(floatArray);
@@ -70,6 +74,12 @@
private void byteBufferTest(ByteBuffer b) {
checkBuffer(b);
+ // Duplicate buffers revert to big-endian.
+ b.order(ByteOrder.LITTLE_ENDIAN);
+ ByteBuffer dupe = b.duplicate();
+ assertEquals(ByteOrder.BIG_ENDIAN, dupe.order());
+ b.order(ByteOrder.BIG_ENDIAN);
+
// Bounds checks
try {
b.put(-1, (byte) 0);
@@ -272,9 +282,9 @@
// Check 'getFloat'
b.order(ByteOrder.LITTLE_ENDIAN);
b.position(0);
- assertEquals(0xA3A2A1A0, Float.floatToIntBits(b.getFloat()));
- assertEquals(0xA7A6A5A4, Float.floatToIntBits(b.getFloat()));
- assertEquals(0xABAAA9A8, Float.floatToIntBits(b.getFloat()));
+ assertEquals(0xA3A2A1A0, Float.floatToRawIntBits(b.getFloat()));
+ assertEquals(0xA7A6A5A4, Float.floatToRawIntBits(b.getFloat()));
+ assertEquals(0xABAAA9A8, Float.floatToRawIntBits(b.getFloat()));
try {
b.getFloat();
fail("expected exception not thrown");
@@ -284,9 +294,9 @@
b.order(ByteOrder.BIG_ENDIAN);
b.position(0);
- assertEquals(0xA0A1A2A3, Float.floatToIntBits(b.getFloat()));
- assertEquals(0xA4A5A6A7, Float.floatToIntBits(b.getFloat()));
- assertEquals(0xA8A9AAAB, Float.floatToIntBits(b.getFloat()));
+ assertEquals(0xA0A1A2A3, Float.floatToRawIntBits(b.getFloat()));
+ assertEquals(0xA4A5A6A7, Float.floatToRawIntBits(b.getFloat()));
+ assertEquals(0xA8A9AAAB, Float.floatToRawIntBits(b.getFloat()));
try {
b.getFloat();
fail("expected exception not thrown");
@@ -296,8 +306,8 @@
// Check 'getDouble(int position)'
b.order(ByteOrder.LITTLE_ENDIAN);
- assertEquals(0xA7A6A5A4A3A2A1A0L, Double.doubleToLongBits(b.getDouble(0)));
- assertEquals(0xA8A7A6A5A4A3A2A1L, Double.doubleToLongBits(b.getDouble(1)));
+ assertEquals(0xA7A6A5A4A3A2A1A0L, Double.doubleToRawLongBits(b.getDouble(0)));
+ assertEquals(0xA8A7A6A5A4A3A2A1L, Double.doubleToRawLongBits(b.getDouble(1)));
try {
b.getDouble(-1);
fail("expected exception not thrown");
@@ -312,8 +322,8 @@
}
b.order(ByteOrder.BIG_ENDIAN);
- assertEquals(0xA0A1A2A3A4A5A6A7L, Double.doubleToLongBits(b.getDouble(0)));
- assertEquals(0xA1A2A3A4A5A6A7A8L, Double.doubleToLongBits(b.getDouble(1)));
+ assertEquals(0xA0A1A2A3A4A5A6A7L, Double.doubleToRawLongBits(b.getDouble(0)));
+ assertEquals(0xA1A2A3A4A5A6A7A8L, Double.doubleToRawLongBits(b.getDouble(1)));
try {
b.getDouble(-1);
fail("expected exception not thrown");
@@ -333,6 +343,9 @@
b.order(ByteOrder.LITTLE_ENDIAN);
bb = b.slice();
assertEquals(4, bb.capacity());
+ assertEquals(ByteOrder.BIG_ENDIAN, bb.order());
+ assertEquals(0xA1A2A3A4, bb.getInt(0));
+ bb.order(ByteOrder.LITTLE_ENDIAN);
assertEquals(0xA4A3A2A1, bb.getInt(0));
bb.order(ByteOrder.LITTLE_ENDIAN);
@@ -370,14 +383,14 @@
checkBuffer(fb);
assertEquals(1, fb.capacity());
- assertEquals(0xA4A3A2A1, Float.floatToIntBits(fb.get()));
+ assertEquals(0xA4A3A2A1, Float.floatToRawIntBits(fb.get()));
bb.order(ByteOrder.BIG_ENDIAN);
fb = bb.asFloatBuffer();
checkBuffer(fb);
assertEquals(1, fb.capacity());
- assertEquals(0xA1A2A3A4, Float.floatToIntBits(fb.get()));
+ assertEquals(0xA1A2A3A4, Float.floatToRawIntBits(fb.get()));
}
private void shortBufferTest(ShortBuffer sb) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
index 58b1b6c..f501459 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
@@ -246,8 +246,8 @@
BridgeXmlBlockParser parser = null;
if (set instanceof BridgeXmlBlockParser) {
parser = (BridgeXmlBlockParser)set;
- } else {
- // reall this should not be happening since its instantiated in Bridge
+ } else if (set != null) { // null parser is ok
+ // really this should not be happening since its instantiated in Bridge
mLogger.error("Parser is not a BridgeXmlBlockParser!");
return null;
}
@@ -256,13 +256,16 @@
TreeMap<Integer, String> styleNameMap = searchAttrs(attrs, frameworkAttributes);
BridgeTypedArray ta = ((BridgeResources) mResources).newTypeArray(attrs.length,
- parser.isPlatformFile());
+ parser != null ? parser.isPlatformFile() : true);
// resolve the defStyleAttr value into a IStyleResourceValue
IStyleResourceValue defStyleValues = null;
// look for a custom style.
- String customStyle = parser.getAttributeValue(null /* namespace*/, "style");
+ String customStyle = null;
+ if (parser != null) {
+ customStyle = parser.getAttributeValue(null /* namespace*/, "style");
+ }
if (customStyle != null) {
IResourceValue item = findResValue(customStyle);
@@ -309,7 +312,10 @@
int index = styleAttribute.getKey().intValue();
String name = styleAttribute.getValue();
- String value = parser.getAttributeValue(namespace, name);
+ String value = null;
+ if (parser != null) {
+ value = parser.getAttributeValue(namespace, name);
+ }
// if there's no direct value for this attribute in the XML, we look for default
// values in the widget defStyle, and then in the theme.
diff --git a/voip/java/android/net/sip/SipManager.java b/voip/java/android/net/sip/SipManager.java
index 80c35fb..8c32aa0 100644
--- a/voip/java/android/net/sip/SipManager.java
+++ b/voip/java/android/net/sip/SipManager.java
@@ -65,6 +65,13 @@
public static final String EXTRA_OFFER_SD = "android:sipOfferSD";
/**
+ * Action to broadcast when SipService is up.
+ * Internal use only.
+ * @hide
+ */
+ public static final String ACTION_SIP_SERVICE_UP =
+ "android.net.sip.SIP_SERVICE_UP";
+ /**
* Action string for the incoming call intent for the Phone app.
* Internal use only.
* @hide
diff --git a/voip/java/com/android/server/sip/SipService.java b/voip/java/com/android/server/sip/SipService.java
index a7c61e5..1fa2400 100644
--- a/voip/java/com/android/server/sip/SipService.java
+++ b/voip/java/com/android/server/sip/SipService.java
@@ -100,6 +100,7 @@
public static void start(Context context) {
if (SipManager.isApiSupported(context)) {
ServiceManager.addService("sip", new SipService(context));
+ context.sendBroadcast(new Intent(SipManager.ACTION_SIP_SERVICE_UP));
Log.i(TAG, "SIP service started");
}
}
@@ -825,11 +826,13 @@
synchronized (SipService.this) {
if (notCurrentSession(session)) return;
- if (errorCode == SipErrorCode.INVALID_CREDENTIALS) {
- if (DEBUG) Log.d(TAG, " pause auto-registration");
- stop();
- } else {
- onError();
+ switch (errorCode) {
+ case SipErrorCode.INVALID_CREDENTIALS:
+ case SipErrorCode.SERVER_UNREACHABLE:
+ if (DEBUG) Log.d(TAG, " pause auto-registration");
+ stop();
+ default:
+ restartLater();
}
mErrorCode = errorCode;
@@ -846,11 +849,11 @@
mErrorCode = SipErrorCode.TIME_OUT;
mProxy.onRegistrationTimeout(session);
- onError();
+ restartLater();
}
}
- private void onError() {
+ private void restartLater() {
mRegistered = false;
restart(backoffDuration());
if (mKeepAliveProcess != null) {
diff --git a/voip/java/com/android/server/sip/SipSessionGroup.java b/voip/java/com/android/server/sip/SipSessionGroup.java
index 37fffa8..57b3710 100644
--- a/voip/java/com/android/server/sip/SipSessionGroup.java
+++ b/voip/java/com/android/server/sip/SipSessionGroup.java
@@ -96,8 +96,6 @@
private SipStack mSipStack;
private SipHelper mSipHelper;
- private String mLastNonce;
- private int mRPort;
// session that processes INVITE requests
private SipSessionImpl mCallReceiverSession;
@@ -150,7 +148,6 @@
Log.d(TAG, " start stack for " + myself.getUriString());
stack.start();
- mLastNonce = null;
mCallReceiverSession = null;
mSessionMap.clear();
}
@@ -366,8 +363,12 @@
ClientTransaction mClientTransaction;
String mPeerSessionDescription;
boolean mInCall;
- boolean mReRegisterFlag = false;
SessionTimer mTimer;
+ int mAuthenticationRetryCount;
+
+ // for registration
+ boolean mReRegisterFlag = false;
+ int mRPort;
// lightweight timer
class SessionTimer {
@@ -417,6 +418,8 @@
mState = SipSession.State.READY_TO_CALL;
mInviteReceived = null;
mPeerSessionDescription = null;
+ mRPort = 0;
+ mAuthenticationRetryCount = 0;
if (mDialog != null) mDialog.delete();
mDialog = null;
@@ -799,22 +802,10 @@
onRegistrationDone((state == SipSession.State.REGISTERING)
? getExpiryTime(((ResponseEvent) evt).getResponse())
: -1);
- mLastNonce = null;
- mRPort = 0;
return true;
case Response.UNAUTHORIZED:
case Response.PROXY_AUTHENTICATION_REQUIRED:
- if (!handleAuthentication(event)) {
- if (mLastNonce == null) {
- onRegistrationFailed(SipErrorCode.SERVER_ERROR,
- "server does not provide challenge");
- } else {
- Log.v(TAG, "Incorrect username/password");
- onRegistrationFailed(
- SipErrorCode.INVALID_CREDENTIALS,
- "incorrect username or password");
- }
- }
+ handleAuthentication(event);
return true;
default:
if (statusCode >= 500) {
@@ -830,16 +821,24 @@
throws SipException {
Response response = event.getResponse();
String nonce = getNonceFromResponse(response);
- if (((nonce != null) && nonce.equals(mLastNonce)) ||
- (nonce == null)) {
- mLastNonce = nonce;
+ if (nonce == null) {
+ onError(SipErrorCode.SERVER_ERROR,
+ "server does not provide challenge");
return false;
- } else {
+ } else if (mAuthenticationRetryCount < 2) {
mClientTransaction = mSipHelper.handleChallenge(
event, getAccountManager());
mDialog = mClientTransaction.getDialog();
- mLastNonce = nonce;
+ mAuthenticationRetryCount++;
+ if (isLoggable(this, event)) {
+ Log.d(TAG, " authentication retry count="
+ + mAuthenticationRetryCount);
+ }
return true;
+ } else {
+ onError(SipErrorCode.INVALID_CREDENTIALS,
+ "incorrect username or password");
+ return false;
}
}
@@ -995,12 +994,6 @@
getRealmFromResponse(response));
} else if (handleAuthentication(event)) {
addSipSession(this);
- } else if (mLastNonce == null) {
- onError(SipErrorCode.SERVER_ERROR,
- "server does not provide challenge");
- } else {
- onError(SipErrorCode.INVALID_CREDENTIALS,
- "incorrect username or password");
}
return true;
case Response.REQUEST_PENDING:
diff --git a/voip/jni/rtp/AmrCodec.cpp b/voip/jni/rtp/AmrCodec.cpp
index 84c7166..72ee44e 100644
--- a/voip/jni/rtp/AmrCodec.cpp
+++ b/voip/jni/rtp/AmrCodec.cpp
@@ -73,7 +73,7 @@
}
// Handle mode-set and octet-align.
- const char *modes = strcasestr(fmtp, "mode-set=");
+ char *modes = (char*)strcasestr(fmtp, "mode-set=");
if (modes) {
mMode = 0;
mModeSet = 0;
diff --git a/voip/jni/rtp/EchoSuppressor.cpp b/voip/jni/rtp/EchoSuppressor.cpp
index 2ceebdc..f99bd0a 100644
--- a/voip/jni/rtp/EchoSuppressor.cpp
+++ b/voip/jni/rtp/EchoSuppressor.cpp
@@ -15,6 +15,7 @@
*/
#include <stdio.h>
+#include <string.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
index 9634157..be5fab4 100644
--- a/wifi/java/android/net/wifi/WifiConfigStore.java
+++ b/wifi/java/android/net/wifi/WifiConfigStore.java
@@ -20,6 +20,9 @@
import android.content.Context;
import android.content.Intent;
import android.net.DhcpInfo;
+import android.net.LinkAddress;
+import android.net.LinkProperties;
+import android.net.NetworkUtils;
import android.net.ProxyProperties;
import android.net.wifi.WifiConfiguration.IpAssignment;
import android.net.wifi.WifiConfiguration.KeyMgmt;
@@ -34,13 +37,18 @@
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
+import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.net.InetAddress;
import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.BitSet;
+import java.util.Collection;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
/**
@@ -61,13 +69,10 @@
* ..
*
* (key, value) pairs for a given network are grouped together and can
- * be in any order. A "EOS" at the end of a set of (key, value) pairs
+ * be in any order. A EOS at the end of a set of (key, value) pairs
* indicates that the next set of (key, value) pairs are for a new
- * network. A network is identified by a unique "id". If there is no
- * "id" key in the (key, value) pairs, the data is discarded. An IP
- * configuration includes the keys - "ipAssignment", "ipAddress", "gateway",
- * "netmask", "dns1" and "dns2". A proxy configuration includes "proxySettings",
- * "proxyHost", "proxyPort" and "exclusionList"
+ * network. A network is identified by a unique ID_KEY. If there is no
+ * ID_KEY in the (key, value) pairs, the data is discarded.
*
* An invalid version on read would result in discarding the contents of
* the file. On the next write, the latest version is written to file.
@@ -118,6 +123,18 @@
private static final int IPCONFIG_FILE_VERSION = 1;
+ /* IP and proxy configuration keys */
+ private static final String ID_KEY = "id";
+ private static final String IP_ASSIGNMENT_KEY = "ipAssignment";
+ private static final String LINK_ADDRESS_KEY = "linkAddress";
+ private static final String GATEWAY_KEY = "gateway";
+ private static final String DNS_KEY = "dns";
+ private static final String PROXY_SETTINGS_KEY = "proxySettings";
+ private static final String PROXY_HOST_KEY = "proxyHost";
+ private static final String PROXY_PORT_KEY = "proxyPort";
+ private static final String EXCLUSION_LIST_KEY = "exclusionList";
+ private static final String EOS = "eos";
+
/**
* Initialize context, fetch the list of configured networks
* and enable all stored networks in supplicant.
@@ -370,25 +387,61 @@
}
/**
- * Fetch the IP configuration for a given network id
+ * Fetch the link properties for a given network id
*/
- static DhcpInfo getIpConfiguration(int netId) {
+ static LinkProperties getLinkProperties(int netId) {
synchronized (sConfiguredNetworks) {
WifiConfiguration config = sConfiguredNetworks.get(netId);
- if (config != null) return new DhcpInfo(config.ipConfig);
+ if (config != null) return new LinkProperties(config.linkProperties);
}
return null;
}
/**
+ * get IP configuration for a given network id
+ * TODO: We cannot handle IPv6 addresses for configuration
+ * right now until NetworkUtils is fixed. When we do
+ * that, we should remove handling DhcpInfo and move
+ * to using LinkProperties
+ */
+ static DhcpInfo getIpConfiguration(int netId) {
+ DhcpInfo dhcpInfo = new DhcpInfo();
+ LinkProperties linkProperties = getLinkProperties(netId);
+
+ if (linkProperties != null) {
+ Iterator<LinkAddress> iter = linkProperties.getLinkAddresses().iterator();
+ if (iter.hasNext()) {
+ try {
+ LinkAddress linkAddress = iter.next();
+ dhcpInfo.ipAddress = NetworkUtils.inetAddressToInt(
+ linkAddress.getAddress());
+ dhcpInfo.gateway = NetworkUtils.inetAddressToInt(
+ linkProperties.getGateway());
+ dhcpInfo.netmask = NetworkUtils.prefixLengthToNetmaskInt(
+ linkAddress.getNetworkPrefixLength());
+ Iterator<InetAddress> dnsIterator = linkProperties.getDnses().iterator();
+ dhcpInfo.dns1 = NetworkUtils.inetAddressToInt(dnsIterator.next());
+ if (dnsIterator.hasNext()) {
+ dhcpInfo.dns2 = NetworkUtils.inetAddressToInt(dnsIterator.next());
+ }
+ } catch (IllegalArgumentException e1) {
+ Log.e(TAG, "IPv6 address cannot be handled " + e1);
+ } catch (NullPointerException e2) {
+ /* Should not happen since a stored static config should be valid */
+ Log.e(TAG, "Invalid partial IP configuration " + e2);
+ }
+ }
+ }
+ return dhcpInfo;
+ }
+
+ /**
* Fetch the proxy properties for a given network id
*/
static ProxyProperties getProxyProperties(int netId) {
- synchronized (sConfiguredNetworks) {
- WifiConfiguration config = sConfiguredNetworks.get(netId);
- if (config != null && config.proxySettings == ProxySettings.STATIC) {
- return new ProxyProperties(config.proxyProperties);
- }
+ LinkProperties linkProperties = getLinkProperties(netId);
+ if (linkProperties != null) {
+ return new ProxyProperties(linkProperties.getHttpProxy());
}
return null;
}
@@ -484,71 +537,75 @@
for(WifiConfiguration config : sConfiguredNetworks.values()) {
boolean writeToFile = false;
- switch (config.ipAssignment) {
- case STATIC:
- out.writeUTF("ipAssignment");
- out.writeUTF(config.ipAssignment.toString());
- out.writeUTF("ipAddress");
- out.writeInt(config.ipConfig.ipAddress);
- out.writeUTF("gateway");
- out.writeInt(config.ipConfig.gateway);
- out.writeUTF("netmask");
- out.writeInt(config.ipConfig.netmask);
- out.writeUTF("dns1");
- out.writeInt(config.ipConfig.dns1);
- out.writeUTF("dns2");
- out.writeInt(config.ipConfig.dns2);
- writeToFile = true;
- break;
- case DHCP:
- out.writeUTF("ipAssignment");
- out.writeUTF(config.ipAssignment.toString());
- writeToFile = true;
- break;
- case UNASSIGNED:
- /* Ignore */
- break;
- default:
- Log.e(TAG, "Ignore invalid ip assignment while writing");
- break;
- }
-
- switch (config.proxySettings) {
- case STATIC:
- out.writeUTF("proxySettings");
- out.writeUTF(config.proxySettings.toString());
- InetSocketAddress proxy = config.proxyProperties.getSocketAddress();
- if (proxy != null) {
- out.writeUTF("proxyHost");
- out.writeUTF(proxy.getHostName());
- out.writeUTF("proxyPort");
- out.writeInt(proxy.getPort());
- String exclusionList = config.proxyProperties.getExclusionList();
- if (exclusionList != null && exclusionList.length() > 0) {
- out.writeUTF("exclusionList");
- out.writeUTF(exclusionList);
+ try {
+ LinkProperties linkProperties = config.linkProperties;
+ switch (config.ipAssignment) {
+ case STATIC:
+ out.writeUTF(IP_ASSIGNMENT_KEY);
+ out.writeUTF(config.ipAssignment.toString());
+ for (LinkAddress linkAddr : linkProperties.getLinkAddresses()) {
+ out.writeUTF(LINK_ADDRESS_KEY);
+ out.writeUTF(linkAddr.getAddress().getHostAddress());
+ out.writeInt(linkAddr.getNetworkPrefixLength());
}
- }
- writeToFile = true;
- break;
- case NONE:
- out.writeUTF("proxySettings");
- out.writeUTF(config.proxySettings.toString());
- writeToFile = true;
- break;
- case UNASSIGNED:
- /* Ignore */
- break;
- default:
- Log.e(TAG, "Ignore invalid proxy settings while writing");
- break;
- }
+ InetAddress gateway = linkProperties.getGateway();
+ if (gateway != null) {
+ out.writeUTF(GATEWAY_KEY);
+ out.writeUTF(gateway.getHostAddress());
+ }
+ for (InetAddress inetAddr : linkProperties.getDnses()) {
+ out.writeUTF(DNS_KEY);
+ out.writeUTF(inetAddr.getHostAddress());
+ }
+ writeToFile = true;
+ break;
+ case DHCP:
+ out.writeUTF(IP_ASSIGNMENT_KEY);
+ out.writeUTF(config.ipAssignment.toString());
+ writeToFile = true;
+ break;
+ case UNASSIGNED:
+ /* Ignore */
+ break;
+ default:
+ Log.e(TAG, "Ignore invalid ip assignment while writing");
+ break;
+ }
- if (writeToFile) {
- out.writeUTF("id");
- out.writeInt(configKey(config));
- out.writeUTF("EOS");
+ switch (config.proxySettings) {
+ case STATIC:
+ ProxyProperties proxyProperties = linkProperties.getHttpProxy();
+ String exclusionList = proxyProperties.getExclusionList();
+ out.writeUTF(PROXY_SETTINGS_KEY);
+ out.writeUTF(config.proxySettings.toString());
+ out.writeUTF(PROXY_HOST_KEY);
+ out.writeUTF(proxyProperties.getSocketAddress().getHostName());
+ out.writeUTF(PROXY_PORT_KEY);
+ out.writeInt(proxyProperties.getSocketAddress().getPort());
+ out.writeUTF(EXCLUSION_LIST_KEY);
+ out.writeUTF(exclusionList);
+ writeToFile = true;
+ break;
+ case NONE:
+ out.writeUTF(PROXY_SETTINGS_KEY);
+ out.writeUTF(config.proxySettings.toString());
+ writeToFile = true;
+ break;
+ case UNASSIGNED:
+ /* Ignore */
+ break;
+ default:
+ Log.e(TAG, "Ignore invalid proxy settings while writing");
+ break;
+ }
+ if (writeToFile) {
+ out.writeUTF(ID_KEY);
+ out.writeInt(configKey(config));
+ }
+ } catch (NullPointerException e) {
+ Log.e(TAG, "Failure in writing " + config.linkProperties + e);
}
+ out.writeUTF(EOS);
}
}
@@ -578,8 +635,8 @@
while (true) {
int id = -1;
IpAssignment ipAssignment = IpAssignment.UNASSIGNED;
- DhcpInfo ipConfig = new DhcpInfo();
ProxySettings proxySettings = ProxySettings.UNASSIGNED;
+ LinkProperties linkProperties = new LinkProperties();
String proxyHost = null;
int proxyPort = -1;
String exclusionList = null;
@@ -587,32 +644,34 @@
do {
key = in.readUTF();
- if (key.equals("id")) {
- id = in.readInt();
- } else if (key.equals("ipAssignment")) {
- ipAssignment = IpAssignment.valueOf(in.readUTF());
- } else if (key.equals("ipAddress")) {
- ipConfig.ipAddress = in.readInt();
- } else if (key.equals("gateway")) {
- ipConfig.gateway = in.readInt();
- } else if (key.equals("netmask")) {
- ipConfig.netmask = in.readInt();
- } else if (key.equals("dns1")) {
- ipConfig.dns1 = in.readInt();
- } else if (key.equals("dns2")) {
- ipConfig.dns2 = in.readInt();
- } else if (key.equals("proxySettings")) {
- proxySettings = ProxySettings.valueOf(in.readUTF());
- } else if (key.equals("proxyHost")) {
- proxyHost = in.readUTF();
- } else if (key.equals("proxyPort")) {
- proxyPort = in.readInt();
- } else if (key.equals("exclusionList")) {
- exclusionList = in.readUTF();
- } else if (key.equals("EOS")) {
- break;
- } else {
- Log.e(TAG, "Ignore unknown key " + key + "while reading");
+ try {
+ if (key.equals(ID_KEY)) {
+ id = in.readInt();
+ } else if (key.equals(IP_ASSIGNMENT_KEY)) {
+ ipAssignment = IpAssignment.valueOf(in.readUTF());
+ } else if (key.equals(LINK_ADDRESS_KEY)) {
+ LinkAddress linkAddr = new LinkAddress(InetAddress.getByName(
+ in.readUTF()), in.readInt());
+ linkProperties.addLinkAddress(linkAddr);
+ } else if (key.equals(GATEWAY_KEY)) {
+ linkProperties.setGateway(InetAddress.getByName(in.readUTF()));
+ } else if (key.equals(DNS_KEY)) {
+ linkProperties.addDns(InetAddress.getByName(in.readUTF()));
+ } else if (key.equals(PROXY_SETTINGS_KEY)) {
+ proxySettings = ProxySettings.valueOf(in.readUTF());
+ } else if (key.equals(PROXY_HOST_KEY)) {
+ proxyHost = in.readUTF();
+ } else if (key.equals(PROXY_PORT_KEY)) {
+ proxyPort = in.readInt();
+ } else if (key.equals(EXCLUSION_LIST_KEY)) {
+ exclusionList = in.readUTF();
+ } else if (key.equals(EOS)) {
+ break;
+ } else {
+ Log.e(TAG, "Ignore unknown key " + key + "while reading");
+ }
+ } catch (UnknownHostException e) {
+ Log.e(TAG, "Ignore invalid address while reading" + e);
}
} while (true);
@@ -624,11 +683,9 @@
if (config == null) {
Log.e(TAG, "configuration found for missing network, ignored");
} else {
+ config.linkProperties = linkProperties;
switch (ipAssignment) {
case STATIC:
- config.ipAssignment = ipAssignment;
- config.ipConfig = ipConfig;
- break;
case DHCP:
config.ipAssignment = ipAssignment;
break;
@@ -647,7 +704,7 @@
proxyProperties.setSocketAddress(
new InetSocketAddress(proxyHost, proxyPort));
proxyProperties.setExclusionList(exclusionList);
- config.proxyProperties = proxyProperties;
+ linkProperties.setHttpProxy(proxyProperties);
break;
case NONE:
config.proxySettings = proxySettings;
@@ -662,11 +719,12 @@
}
}
} else {
- Log.e(TAG,"Missing id while parsing configuration");
+ Log.e(TAG, "Missing id while parsing configuration");
}
}
+ } catch (EOFException ignore) {
} catch (IOException e) {
- Log.e(TAG, "Error parsing configuration");
+ Log.e(TAG, "Error parsing configuration" + e);
} finally {
if (in != null) {
try {
@@ -894,63 +952,140 @@
/* Compare current and new configuration and write to file on change */
private static void writeIpAndProxyConfigurationsOnChange(WifiConfiguration currentConfig,
WifiConfiguration newConfig) {
- boolean newNetwork = (newConfig.networkId == INVALID_NETWORK_ID);
- boolean writeConfigToFile = false;
+ boolean ipChanged = false;
+ boolean proxyChanged = false;
+ LinkProperties linkProperties = new LinkProperties();
- if (newConfig.ipAssignment != IpAssignment.UNASSIGNED) {
- if (newNetwork ||
- (currentConfig.ipAssignment != newConfig.ipAssignment) ||
- (currentConfig.ipConfig.ipAddress != newConfig.ipConfig.ipAddress) ||
- (currentConfig.ipConfig.gateway != newConfig.ipConfig.gateway) ||
- (currentConfig.ipConfig.netmask != newConfig.ipConfig.netmask) ||
- (currentConfig.ipConfig.dns1 != newConfig.ipConfig.dns1) ||
- (currentConfig.ipConfig.dns2 != newConfig.ipConfig.dns2)) {
- currentConfig.ipAssignment = newConfig.ipAssignment;
- currentConfig.ipConfig = newConfig.ipConfig;
- writeConfigToFile = true;
+ switch (newConfig.ipAssignment) {
+ case STATIC:
+ Collection<LinkAddress> currentLinkAddresses = currentConfig.linkProperties
+ .getLinkAddresses();
+ Collection<LinkAddress> newLinkAddresses = newConfig.linkProperties
+ .getLinkAddresses();
+ Collection<InetAddress> currentDnses = currentConfig.linkProperties.getDnses();
+ Collection<InetAddress> newDnses = newConfig.linkProperties.getDnses();
+ InetAddress currentGateway = currentConfig.linkProperties.getGateway();
+ InetAddress newGateway = newConfig.linkProperties.getGateway();
+
+ boolean linkAddressesDiffer = !currentLinkAddresses.containsAll(newLinkAddresses) ||
+ (currentLinkAddresses.size() != newLinkAddresses.size());
+ boolean dnsesDiffer = !currentDnses.containsAll(newDnses) ||
+ (currentDnses.size() != newDnses.size());
+ boolean gatewaysDiffer = (currentGateway == null) ||
+ !currentGateway.equals(newGateway);
+
+ if ((currentConfig.ipAssignment != newConfig.ipAssignment) ||
+ linkAddressesDiffer ||
+ dnsesDiffer ||
+ gatewaysDiffer) {
+ ipChanged = true;
+ }
+ break;
+ case DHCP:
+ if (currentConfig.ipAssignment != newConfig.ipAssignment) {
+ ipChanged = true;
+ }
+ break;
+ case UNASSIGNED:
+ /* Ignore */
+ break;
+ default:
+ Log.e(TAG, "Ignore invalid ip assignment during write");
+ break;
+ }
+
+ switch (newConfig.proxySettings) {
+ case STATIC:
+ InetSocketAddress newSockAddr = null;
+ String newExclusionList = null;
+ InetSocketAddress currentSockAddr = null;
+ String currentExclusionList = null;
+
+ ProxyProperties newHttpProxy = newConfig.linkProperties.getHttpProxy();
+ if (newHttpProxy != null) {
+ newSockAddr = newHttpProxy.getSocketAddress();
+ newExclusionList = newHttpProxy.getExclusionList();
+ }
+
+ ProxyProperties currentHttpProxy = currentConfig.linkProperties.getHttpProxy();
+ if (currentHttpProxy != null) {
+ currentSockAddr = currentHttpProxy.getSocketAddress();
+ currentExclusionList = currentHttpProxy.getExclusionList();
+ }
+
+ boolean socketAddressDiffers = false;
+ boolean exclusionListDiffers = false;
+
+ if (newSockAddr != null && currentSockAddr != null ) {
+ socketAddressDiffers = !currentSockAddr.equals(newSockAddr);
+ } else if (newSockAddr != null || currentSockAddr != null) {
+ socketAddressDiffers = true;
+ }
+
+ if (newExclusionList != null && currentExclusionList != null) {
+ exclusionListDiffers = !currentExclusionList.equals(newExclusionList);
+ } else if (newExclusionList != null || currentExclusionList != null) {
+ exclusionListDiffers = true;
+ }
+
+ if ((currentConfig.proxySettings != newConfig.proxySettings) ||
+ socketAddressDiffers ||
+ exclusionListDiffers) {
+ proxyChanged = true;
+ }
+ break;
+ case NONE:
+ if (currentConfig.proxySettings != newConfig.proxySettings) {
+ proxyChanged = true;
+ }
+ break;
+ case UNASSIGNED:
+ /* Ignore */
+ break;
+ default:
+ Log.e(TAG, "Ignore invalid proxy configuration during write");
+ break;
+ }
+
+ if (!ipChanged) {
+ addIpSettingsFromConfig(linkProperties, currentConfig);
+ } else {
+ currentConfig.ipAssignment = newConfig.ipAssignment;
+ addIpSettingsFromConfig(linkProperties, newConfig);
+ Log.d(TAG, "IP config changed SSID = " + currentConfig.SSID + " linkProperties: " +
+ linkProperties.toString());
+ }
+
+
+ if (!proxyChanged) {
+ linkProperties.setHttpProxy(currentConfig.linkProperties.getHttpProxy());
+ } else {
+ currentConfig.proxySettings = newConfig.proxySettings;
+ linkProperties.setHttpProxy(newConfig.linkProperties.getHttpProxy());
+ Log.d(TAG, "proxy changed SSID = " + currentConfig.SSID);
+ if (linkProperties.getHttpProxy() != null) {
+ Log.d(TAG, " proxyProperties: " + linkProperties.getHttpProxy().toString());
}
}
- if (newConfig.proxySettings != ProxySettings.UNASSIGNED) {
- InetSocketAddress newSockAddr = newConfig.proxyProperties.getSocketAddress();
- String newExclusionList = newConfig.proxyProperties.getExclusionList();
-
- InetSocketAddress currentSockAddr = currentConfig.proxyProperties.getSocketAddress();
- String currentExclusionList = currentConfig.proxyProperties.getExclusionList();
-
- boolean socketAddressDiffers = false;
- boolean exclusionListDiffers = false;
-
- if (newSockAddr != null && currentSockAddr != null ) {
- socketAddressDiffers = !currentSockAddr.equals(newSockAddr);
- } else if (newSockAddr != null || currentSockAddr != null) {
- socketAddressDiffers = true;
- }
-
- if (newExclusionList != null && currentExclusionList != null) {
- exclusionListDiffers = currentExclusionList.equals(newExclusionList);
- } else if (newExclusionList != null || currentExclusionList != null) {
- exclusionListDiffers = true;
- }
-
- if (newNetwork ||
- (currentConfig.proxySettings != newConfig.proxySettings) ||
- socketAddressDiffers ||
- exclusionListDiffers) {
- currentConfig.proxySettings = newConfig.proxySettings;
- currentConfig.proxyProperties = newConfig.proxyProperties;
- Log.d(TAG, "proxy change SSID = " + currentConfig.SSID + " proxyProperties: " +
- currentConfig.proxyProperties.toString());
- writeConfigToFile = true;
- }
- }
-
- if (writeConfigToFile) {
+ if (ipChanged || proxyChanged) {
+ currentConfig.linkProperties = linkProperties;
writeIpAndProxyConfigurations();
sendConfigChangeBroadcast();
}
}
+ private static void addIpSettingsFromConfig(LinkProperties linkProperties,
+ WifiConfiguration config) {
+ for (LinkAddress linkAddr : config.linkProperties.getLinkAddresses()) {
+ linkProperties.addLinkAddress(linkAddr);
+ }
+ linkProperties.setGateway(config.linkProperties.getGateway());
+ for (InetAddress dns : config.linkProperties.getDnses()) {
+ linkProperties.addDns(dns);
+ }
+ }
+
/**
* Read the variables from the supplicant daemon that are needed to
* fill in the WifiConfiguration object.
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index c4a1310..d5fb63e 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -16,8 +16,7 @@
package android.net.wifi;
-import android.net.DhcpInfo;
-import android.net.ProxyProperties;
+import android.net.LinkProperties;
import android.os.Parcelable;
import android.os.Parcel;
@@ -303,7 +302,7 @@
*/
public enum IpAssignment {
/* Use statically configured IP settings. Configuration can be accessed
- * with ipConfig */
+ * with linkProperties */
STATIC,
/* Use dynamically configured IP settigns */
DHCP,
@@ -315,10 +314,6 @@
* @hide
*/
public IpAssignment ipAssignment;
- /**
- * @hide
- */
- public DhcpInfo ipConfig;
/**
* @hide
@@ -328,7 +323,7 @@
* should be cleared. */
NONE,
/* Use statically configured proxy. Configuration can be accessed
- * with proxyProperties */
+ * with linkProperties */
STATIC,
/* no proxy details are assigned, this is used to indicate
* that any existing proxy settings should be retained */
@@ -341,7 +336,7 @@
/**
* @hide
*/
- public ProxyProperties proxyProperties;
+ public LinkProperties linkProperties;
public WifiConfiguration() {
networkId = INVALID_NETWORK_ID;
@@ -361,9 +356,8 @@
field.setValue(null);
}
ipAssignment = IpAssignment.UNASSIGNED;
- ipConfig = new DhcpInfo();
proxySettings = ProxySettings.UNASSIGNED;
- proxyProperties = new ProxyProperties();
+ linkProperties = new LinkProperties();
}
public String toString() {
@@ -445,17 +439,13 @@
if (value != null) sbuf.append(value);
}
sbuf.append('\n');
- if (ipAssignment == IpAssignment.STATIC) {
- sbuf.append(" ").append("Static IP configuration:").append('\n');
- sbuf.append(" ").append(ipConfig);
- }
- sbuf.append('\n');
+ sbuf.append("IP assignment: " + ipAssignment.toString());
+ sbuf.append("\n");
+ sbuf.append("Proxy settings: " + proxySettings.toString());
+ sbuf.append("\n");
+ sbuf.append(linkProperties.toString());
+ sbuf.append("\n");
- if (proxySettings == ProxySettings.STATIC) {
- sbuf.append(" ").append("Proxy configuration:").append('\n');
- sbuf.append(" ").append(proxyProperties);
- }
- sbuf.append('\n');
return sbuf.toString();
}
@@ -521,9 +511,8 @@
enterpriseFields[i].setValue(source.enterpriseFields[i].value());
}
ipAssignment = source.ipAssignment;
- ipConfig = new DhcpInfo(source.ipConfig);
proxySettings = source.proxySettings;
- proxyProperties = new ProxyProperties(source.proxyProperties);
+ linkProperties = new LinkProperties(source.linkProperties);
}
}
@@ -550,15 +539,8 @@
dest.writeString(field.value());
}
dest.writeString(ipAssignment.name());
- dest.writeInt(ipConfig.ipAddress);
- dest.writeInt(ipConfig.netmask);
- dest.writeInt(ipConfig.gateway);
- dest.writeInt(ipConfig.dns1);
- dest.writeInt(ipConfig.dns2);
- dest.writeInt(ipConfig.serverAddress);
- dest.writeInt(ipConfig.leaseDuration);
dest.writeString(proxySettings.name());
- dest.writeParcelable(proxyProperties, flags);
+ dest.writeParcelable(linkProperties, flags);
}
/** Implement the Parcelable interface {@hide} */
@@ -587,15 +569,8 @@
}
config.ipAssignment = IpAssignment.valueOf(in.readString());
- config.ipConfig.ipAddress = in.readInt();
- config.ipConfig.netmask = in.readInt();
- config.ipConfig.gateway = in.readInt();
- config.ipConfig.dns1 = in.readInt();
- config.ipConfig.dns2 = in.readInt();
- config.ipConfig.serverAddress = in.readInt();
- config.ipConfig.leaseDuration = in.readInt();
config.proxySettings = ProxySettings.valueOf(in.readString());
- config.proxyProperties = in.readParcelable(null);
+ config.linkProperties = in.readParcelable(null);
return config;
}
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 572abc0..efd0e0a 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -1253,25 +1253,22 @@
}
private void configureLinkProperties() {
-
+ if (WifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
+ mLinkProperties = WifiConfigStore.getLinkProperties(mLastNetworkId);
+ } else {
+ // TODO - fix this for v6
+ synchronized (mDhcpInfo) {
+ mLinkProperties.addLinkAddress(new LinkAddress(
+ NetworkUtils.intToInetAddress(mDhcpInfo.ipAddress),
+ NetworkUtils.intToInetAddress(mDhcpInfo.netmask)));
+ mLinkProperties.setGateway(NetworkUtils.intToInetAddress(mDhcpInfo.gateway));
+ mLinkProperties.addDns(NetworkUtils.intToInetAddress(mDhcpInfo.dns1));
+ mLinkProperties.addDns(NetworkUtils.intToInetAddress(mDhcpInfo.dns2));
+ }
+ mLinkProperties.setHttpProxy(WifiConfigStore.getProxyProperties(mLastNetworkId));
+ }
mLinkProperties.setInterfaceName(mInterfaceName);
-
- // TODO - fix this for v6
- synchronized (mDhcpInfo) {
- mLinkProperties.addLinkAddress(new LinkAddress(
- NetworkUtils.intToInetAddress(mDhcpInfo.ipAddress),
- NetworkUtils.intToInetAddress(mDhcpInfo.netmask)));
- mLinkProperties.setGateway(NetworkUtils.intToInetAddress(mDhcpInfo.gateway));
- mLinkProperties.addDns(NetworkUtils.intToInetAddress(mDhcpInfo.dns1));
- mLinkProperties.addDns(NetworkUtils.intToInetAddress(mDhcpInfo.dns2));
- }
-
- ProxyProperties proxyProperties = WifiConfigStore.getProxyProperties(mLastNetworkId);
- if (proxyProperties != null) {
- mLinkProperties.setHttpProxy(proxyProperties);
- Log.d(TAG, "netId=" + mLastNetworkId + " proxy configured: "
- + proxyProperties.toString());
- }
+ Log.d(TAG, "netId=" + mLastNetworkId + " Link configured: " + mLinkProperties.toString());
}
private int getMaxDhcpRetries() {
@@ -2571,7 +2568,6 @@
mLastSignalLevel = -1; // force update of signal strength
synchronized (mDhcpInfo) {
mWifiInfo.setIpAddress(mDhcpInfo.ipAddress);
- Log.d(TAG, "IP configuration: " + mDhcpInfo);
}
configureLinkProperties();
setDetailedState(DetailedState.CONNECTED);