diff options
Diffstat (limited to 'core')
410 files changed, 10826 insertions, 5344 deletions
diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java index 58eb66f..82c2159 100644 --- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java +++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java @@ -29,6 +29,7 @@ import android.os.UserManager; import android.text.TextUtils; import android.util.Log; import android.view.View; +import android.view.Window; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; @@ -127,6 +128,7 @@ public class ChooseTypeAndAccountActivity extends Activity private int mCallingUid; private String mCallingPackage; private boolean mDisallowAddAccounts; + private boolean mDontShowPicker; @Override public void onCreate(Bundle savedInstanceState) { @@ -189,11 +191,23 @@ public class ChooseTypeAndAccountActivity extends Activity mSetOfRelevantAccountTypes = getReleventAccountTypes(intent); mAlwaysPromptForAccount = intent.getBooleanExtra(EXTRA_ALWAYS_PROMPT_FOR_ACCOUNT, false); mDescriptionOverride = intent.getStringExtra(EXTRA_DESCRIPTION_TEXT_OVERRIDE); + + // Need to do this once here to request the window feature. Can't do it in onResume + mAccounts = getAcceptableAccountChoices(AccountManager.get(this)); + if (mAccounts.isEmpty() + && mDisallowAddAccounts) { + requestWindowFeature(Window.FEATURE_NO_TITLE); + setContentView(R.layout.app_not_authorized); + mDontShowPicker = true; + } } @Override protected void onResume() { super.onResume(); + + if (mDontShowPicker) return; + final AccountManager accountManager = AccountManager.get(this); mAccounts = getAcceptableAccountChoices(accountManager); @@ -206,11 +220,6 @@ public class ChooseTypeAndAccountActivity extends Activity // If there are no relevant accounts and only one relevant account type go directly to // add account. Otherwise let the user choose. if (mAccounts.isEmpty()) { - if (mDisallowAddAccounts) { - setContentView(R.layout.app_not_authorized); - setTitle(R.string.error_message_title); - return; - } if (mSetOfRelevantAccountTypes.size() == 1) { runAddAccountForAuthenticator(mSetOfRelevantAccountTypes.iterator().next()); } else { diff --git a/core/java/android/animation/ObjectAnimator.java b/core/java/android/animation/ObjectAnimator.java index 173ee73..9c88ccf 100644 --- a/core/java/android/animation/ObjectAnimator.java +++ b/core/java/android/animation/ObjectAnimator.java @@ -123,9 +123,37 @@ public final class ObjectAnimator extends ValueAnimator { * in a call to the function <code>setFoo()</code> on the target object. If either * <code>valueFrom</code> or <code>valueTo</code> is null, then a getter function will * also be derived and called. + * + * <p>If this animator was created with a {@link Property} object instead of the + * string name of a property, then this method will return the {@link + * Property#getName() name} of that Property object instead. If this animator was + * created with one or more {@link PropertyValuesHolder} objects, then this method + * will return the {@link PropertyValuesHolder#getPropertyName() name} of that + * object (if there was just one) or a comma-separated list of all of the + * names (if there are more than one).</p> */ public String getPropertyName() { - return mPropertyName; + String propertyName = null; + if (mPropertyName != null) { + propertyName = mPropertyName; + } else if (mProperty != null) { + propertyName = mProperty.getName(); + } else if (mValues != null && mValues.length > 0) { + for (int i = 0; i < mValues.length; ++i) { + if (i == 0) { + propertyName = ""; + } else { + propertyName += ","; + } + propertyName += mValues[i].getPropertyName(); + } + } + return propertyName; + } + + @Override + String getNameForTrace() { + return "animator:" + getPropertyName(); } /** diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java index cb44264..f8ae616 100644 --- a/core/java/android/animation/ValueAnimator.java +++ b/core/java/android/animation/ValueAnimator.java @@ -869,7 +869,7 @@ public class ValueAnimator extends Animator { * * <p>If this ValueAnimator has only one set of values being animated between, this evaluator * will be used for that set. If there are several sets of values being animated, which is - * the case if PropertyValuesHOlder objects were set on the ValueAnimator, then the evaluator + * the case if PropertyValuesHolder objects were set on the ValueAnimator, then the evaluator * is assigned just to the first PropertyValuesHolder object.</p> * * @param value the evaluator to be used this animation @@ -1024,7 +1024,7 @@ public class ValueAnimator extends Animator { mStarted = false; mStartListenersCalled = false; mPlayingBackwards = false; - Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, "animator", + Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, getNameForTrace(), System.identityHashCode(this)); } @@ -1033,7 +1033,7 @@ public class ValueAnimator extends Animator { * called on the UI thread. */ private void startAnimation(AnimationHandler handler) { - Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW, "animator", + Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW, getNameForTrace(), System.identityHashCode(this)); initAnimation(); handler.mAnimations.add(this); @@ -1045,6 +1045,14 @@ public class ValueAnimator extends Animator { } /** + * Returns the name of this animator for debugging purposes. + */ + String getNameForTrace() { + return "animator"; + } + + + /** * Internal function called to process an animation frame on an animation that is currently * sleeping through its <code>startDelay</code> phase. The return value indicates whether it * should be woken up and put on the active animations queue. diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 6b5df7f..7f2f744 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -1877,9 +1877,12 @@ public class Activity extends ContextThemeWrapper if (isChild() || !window.hasFeature(Window.FEATURE_ACTION_BAR) || mActionBar != null) { return; } - + mActionBar = new ActionBarImpl(this); mActionBar.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp); + + mWindow.setDefaultIcon(mActivityInfo.getIconResource()); + mWindow.setDefaultLogo(mActivityInfo.getLogoResource()); } /** diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index bb9e19f..63ac42e 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -31,9 +31,8 @@ import android.content.pm.UserInfo; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Point; -import android.hardware.display.DisplayManager; +import android.graphics.Rect; import android.hardware.display.DisplayManagerGlobal; -import android.os.Binder; import android.os.Bundle; import android.os.Debug; import android.os.Handler; @@ -453,14 +452,21 @@ public class ActivityManager { * Description of the task's last state. */ public CharSequence description; - + + /** + * The id of the ActivityStack this Task was on most recently. + */ + public int stackId; + public RecentTaskInfo() { } + @Override public int describeContents() { return 0; } + @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(id); dest.writeInt(persistentId); @@ -473,6 +479,7 @@ public class ActivityManager { ComponentName.writeToParcel(origActivity, dest); TextUtils.writeToParcel(description, dest, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); + dest.writeInt(stackId); } public void readFromParcel(Parcel source) { @@ -485,8 +492,9 @@ public class ActivityManager { } origActivity = ComponentName.readFromParcel(source); description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); + stackId = source.readInt(); } - + public static final Creator<RecentTaskInfo> CREATOR = new Creator<RecentTaskInfo>() { public RecentTaskInfo createFromParcel(Parcel source) { @@ -1229,7 +1237,169 @@ public class ActivityManager { } catch (RemoteException e) { } } - + + /** + * Information you can retrieve about the WindowManager StackBox hierarchy. + * @hide + */ + public static class StackBoxInfo implements Parcelable { + public int stackBoxId; + public float weight; + public boolean vertical; + public Rect bounds; + public StackBoxInfo[] children; + public int stackId; + public StackInfo stack; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(stackBoxId); + dest.writeFloat(weight); + dest.writeInt(vertical ? 1 : 0); + bounds.writeToParcel(dest, flags); + dest.writeInt(stackId); + if (children != null) { + children[0].writeToParcel(dest, flags); + children[1].writeToParcel(dest, flags); + } else { + stack.writeToParcel(dest, flags); + } + } + + public void readFromParcel(Parcel source) { + stackBoxId = source.readInt(); + weight = source.readFloat(); + vertical = source.readInt() == 1; + bounds = Rect.CREATOR.createFromParcel(source); + stackId = source.readInt(); + if (stackId == -1) { + children = new StackBoxInfo[2]; + children[0] = StackBoxInfo.CREATOR.createFromParcel(source); + children[1] = StackBoxInfo.CREATOR.createFromParcel(source); + } else { + stack = StackInfo.CREATOR.createFromParcel(source); + } + } + + public static final Creator<StackBoxInfo> CREATOR = + new Creator<ActivityManager.StackBoxInfo>() { + + @Override + public StackBoxInfo createFromParcel(Parcel source) { + return new StackBoxInfo(source); + } + + @Override + public StackBoxInfo[] newArray(int size) { + return new StackBoxInfo[size]; + } + }; + + public StackBoxInfo() { + } + + public StackBoxInfo(Parcel source) { + readFromParcel(source); + } + + public String toString(String prefix) { + StringBuilder sb = new StringBuilder(256); + sb.append(prefix); sb.append("Box id=" + stackBoxId); sb.append(" weight=" + weight); + sb.append(" vertical=" + vertical); sb.append(" bounds=" + bounds.toShortString()); + sb.append("\n"); + if (children != null) { + sb.append(prefix); sb.append("First child=\n"); + sb.append(children[0].toString(prefix + " ")); + sb.append(prefix); sb.append("Second child=\n"); + sb.append(children[1].toString(prefix + " ")); + } else { + sb.append(prefix); sb.append("Stack=\n"); + sb.append(stack.toString(prefix + " ")); + } + return sb.toString(); + } + + @Override + public String toString() { + return toString(""); + } + } + + /** + * Information you can retrieve about an ActivityStack in the system. + * @hide + */ + public static class StackInfo implements Parcelable { + public int stackId; + public Rect bounds; + public int[] taskIds; + public String[] taskNames; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(stackId); + dest.writeInt(bounds.left); + dest.writeInt(bounds.top); + dest.writeInt(bounds.right); + dest.writeInt(bounds.bottom); + dest.writeIntArray(taskIds); + dest.writeStringArray(taskNames); + } + + public void readFromParcel(Parcel source) { + stackId = source.readInt(); + bounds = new Rect( + source.readInt(), source.readInt(), source.readInt(), source.readInt()); + taskIds = source.createIntArray(); + taskNames = source.createStringArray(); + } + + public static final Creator<StackInfo> CREATOR = new Creator<StackInfo>() { + @Override + public StackInfo createFromParcel(Parcel source) { + return new StackInfo(source); + } + @Override + public StackInfo[] newArray(int size) { + return new StackInfo[size]; + } + }; + + public StackInfo() { + } + + private StackInfo(Parcel source) { + readFromParcel(source); + } + + public String toString(String prefix) { + StringBuilder sb = new StringBuilder(256); + sb.append(prefix); sb.append("Stack id="); sb.append(stackId); + sb.append(" bounds="); sb.append(bounds.toShortString()); sb.append("\n"); + prefix = prefix + " "; + for (int i = 0; i < taskIds.length; ++i) { + sb.append(prefix); sb.append("taskId="); sb.append(taskIds[i]); + sb.append(": "); sb.append(taskNames[i]); sb.append("\n"); + } + return sb.toString(); + } + + @Override + public String toString() { + return toString(""); + } + } + /** * @hide */ @@ -1303,10 +1473,12 @@ public class ActivityManager { public ProcessErrorStateInfo() { } + @Override public int describeContents() { return 0; } + @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(condition); dest.writeString(processName); @@ -1317,7 +1489,7 @@ public class ActivityManager { dest.writeString(longMsg); dest.writeString(stackTrace); } - + public void readFromParcel(Parcel source) { condition = source.readInt(); processName = source.readString(); diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index d4478bf..27e20b9 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -16,6 +16,7 @@ package android.app; +import android.app.ActivityManager.StackBoxInfo; import android.content.ComponentName; import android.content.IIntentReceiver; import android.content.IIntentSender; @@ -107,7 +108,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM public ActivityManagerNative() { attachInterface(this, descriptor); } - + + @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { switch (code) { @@ -197,7 +199,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM Intent intent = Intent.CREATOR.createFromParcel(data); String resolvedType = data.readString(); IBinder resultTo = data.readStrongBinder(); - String resultWho = data.readString(); + String resultWho = data.readString(); int requestCode = data.readInt(); int startFlags = data.readInt(); Configuration config = Configuration.CREATOR.createFromParcel(data); @@ -223,7 +225,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM } String resolvedType = data.readString(); IBinder resultTo = data.readStrongBinder(); - String resultWho = data.readString(); + String resultWho = data.readString(); int requestCode = data.readInt(); int flagsMask = data.readInt(); int flagsValues = data.readInt(); @@ -236,7 +238,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM reply.writeInt(result); return true; } - + case START_NEXT_MATCHING_ACTIVITY_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); @@ -267,7 +269,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM case FINISH_SUB_ACTIVITY_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); - String resultWho = data.readString(); + String resultWho = data.readString(); int requestCode = data.readInt(); finishSubActivity(token, resultWho, requestCode); reply.writeNoException(); @@ -478,14 +480,13 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM IThumbnailReceiver receiver = receiverBinder != null ? IThumbnailReceiver.Stub.asInterface(receiverBinder) : null; - List list = getTasks(maxNum, fl, receiver); + List<ActivityManager.RunningTaskInfo> list = getTasks(maxNum, fl, receiver); reply.writeNoException(); int N = list != null ? list.size() : -1; reply.writeInt(N); int i; for (i=0; i<N; i++) { - ActivityManager.RunningTaskInfo info = - (ActivityManager.RunningTaskInfo)list.get(i); + ActivityManager.RunningTaskInfo info = list.get(i); info.writeToParcel(reply, 0); } return true; @@ -535,14 +536,13 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM data.enforceInterface(IActivityManager.descriptor); int maxNum = data.readInt(); int fl = data.readInt(); - List list = getServices(maxNum, fl); + List<ActivityManager.RunningServiceInfo> list = getServices(maxNum, fl); reply.writeNoException(); int N = list != null ? list.size() : -1; reply.writeInt(N); int i; for (i=0; i<N; i++) { - ActivityManager.RunningServiceInfo info = - (ActivityManager.RunningServiceInfo)list.get(i); + ActivityManager.RunningServiceInfo info = list.get(i); info.writeToParcel(reply, 0); } return true; @@ -555,7 +555,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM reply.writeTypedList(list); return true; } - + case GET_RUNNING_APP_PROCESSES_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); List<ActivityManager.RunningAppProcessInfo> list = getRunningAppProcesses(); @@ -609,6 +609,53 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } + case CREATE_STACK_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + int taskId = data.readInt(); + int relativeStackId = data.readInt(); + int position = data.readInt(); + float weight = data.readFloat(); + int res = createStack(taskId, relativeStackId, position, weight); + reply.writeNoException(); + reply.writeInt(res); + return true; + } + + case MOVE_TASK_TO_STACK_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + int taskId = data.readInt(); + int stackId = data.readInt(); + boolean toTop = data.readInt() != 0; + moveTaskToStack(taskId, stackId, toTop); + reply.writeNoException(); + return true; + } + + case RESIZE_STACK_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + int stackBoxId = data.readInt(); + float weight = data.readFloat(); + resizeStackBox(stackBoxId, weight); + reply.writeNoException(); + return true; + } + + case GET_STACK_BOXES_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + List<StackBoxInfo> list = getStackBoxes(); + reply.writeNoException(); + reply.writeTypedList(list); + return true; + } + + case SET_FOCUSED_STACK_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + int stackId = data.readInt(); + setFocusedStack(stackId); + reply.writeNoException(); + return true; + } + case GET_TASK_FOR_ACTIVITY_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); @@ -1033,9 +1080,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM reply.writeInt(res); return true; } - + case CLEAR_APP_DATA_TRANSACTION: { - data.enforceInterface(IActivityManager.descriptor); + data.enforceInterface(IActivityManager.descriptor); String packageName = data.readString(); IPackageDataObserver observer = IPackageDataObserver.Stub.asInterface( data.readStrongBinder()); @@ -1045,7 +1092,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM reply.writeInt(res ? 1 : 0); return true; } - + case GRANT_URI_PERMISSION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); @@ -1057,7 +1104,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM reply.writeNoException(); return true; } - + case REVOKE_URI_PERMISSION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); @@ -1068,7 +1115,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM reply.writeNoException(); return true; } - + case SHOW_WAITING_FOR_DEBUGGER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); @@ -1257,7 +1304,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM reply.writeNoException(); return true; } - + case FORCE_STOP_PACKAGE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String packageName = data.readString(); @@ -1363,7 +1410,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM data.enforceInterface(IActivityManager.descriptor); String pkg = data.readString(); int appid = data.readInt(); - killApplicationWithAppId(pkg, appid); + String reason = data.readString(); + killApplicationWithAppId(pkg, appid, reason); reply.writeNoException(); return true; } @@ -2565,6 +2613,76 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); reply.recycle(); } + @Override + public int createStack(int taskId, int relativeStackBoxId, int position, float weight) + throws RemoteException + { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeInt(taskId); + data.writeInt(relativeStackBoxId); + data.writeInt(position); + data.writeFloat(weight); + mRemote.transact(CREATE_STACK_TRANSACTION, data, reply, 0); + reply.readException(); + int res = reply.readInt(); + data.recycle(); + reply.recycle(); + return res; + } + @Override + public void moveTaskToStack(int taskId, int stackId, boolean toTop) throws RemoteException + { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeInt(taskId); + data.writeInt(stackId); + data.writeInt(toTop ? 1 : 0); + mRemote.transact(MOVE_TASK_TO_STACK_TRANSACTION, data, reply, 0); + reply.readException(); + data.recycle(); + reply.recycle(); + } + @Override + public void resizeStackBox(int stackBoxId, float weight) throws RemoteException + { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeInt(stackBoxId); + data.writeFloat(weight); + mRemote.transact(RESIZE_STACK_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY); + reply.readException(); + data.recycle(); + reply.recycle(); + } + @Override + public List<StackBoxInfo> getStackBoxes() throws RemoteException + { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + mRemote.transact(GET_STACK_BOXES_TRANSACTION, data, reply, 0); + reply.readException(); + ArrayList<StackBoxInfo> list = reply.createTypedArrayList(StackBoxInfo.CREATOR); + data.recycle(); + reply.recycle(); + return list; + } + @Override + public void setFocusedStack(int stackId) throws RemoteException + { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeInt(stackId); + mRemote.transact(SET_FOCUSED_STACK_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY); + reply.readException(); + data.recycle(); + reply.recycle(); + } public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException { Parcel data = Parcel.obtain(); @@ -3575,12 +3693,14 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); } - public void killApplicationWithAppId(String pkg, int appid) throws RemoteException { + public void killApplicationWithAppId(String pkg, int appid, String reason) + throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeString(pkg); data.writeInt(appid); + data.writeString(reason); mRemote.transact(KILL_APPLICATION_WITH_APPID_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 4268fa6..4a41896 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -539,17 +539,17 @@ public final class ActivityThread { IBinder requestToken; int requestType; } - + private native void dumpGraphicsInfo(FileDescriptor fd); private class ApplicationThread extends ApplicationThreadNative { - private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s"; + private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s"; private static final String ONE_COUNT_COLUMN = "%21s %8d"; private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d"; private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s"; // Formatting for checkin service - update version if row format changes - private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 1; + private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 2; private void updatePendingConfiguration(Configuration config) { synchronized (mPackages) { @@ -895,17 +895,18 @@ public final class ActivityThread { @Override public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin, - boolean all, String[] args) { + boolean dumpInfo, boolean dumpDalvik, String[] args) { FileOutputStream fout = new FileOutputStream(fd); PrintWriter pw = new PrintWriter(fout); try { - return dumpMemInfo(pw, checkin, all); + return dumpMemInfo(pw, checkin, dumpInfo, dumpDalvik); } finally { pw.flush(); } } - private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, boolean checkin, boolean all) { + private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, boolean checkin, boolean dumpInfo, + boolean dumpDalvik) { long nativeMax = Debug.getNativeHeapSize() / 1024; long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024; long nativeFree = Debug.getNativeHeapFreeSize() / 1024; @@ -913,7 +914,7 @@ public final class ActivityThread { Debug.MemoryInfo memInfo = new Debug.MemoryInfo(); Debug.getMemoryInfo(memInfo); - if (!all) { + if (!dumpInfo) { return memInfo; } @@ -970,20 +971,42 @@ public final class ActivityThread { pw.print(memInfo.otherPss); pw.print(','); pw.print(memInfo.nativePss + memInfo.dalvikPss + memInfo.otherPss); pw.print(','); - // Heap info - shared + // Heap info - proportional set size + pw.print(memInfo.nativeSwappablePss); pw.print(','); + pw.print(memInfo.dalvikSwappablePss); pw.print(','); + pw.print(memInfo.otherSwappablePss); pw.print(','); + pw.print(memInfo.nativeSwappablePss + memInfo.dalvikSwappablePss + memInfo.otherSwappablePss); pw.print(','); + + // Heap info - shared dirty pw.print(memInfo.nativeSharedDirty); pw.print(','); pw.print(memInfo.dalvikSharedDirty); pw.print(','); pw.print(memInfo.otherSharedDirty); pw.print(','); pw.print(memInfo.nativeSharedDirty + memInfo.dalvikSharedDirty + memInfo.otherSharedDirty); pw.print(','); - // Heap info - private + // Heap info - shared clean + pw.print(memInfo.nativeSharedClean); pw.print(','); + pw.print(memInfo.dalvikSharedClean); pw.print(','); + pw.print(memInfo.otherSharedClean); pw.print(','); + pw.print(memInfo.nativeSharedClean + memInfo.dalvikSharedClean + + memInfo.otherSharedClean); pw.print(','); + + // Heap info - private Dirty pw.print(memInfo.nativePrivateDirty); pw.print(','); pw.print(memInfo.dalvikPrivateDirty); pw.print(','); pw.print(memInfo.otherPrivateDirty); pw.print(','); pw.print(memInfo.nativePrivateDirty + memInfo.dalvikPrivateDirty + memInfo.otherPrivateDirty); pw.print(','); + + // Heap info - private Clean + pw.print(memInfo.nativePrivateClean); pw.print(','); + pw.print(memInfo.dalvikPrivateClean); pw.print(','); + pw.print(memInfo.otherPrivateClean); pw.print(','); + pw.print(memInfo.nativePrivateClean + memInfo.dalvikPrivateClean + + memInfo.otherPrivateClean); pw.print(','); + + // Object counts pw.print(viewInstanceCount); pw.print(','); pw.print(viewRootInstanceCount); pw.print(','); @@ -1018,34 +1041,80 @@ public final class ActivityThread { } // otherwise, show human-readable format - printRow(pw, HEAP_COLUMN, "", "", "Shared", "Private", "Heap", "Heap", "Heap"); - printRow(pw, HEAP_COLUMN, "", "Pss", "Dirty", "Dirty", "Size", "Alloc", "Free"); + printRow(pw, HEAP_COLUMN, "", "Pss", "Pss","Shared", "Private", "Shared", "Private", + "Heap", "Heap", "Heap"); + printRow(pw, HEAP_COLUMN, "", "Total", "Clean", "Dirty", "Dirty", "Clean", "Clean", + "Size", "Alloc", "Free"); printRow(pw, HEAP_COLUMN, "", "------", "------", "------", "------", "------", - "------"); - printRow(pw, HEAP_COLUMN, "Native", memInfo.nativePss, memInfo.nativeSharedDirty, - memInfo.nativePrivateDirty, nativeMax, nativeAllocated, nativeFree); - printRow(pw, HEAP_COLUMN, "Dalvik", memInfo.dalvikPss, memInfo.dalvikSharedDirty, - memInfo.dalvikPrivateDirty, dalvikMax, dalvikAllocated, dalvikFree); + "------", "------", "------", "------"); + printRow(pw, HEAP_COLUMN, "Native Heap", memInfo.nativePss, memInfo.nativeSwappablePss, + memInfo.nativeSharedDirty, + memInfo.nativePrivateDirty, memInfo.nativeSharedClean, + memInfo.nativePrivateClean, nativeMax, nativeAllocated, nativeFree); + printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss, memInfo.dalvikSwappablePss, + memInfo.dalvikSharedDirty, + memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean, + memInfo.dalvikPrivateClean, dalvikMax, dalvikAllocated, dalvikFree); int otherPss = memInfo.otherPss; + int otherSwappablePss = memInfo.otherSwappablePss; int otherSharedDirty = memInfo.otherSharedDirty; int otherPrivateDirty = memInfo.otherPrivateDirty; + int otherSharedClean = memInfo.otherSharedClean; + int otherPrivateClean = memInfo.otherPrivateClean; for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) { - printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i), - memInfo.getOtherPss(i), memInfo.getOtherSharedDirty(i), - memInfo.getOtherPrivateDirty(i), "", "", ""); - otherPss -= memInfo.getOtherPss(i); - otherSharedDirty -= memInfo.getOtherSharedDirty(i); - otherPrivateDirty -= memInfo.getOtherPrivateDirty(i); + final int myPss = memInfo.getOtherPss(i); + final int mySwappablePss = memInfo.getOtherSwappablePss(i); + final int mySharedDirty = memInfo.getOtherSharedDirty(i); + final int myPrivateDirty = memInfo.getOtherPrivateDirty(i); + final int mySharedClean = memInfo.getOtherSharedClean(i); + final int myPrivateClean = memInfo.getOtherPrivateClean(i); + if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0 + || mySharedClean != 0 || myPrivateClean != 0) { + printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i), + myPss, mySwappablePss, mySharedDirty, myPrivateDirty, + mySharedClean, myPrivateClean, "", "", ""); + otherPss -= myPss; + otherSwappablePss -= mySwappablePss; + otherSharedDirty -= mySharedDirty; + otherPrivateDirty -= myPrivateDirty; + otherSharedClean -= mySharedClean; + otherPrivateClean -= myPrivateClean; + } } - printRow(pw, HEAP_COLUMN, "Unknown", otherPss, otherSharedDirty, - otherPrivateDirty, "", "", ""); + + + printRow(pw, HEAP_COLUMN, "Unknown", otherPss, otherSwappablePss, otherSharedDirty, + otherPrivateDirty, otherSharedClean, otherPrivateClean,"", "", ""); printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(), + memInfo.getTotalSwappablePss(), memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(), - nativeMax+dalvikMax, nativeAllocated+dalvikAllocated, - nativeFree+dalvikFree); + memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(), + nativeMax+dalvikMax, + nativeAllocated+dalvikAllocated, nativeFree+dalvikFree); + + if (dumpDalvik) { + pw.println(" "); + pw.println(" Dalvik Details"); + + for (int i=Debug.MemoryInfo.NUM_OTHER_STATS; + i<Debug.MemoryInfo.NUM_OTHER_STATS + Debug.MemoryInfo.NUM_DVK_STATS; i++) { + final int myPss = memInfo.getOtherPss(i); + final int mySwappablePss = memInfo.getOtherSwappablePss(i); + final int mySharedDirty = memInfo.getOtherSharedDirty(i); + final int myPrivateDirty = memInfo.getOtherPrivateDirty(i); + final int mySharedClean = memInfo.getOtherSharedClean(i); + final int myPrivateClean = memInfo.getOtherPrivateClean(i); + if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0 + || mySharedClean != 0 || myPrivateClean != 0) { + printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i), + myPss, mySwappablePss, mySharedDirty, myPrivateDirty, + mySharedClean, myPrivateClean, "", "", ""); + } + } + } pw.println(" "); pw.println(" Objects"); @@ -1748,7 +1817,7 @@ public final class ActivityThread { r.getAssets().close(); return existing; } - + // XXX need to remove entries when weak references go away mActiveResources.put(key, new WeakReference<Resources>(r)); return r; diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index c9776f1..32bb71e 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -95,8 +95,18 @@ public class AppOpsManager { public static final int OP_PLAY_AUDIO = 28; public static final int OP_READ_CLIPBOARD = 29; public static final int OP_WRITE_CLIPBOARD = 30; + public static final int OP_TAKE_MEDIA_BUTTONS = 31; + public static final int OP_TAKE_AUDIO_FOCUS = 32; + public static final int OP_AUDIO_MASTER_VOLUME = 33; + public static final int OP_AUDIO_VOICE_VOLUME = 34; + public static final int OP_AUDIO_RING_VOLUME = 35; + public static final int OP_AUDIO_MEDIA_VOLUME = 36; + public static final int OP_AUDIO_ALARM_VOLUME = 37; + public static final int OP_AUDIO_NOTIFICATION_VOLUME = 38; + public static final int OP_AUDIO_BLUETOOTH_VOLUME = 39; + public static final int OP_WAKE_LOCK = 40; /** @hide */ - public static final int _NUM_OP = 31; + public static final int _NUM_OP = 41; /** * This maps each operation to the operation that serves as the @@ -138,6 +148,16 @@ public class AppOpsManager { OP_PLAY_AUDIO, OP_READ_CLIPBOARD, OP_WRITE_CLIPBOARD, + OP_TAKE_MEDIA_BUTTONS, + OP_TAKE_AUDIO_FOCUS, + OP_AUDIO_MASTER_VOLUME, + OP_AUDIO_VOICE_VOLUME, + OP_AUDIO_RING_VOLUME, + OP_AUDIO_MEDIA_VOLUME, + OP_AUDIO_ALARM_VOLUME, + OP_AUDIO_NOTIFICATION_VOLUME, + OP_AUDIO_BLUETOOTH_VOLUME, + OP_WAKE_LOCK, }; /** @@ -176,6 +196,16 @@ public class AppOpsManager { "PLAY_AUDIO", "READ_CLIPBOARD", "WRITE_CLIPBOARD", + "TAKE_MEDIA_BUTTONS", + "TAKE_AUDIO_FOCUS", + "AUDIO_MASTER_VOLUME", + "AUDIO_VOICE_VOLUME", + "AUDIO_RING_VOLUME", + "AUDIO_MEDIA_VOLUME", + "AUDIO_ALARM_VOLUME", + "AUDIO_NOTIFICATION_VOLUME", + "AUDIO_BLUETOOTH_VOLUME", + "WAKE_LOCK", }; /** @@ -214,6 +244,16 @@ public class AppOpsManager { null, // no permission for playing audio null, // no permission for reading clipboard null, // no permission for writing clipboard + null, // no permission for taking media buttons + null, // no permission for taking audio focus + null, // no permission for changing master volume + null, // no permission for changing voice volume + null, // no permission for changing ring volume + null, // no permission for changing media volume + null, // no permission for changing alarm volume + null, // no permission for changing notification volume + null, // no permission for changing bluetooth volume + android.Manifest.permission.WAKE_LOCK, }; /** diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java index b1c58f2..e903447 100644 --- a/core/java/android/app/ApplicationThreadNative.java +++ b/core/java/android/app/ApplicationThreadNative.java @@ -524,12 +524,13 @@ public abstract class ApplicationThreadNative extends Binder data.enforceInterface(IApplicationThread.descriptor); ParcelFileDescriptor fd = data.readFileDescriptor(); boolean checkin = data.readInt() != 0; - boolean all = data.readInt() != 0; + boolean dumpInfo = data.readInt() != 0; + boolean dumpDalvik = data.readInt() != 0; String[] args = data.readStringArray(); Debug.MemoryInfo mi = null; if (fd != null) { try { - mi = dumpMemInfo(fd.getFileDescriptor(), checkin, all, args); + mi = dumpMemInfo(fd.getFileDescriptor(), checkin, dumpInfo, dumpDalvik, args); } finally { try { fd.close(); @@ -1159,14 +1160,15 @@ class ApplicationThreadProxy implements IApplicationThread { IBinder.FLAG_ONEWAY); } - public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin, boolean all, - String[] args) throws RemoteException { + public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin, boolean dumpInfo, + boolean dumpDalvik, String[] args) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeFileDescriptor(fd); data.writeInt(checkin ? 1 : 0); - data.writeInt(all ? 1 : 0); + data.writeInt(dumpInfo ? 1 : 0); + data.writeInt(dumpDalvik ? 1 : 0); data.writeStringArray(args); mRemote.transact(DUMP_MEM_INFO_TRANSACTION, data, reply, 0); reply.readException(); diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java index b3d99c5..634fa30 100644 --- a/core/java/android/app/Dialog.java +++ b/core/java/android/app/Dialog.java @@ -16,6 +16,8 @@ package android.app; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import com.android.internal.app.ActionBarImpl; import com.android.internal.policy.PolicyManager; @@ -264,6 +266,9 @@ public class Dialog implements DialogInterface, Window.Callback, mDecor = mWindow.getDecorView(); if (mActionBar == null && mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) { + final ApplicationInfo info = mContext.getApplicationInfo(); + mWindow.setDefaultIcon(info.icon); + mWindow.setDefaultLogo(info.logo); mActionBar = new ActionBarImpl(this); } diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index a21caee..b48eed2 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -16,6 +16,9 @@ package android.app; +import android.app.ActivityManager.RunningTaskInfo; +import android.app.ActivityManager.RunningServiceInfo; +import android.app.ActivityManager.StackBoxInfo; import android.content.ComponentName; import android.content.ContentProviderNative; import android.content.IContentProvider; @@ -99,19 +102,25 @@ public interface IActivityManager extends IInterface { public void activityDestroyed(IBinder token) throws RemoteException; public String getCallingPackage(IBinder token) throws RemoteException; public ComponentName getCallingActivity(IBinder token) throws RemoteException; - public List getTasks(int maxNum, int flags, + public List<RunningTaskInfo> getTasks(int maxNum, int flags, IThumbnailReceiver receiver) throws RemoteException; public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) throws RemoteException; public ActivityManager.TaskThumbnails getTaskThumbnails(int taskId) throws RemoteException; public Bitmap getTaskTopThumbnail(int taskId) throws RemoteException; - public List getServices(int maxNum, int flags) throws RemoteException; + public List<RunningServiceInfo> getServices(int maxNum, int flags) throws RemoteException; public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() throws RemoteException; public void moveTaskToFront(int task, int flags, Bundle options) throws RemoteException; public void moveTaskToBack(int task) throws RemoteException; public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) throws RemoteException; public void moveTaskBackwards(int task) throws RemoteException; + public int createStack(int taskId, int relativeStackBoxId, int position, float weight) + throws RemoteException; + public void moveTaskToStack(int taskId, int stackId, boolean toTop) throws RemoteException; + public void resizeStackBox(int stackBoxId, float weight) throws RemoteException; + public List<StackBoxInfo> getStackBoxes() throws RemoteException; + public void setFocusedStack(int stackId) throws RemoteException; public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException; /* oneway */ public void reportThumbnail(IBinder token, @@ -149,14 +158,14 @@ public interface IActivityManager extends IInterface { public void serviceDoneExecuting(IBinder token, int type, int startId, int res) throws RemoteException; public IBinder peekService(Intent service, String resolvedType) throws RemoteException; - + public boolean bindBackupAgent(ApplicationInfo appInfo, int backupRestoreMode) throws RemoteException; public void clearPendingBackup() throws RemoteException; public void backupAgentCreated(String packageName, IBinder agent) throws RemoteException; public void unbindBackupAgent(ApplicationInfo appInfo) throws RemoteException; public void killApplicationProcess(String processName, int uid) throws RemoteException; - + public boolean startInstrumentation(ComponentName className, String profileFile, int flags, Bundle arguments, IInstrumentationWatcher watcher, IUiAutomationConnection connection, int userId) throws RemoteException; @@ -168,7 +177,7 @@ public interface IActivityManager extends IInterface { public void setRequestedOrientation(IBinder token, int requestedOrientation) throws RemoteException; public int getRequestedOrientation(IBinder token) throws RemoteException; - + public ComponentName getActivityClassForToken(IBinder token) throws RemoteException; public String getPackageForToken(IBinder token) throws RemoteException; @@ -181,16 +190,16 @@ public interface IActivityManager extends IInterface { final IPackageDataObserver observer, int userId) throws RemoteException; public String getPackageForIntentSender(IIntentSender sender) throws RemoteException; public int getUidForIntentSender(IIntentSender sender) throws RemoteException; - + public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, boolean requireFull, String name, String callerPackage) throws RemoteException; public void setProcessLimit(int max) throws RemoteException; public int getProcessLimit() throws RemoteException; - + public void setProcessForeground(IBinder token, int pid, boolean isForeground) throws RemoteException; - + public int checkPermission(String permission, int pid, int uid) throws RemoteException; @@ -274,7 +283,8 @@ public interface IActivityManager extends IInterface { public void stopAppSwitches() throws RemoteException; public void resumeAppSwitches() throws RemoteException; - public void killApplicationWithAppId(String pkg, int appid) throws RemoteException; + public void killApplicationWithAppId(String pkg, int appid, String reason) + throws RemoteException; public void closeSystemDialogs(String reason) throws RemoteException; @@ -395,10 +405,12 @@ public interface IActivityManager extends IInterface { info = _info; } + @Override public int describeContents() { return 0; } + @Override public void writeToParcel(Parcel dest, int flags) { info.writeToParcel(dest, 0); if (provider != null) { @@ -412,10 +424,12 @@ public interface IActivityManager extends IInterface { public static final Parcelable.Creator<ContentProviderHolder> CREATOR = new Parcelable.Creator<ContentProviderHolder>() { + @Override public ContentProviderHolder createFromParcel(Parcel source) { return new ContentProviderHolder(source); } + @Override public ContentProviderHolder[] newArray(int size) { return new ContentProviderHolder[size]; } @@ -441,10 +455,12 @@ public interface IActivityManager extends IInterface { public WaitResult() { } + @Override public int describeContents() { return 0; } + @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(result); dest.writeInt(timeout ? 1 : 0); @@ -455,10 +471,12 @@ public interface IActivityManager extends IInterface { public static final Parcelable.Creator<WaitResult> CREATOR = new Parcelable.Creator<WaitResult>() { + @Override public WaitResult createFromParcel(Parcel source) { return new WaitResult(source); } + @Override public WaitResult[] newArray(int size) { return new WaitResult[size]; } @@ -641,4 +659,9 @@ public interface IActivityManager extends IInterface { int KILL_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+164; int SET_USER_IS_MONKEY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+165; int HANG_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+166; + int CREATE_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+167; + int MOVE_TASK_TO_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+168; + int RESIZE_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+169; + int GET_STACK_BOXES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+170; + int SET_FOCUSED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+171; } diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java index 3189b31..a009bd3 100644 --- a/core/java/android/app/IApplicationThread.java +++ b/core/java/android/app/IApplicationThread.java @@ -126,8 +126,8 @@ public interface IApplicationThread extends IInterface { void setCoreSettings(Bundle coreSettings) throws RemoteException; void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) throws RemoteException; void scheduleTrimMemory(int level) throws RemoteException; - Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin, boolean all, - String[] args) throws RemoteException; + Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin, boolean dumpInfo, + boolean dumpDalvik, String[] args) throws RemoteException; void dumpGfxInfo(FileDescriptor fd, String[] args) throws RemoteException; void dumpDbInfo(FileDescriptor fd, String[] args) throws RemoteException; void unstableProviderDied(IBinder provider) throws RemoteException; diff --git a/core/java/android/app/LoaderManager.java b/core/java/android/app/LoaderManager.java index 267555a..b13b24a 100644 --- a/core/java/android/app/LoaderManager.java +++ b/core/java/android/app/LoaderManager.java @@ -204,13 +204,13 @@ class LoaderManagerImpl extends LoaderManager { // These are the currently active loaders. A loader is here // from the time its load is started until it has been explicitly // stopped or restarted by the application. - final SparseArray<LoaderInfo> mLoaders = new SparseArray<LoaderInfo>(); + final SparseArray<LoaderInfo> mLoaders = new SparseArray<LoaderInfo>(0); // These are previously run loaders. This list is maintained internally // to avoid destroying a loader while an application is still using it. // It allows an application to restart a loader, but continue using its // previously run loader until the new loader's data is available. - final SparseArray<LoaderInfo> mInactiveLoaders = new SparseArray<LoaderInfo>(); + final SparseArray<LoaderInfo> mInactiveLoaders = new SparseArray<LoaderInfo>(0); final String mWho; diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java index c62bf32..3a355f9 100644 --- a/core/java/android/appwidget/AppWidgetHost.java +++ b/core/java/android/appwidget/AppWidgetHost.java @@ -198,7 +198,6 @@ public class AppWidgetHost { * @return a appWidgetId */ public int allocateAppWidgetId() { - try { if (mPackageName == null) { mPackageName = mContext.getPackageName(); @@ -211,20 +210,17 @@ public class AppWidgetHost { } /** - * Get a appWidgetId for a host in the calling process. + * Get a appWidgetId for a host in the given package. * * @return a appWidgetId * @hide */ - public static int allocateAppWidgetIdForSystem(int hostId, int userId) { + public static int allocateAppWidgetIdForPackage(int hostId, int userId, String packageName) { checkCallerIsSystem(); try { if (sService == null) { bindService(); } - Context systemContext = - (Context) ActivityThread.currentActivityThread().getSystemContext(); - String packageName = systemContext.getPackageName(); return sService.allocateAppWidgetId(packageName, hostId, userId); } catch (RemoteException e) { throw new RuntimeException("system server dead?", e); diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java index 0752df8..df3ec1a 100644 --- a/core/java/android/bluetooth/BluetoothGatt.java +++ b/core/java/android/bluetooth/BluetoothGatt.java @@ -167,7 +167,7 @@ public final class BluetoothGatt implements BluetoothProfile { try { mCallback.onConnectionStateChange(BluetoothGatt.this, status, profileState); } catch (Exception ex) { - Log.w(TAG, "Unhandled exception: " + ex); + Log.w(TAG, "Unhandled exception in callback", ex); } synchronized(mStateLock) { @@ -294,7 +294,7 @@ public final class BluetoothGatt implements BluetoothProfile { try { mCallback.onServicesDiscovered(BluetoothGatt.this, status); } catch (Exception ex) { - Log.w(TAG, "Unhandled exception: " + ex); + Log.w(TAG, "Unhandled exception in callback", ex); } } @@ -341,7 +341,7 @@ public final class BluetoothGatt implements BluetoothProfile { try { mCallback.onCharacteristicRead(BluetoothGatt.this, characteristic, status); } catch (Exception ex) { - Log.w(TAG, "Unhandled exception: " + ex); + Log.w(TAG, "Unhandled exception in callback", ex); } } @@ -387,7 +387,7 @@ public final class BluetoothGatt implements BluetoothProfile { try { mCallback.onCharacteristicWrite(BluetoothGatt.this, characteristic, status); } catch (Exception ex) { - Log.w(TAG, "Unhandled exception: " + ex); + Log.w(TAG, "Unhandled exception in callback", ex); } } @@ -418,7 +418,7 @@ public final class BluetoothGatt implements BluetoothProfile { try { mCallback.onCharacteristicChanged(BluetoothGatt.this, characteristic); } catch (Exception ex) { - Log.w(TAG, "Unhandled exception: " + ex); + Log.w(TAG, "Unhandled exception in callback", ex); } } @@ -467,7 +467,7 @@ public final class BluetoothGatt implements BluetoothProfile { try { mCallback.onDescriptorRead(BluetoothGatt.this, descriptor, status); } catch (Exception ex) { - Log.w(TAG, "Unhandled exception: " + ex); + Log.w(TAG, "Unhandled exception in callback", ex); } } @@ -515,7 +515,7 @@ public final class BluetoothGatt implements BluetoothProfile { try { mCallback.onDescriptorWrite(BluetoothGatt.this, descriptor, status); } catch (Exception ex) { - Log.w(TAG, "Unhandled exception: " + ex); + Log.w(TAG, "Unhandled exception in callback", ex); } } @@ -532,7 +532,7 @@ public final class BluetoothGatt implements BluetoothProfile { try { mCallback.onReliableWriteCompleted(BluetoothGatt.this, status); } catch (Exception ex) { - Log.w(TAG, "Unhandled exception: " + ex); + Log.w(TAG, "Unhandled exception in callback", ex); } } @@ -549,7 +549,7 @@ public final class BluetoothGatt implements BluetoothProfile { try { mCallback.onReadRemoteRssi(BluetoothGatt.this, rssi, status); } catch (Exception ex) { - Log.w(TAG, "Unhandled exception: " + ex); + Log.w(TAG, "Unhandled exception in callback", ex); } } }; diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java index 78d536b..58ee54f 100644 --- a/core/java/android/bluetooth/BluetoothGattServer.java +++ b/core/java/android/bluetooth/BluetoothGattServer.java @@ -108,7 +108,7 @@ public final class BluetoothGattServer implements BluetoothProfile { connected ? BluetoothProfile.STATE_CONNECTED : BluetoothProfile.STATE_DISCONNECTED); } catch (Exception ex) { - Log.w(TAG, "Unhandled exception: " + ex); + Log.w(TAG, "Unhandled exception in callback", ex); } } @@ -128,7 +128,7 @@ public final class BluetoothGattServer implements BluetoothProfile { try { mCallback.onServiceAdded((int)status, service); } catch (Exception ex) { - Log.w(TAG, "Unhandled exception: " + ex); + Log.w(TAG, "Unhandled exception in callback", ex); } } @@ -154,7 +154,7 @@ public final class BluetoothGattServer implements BluetoothProfile { try { mCallback.onCharacteristicReadRequest(device, transId, offset, characteristic); } catch (Exception ex) { - Log.w(TAG, "Unhandled exception: " + ex); + Log.w(TAG, "Unhandled exception in callback", ex); } } @@ -186,7 +186,7 @@ public final class BluetoothGattServer implements BluetoothProfile { try { mCallback.onDescriptorReadRequest(device, transId, offset, descriptor); } catch (Exception ex) { - Log.w(TAG, "Unhandled exception: " + ex); + Log.w(TAG, "Unhandled exception in callback", ex); } } @@ -214,7 +214,7 @@ public final class BluetoothGattServer implements BluetoothProfile { mCallback.onCharacteristicWriteRequest(device, transId, characteristic, isPrep, needRsp, offset, value); } catch (Exception ex) { - Log.w(TAG, "Unhandled exception: " + ex); + Log.w(TAG, "Unhandled exception in callback", ex); } } @@ -250,7 +250,7 @@ public final class BluetoothGattServer implements BluetoothProfile { mCallback.onDescriptorWriteRequest(device, transId, descriptor, isPrep, needRsp, offset, value); } catch (Exception ex) { - Log.w(TAG, "Unhandled exception: " + ex); + Log.w(TAG, "Unhandled exception in callback", ex); } } @@ -270,7 +270,7 @@ public final class BluetoothGattServer implements BluetoothProfile { try { mCallback.onExecuteWrite(device, transId, execWrite); } catch (Exception ex) { - Log.w(TAG, "Unhandled exception: " + ex); + Log.w(TAG, "Unhandled exception in callback", ex); } } }; diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java index 793d798..963e9fc 100644 --- a/core/java/android/bluetooth/BluetoothHeadset.java +++ b/core/java/android/bluetooth/BluetoothHeadset.java @@ -815,27 +815,6 @@ public final class BluetoothHeadset implements BluetoothProfile { } /** - * Notify Headset of phone roam state change. - * This is a backdoor for phone app to call BluetoothHeadset since - * there is currently not a good way to get roaming state change outside - * of phone app. - * - * @hide - */ - public void roamChanged(boolean roaming) { - if (mService != null && isEnabled()) { - try { - mService.roamChanged(roaming); - } catch (RemoteException e) { - Log.e(TAG, e.toString()); - } - } else { - Log.w(TAG, "Proxy not attached to service"); - if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable())); - } - } - - /** * Send Headset of CLCC response * * @hide diff --git a/core/java/android/bluetooth/IBluetoothHeadset.aidl b/core/java/android/bluetooth/IBluetoothHeadset.aidl index fc7627a..285eea7 100644..100755 --- a/core/java/android/bluetooth/IBluetoothHeadset.aidl +++ b/core/java/android/bluetooth/IBluetoothHeadset.aidl @@ -50,7 +50,6 @@ interface IBluetoothHeadset { boolean startScoUsingVirtualVoiceCall(in BluetoothDevice device); boolean stopScoUsingVirtualVoiceCall(in BluetoothDevice device); void phoneStateChanged(int numActive, int numHeld, int callState, String number, int type); - void roamChanged(boolean roam); void clccResponse(int index, int direction, int status, int mode, boolean mpty, String number, int type); } diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java index fefd343..b3f0d96 100644 --- a/core/java/android/content/ContentResolver.java +++ b/core/java/android/content/ContentResolver.java @@ -220,6 +220,7 @@ public abstract class ContentResolver { // Always log queries which take 500ms+; shorter queries are // sampled accordingly. + private static final boolean ENABLE_CONTENT_SAMPLE = false; private static final int SLOW_THRESHOLD_MILLIS = 500; private final Random mRandom = new Random(); // guarded by itself @@ -1832,6 +1833,7 @@ public abstract class ContentResolver { private void maybeLogQueryToEventLog(long durationMillis, Uri uri, String[] projection, String selection, String sortOrder) { + if (!ENABLE_CONTENT_SAMPLE) return; int samplePercent = samplePercentForDuration(durationMillis); if (samplePercent < 100) { synchronized (mRandom) { @@ -1871,6 +1873,7 @@ public abstract class ContentResolver { private void maybeLogUpdateToEventLog( long durationMillis, Uri uri, String operation, String selection) { + if (!ENABLE_CONTENT_SAMPLE) return; int samplePercent = samplePercentForDuration(durationMillis); if (samplePercent < 100) { synchronized (mRandom) { diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 5bd28b9..81d6f0b 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -2434,7 +2434,7 @@ public abstract class Context { * Remove all permissions to access a particular content provider Uri * that were previously added with {@link #grantUriPermission}. The given * Uri will match all previously granted Uris that are the same or a - * sub-path of the given Uri. That is, revoking "content://foo/one" will + * sub-path of the given Uri. That is, revoking "content://foo/target" will * revoke both "content://foo/target" and "content://foo/target/sub", but not * "content://foo". * diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index fc95728..897e6fe 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1165,13 +1165,12 @@ public class Intent implements Parcelable, Cloneable { * additional optional contextual information about where the user was when they requested * the voice assist. * Output: nothing. - * @hide */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_VOICE_ASSIST = "android.intent.action.VOICE_ASSIST"; /** - * An optional field on {@link #ACTION_ASSIST} + * An optional field on {@link #ACTION_ASSIST} and {@link #ACTION_VOICE_ASSIST} * containing the name of the current foreground application package at the time * the assist was invoked. */ @@ -1179,7 +1178,7 @@ public class Intent implements Parcelable, Cloneable { = "android.intent.extra.ASSIST_PACKAGE"; /** - * An optional field on {@link #ACTION_ASSIST} + * An optional field on {@link #ACTION_ASSIST} and {@link #ACTION_VOICE_ASSIST} * containing additional contextual information supplied by the current * foreground app at the time of the assist request. This is a {@link Bundle} of * additional data. @@ -2599,6 +2598,46 @@ public class Intent implements Parcelable, Cloneable { */ public static final String ACTION_GLOBAL_BUTTON = "android.intent.action.GLOBAL_BUTTON"; + /** + * Activity Action: Allow the user to select and open one or more existing + * documents. Both read and write access to the documents will be granted + * until explicitly revoked by the user. + * <p> + * Callers can restrict selection to a specific kind of data, such as + * photos, by setting one or more MIME types in {@link #EXTRA_MIME_TYPES}. + * <p> + * If the caller can handle multiple returned items (the user performing + * multiple selection), then it can specify {@link #EXTRA_ALLOW_MULTIPLE} to + * indicate this. + * <p> + * All returned URIs can be opened as a stream with + * {@link ContentResolver#openInputStream(Uri)}. + * <p> + * Output: The URI of the item that was picked. This must be a content: URI + * so that any receiver can access it. + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_OPEN_DOCUMENT = "android.intent.action.OPEN_DOCUMENT"; + + /** + * Activity Action: Allow the user to create a new document. Both read and + * write access to the document will be granted until explicitly revoked by + * the user. + * <p> + * Callers can provide a hint document name by setting {@link #EXTRA_TITLE}, + * but the user may change this value before creating the file. Callers can + * optionally hint at the MIME type being created by setting + * {@link #setType(String)}. + * <p> + * All returned URIs can be opened as a stream with + * {@link ContentResolver#openOutputStream(Uri)}. + * <p> + * Output: The URI of the item that was created. This must be a content: URI + * so that any receiver can access it. + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_CREATE_DOCUMENT = "android.intent.action.CREATE_DOCUMENT"; + // --------------------------------------------------------------------- // --------------------------------------------------------------------- // Standard intent categories (see addCategory()). @@ -3202,6 +3241,13 @@ public class Intent implements Parcelable, Cloneable { public static final String EXTRA_RESTRICTIONS_INTENT = "android.intent.extra.restrictions_intent"; + /** + * Extra used to communicate set of acceptable MIME types for + * {@link #ACTION_GET_CONTENT} or {@link #ACTION_OPEN_DOCUMENT}. The type of the + * extra is <code>ArrayList<String></code>. + */ + public static final String EXTRA_MIME_TYPES = "android.intent.extra.MIME_TYPES"; + // --------------------------------------------------------------------- // --------------------------------------------------------------------- // Intent flags (see mFlags variable). @@ -3251,6 +3297,15 @@ public class Intent implements Parcelable, Cloneable { public static final int FLAG_INCLUDE_STOPPED_PACKAGES = 0x00000020; /** + * When combined with {@link #FLAG_GRANT_READ_URI_PERMISSION} and/or + * {@link #FLAG_GRANT_WRITE_URI_PERMISSION}, the grant will be remembered + * until explicitly revoked with + * {@link Context#revokeUriPermission(Uri, int)}. These grants persist + * across device reboots. + */ + public static final int FLAG_PERSIST_GRANT_URI_PERMISSION = 0x00000040; + + /** * If set, the new activity is not kept in the history stack. As soon as * the user navigates away from it, the activity is finished. This may also * be set with the {@link android.R.styleable#AndroidManifestActivity_noHistory @@ -7039,7 +7094,8 @@ public class Intent implements Parcelable, Cloneable { // and flags to ourselves to grant. setClipData(target.getClipData()); addFlags(target.getFlags() - & (FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION)); + & (FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION + | FLAG_PERSIST_GRANT_URI_PERMISSION)); return true; } else { return false; diff --git a/core/java/android/content/UndoManager.java b/core/java/android/content/UndoManager.java new file mode 100644 index 0000000..1c2db47 --- /dev/null +++ b/core/java/android/content/UndoManager.java @@ -0,0 +1,932 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content; + +import android.os.Parcel; +import android.os.Parcelable; +import android.os.ParcelableParcel; +import android.text.TextUtils; + +import java.util.ArrayList; +import java.util.HashMap; + +/** + * Top-level class for managing and interacting with the global undo state for + * a document or application. This class supports both undo and redo and has + * helpers for merging undoable operations together as they are performed. + * + * <p>A single undoable operation is represented by {@link UndoOperation} which + * apps implement to define their undo/redo behavior. The UndoManager keeps + * a stack of undo states; each state can have one or more undo operations + * inside of it.</p> + * + * <p>Updates to the stack must be done inside of a {@link #beginUpdate}/{@link #endUpdate()} + * pair. During this time you can add new operations to the stack with + * {@link #addOperation}, retrieve and modify existing operations with + * {@link #getLastOperation}, control the label shown to the user for this operation + * with {@link #setUndoLabel} and {@link #suggestUndoLabel}, etc.</p> + * + * <p>Every {link UndoOperation} is associated with an {@link UndoOwner}, which identifies + * the data it belongs to. The owner is used to indicate how operations are dependent + * on each other -- operations with the same owner are dependent on others with the + * same owner. For example, you may have a document with multiple embedded objects. If the + * document itself and each embedded object use different owners, then you + * can provide undo semantics appropriate to the user's context: while within + * an embedded object, only edits to that object are seen and the user can + * undo/redo them without needing to impact edits in other objects; while + * within the larger document, all edits can be seen and the user must + * undo/redo them as a single stream.</p> + */ +public class UndoManager { + private final HashMap<String, UndoOwner> mOwners = new HashMap<String, UndoOwner>(); + private final ArrayList<UndoState> mUndos = new ArrayList<UndoState>(); + private final ArrayList<UndoState> mRedos = new ArrayList<UndoState>(); + private int mUpdateCount; + private int mHistorySize = 20; + private UndoState mWorking; + private int mCommitId = 1; + private boolean mInUndo; + private boolean mMerged; + + private int mStateSeq; + private int mNextSavedIdx; + private UndoOwner[] mStateOwners; + + /** + * Never merge with the last undo state. + */ + public static final int MERGE_MODE_NONE = 0; + + /** + * Allow merge with the last undo state only if it contains + * operations with the caller's owner. + */ + public static final int MERGE_MODE_UNIQUE = 1; + + /** + * Always allow merge with the last undo state, if possible. + */ + public static final int MERGE_MODE_ANY = 2; + + public UndoOwner getOwner(String tag, Object data) { + if (tag == null) { + throw new NullPointerException("tag can't be null"); + } + if (data == null) { + throw new NullPointerException("data can't be null"); + } + UndoOwner owner = mOwners.get(tag); + if (owner != null) { + if (owner.mData != data) { + if (owner.mData != null) { + throw new IllegalStateException("Owner " + owner + " already exists with data " + + owner.mData + " but giving different data " + data); + } + owner.mData = data; + } + return owner; + } + + owner = new UndoOwner(tag); + owner.mManager = this; + owner.mData = data; + mOwners.put(tag, owner); + return owner; + } + + void removeOwner(UndoOwner owner) { + // XXX need to figure out how to prune. + if (false) { + mOwners.remove(owner.mTag); + owner.mManager = null; + } + } + + /** + * Flatten the current undo state into a Parcelable object, which can later be restored + * with {@link #restoreInstanceState(android.os.Parcelable)}. + */ + public Parcelable saveInstanceState() { + if (mUpdateCount > 0) { + throw new IllegalStateException("Can't save state while updating"); + } + ParcelableParcel pp = new ParcelableParcel(getClass().getClassLoader()); + Parcel p = pp.getParcel(); + mStateSeq++; + if (mStateSeq <= 0) { + mStateSeq = 0; + } + mNextSavedIdx = 0; + p.writeInt(mHistorySize); + p.writeInt(mOwners.size()); + // XXX eventually we need to be smart here about limiting the + // number of undo states we write to not exceed X bytes. + int i = mUndos.size(); + while (i > 0) { + p.writeInt(1); + i--; + mUndos.get(i).writeToParcel(p); + } + i = mRedos.size(); + p.writeInt(i); + while (i > 0) { + p.writeInt(2); + i--; + mRedos.get(i).writeToParcel(p); + } + p.writeInt(0); + return pp; + } + + void saveOwner(UndoOwner owner, Parcel out) { + if (owner.mStateSeq == mStateSeq) { + out.writeInt(owner.mSavedIdx); + } else { + owner.mStateSeq = mStateSeq; + owner.mSavedIdx = mNextSavedIdx; + out.writeInt(owner.mSavedIdx); + out.writeString(owner.mTag); + mNextSavedIdx++; + } + } + + /** + * Restore an undo state previously created with {@link #saveInstanceState()}. This will + * restore the UndoManager's state to almost exactly what it was at the point it had + * been previously saved; the only information not restored is the data object + * associated with each {@link UndoOwner}, which requires separate calls to + * {@link #getOwner(String, Object)} to re-associate the owner with its data. + */ + public void restoreInstanceState(Parcelable state) { + if (mUpdateCount > 0) { + throw new IllegalStateException("Can't save state while updating"); + } + forgetUndos(null, -1); + forgetRedos(null, -1); + ParcelableParcel pp = (ParcelableParcel)state; + Parcel p = pp.getParcel(); + mHistorySize = p.readInt(); + mStateOwners = new UndoOwner[p.readInt()]; + + int stype; + while ((stype=p.readInt()) != 0) { + UndoState ustate = new UndoState(this, p, pp.getClassLoader()); + if (stype == 1) { + mUndos.add(0, ustate); + } else { + mRedos.add(0, ustate); + } + } + } + + UndoOwner restoreOwner(Parcel in) { + int idx = in.readInt(); + UndoOwner owner = mStateOwners[idx]; + if (owner == null) { + String tag = in.readString(); + owner = new UndoOwner(tag); + mStateOwners[idx] = owner; + mOwners.put(tag, owner); + } + return owner; + } + + /** + * Set the maximum number of undo states that will be retained. + */ + public void setHistorySize(int size) { + mHistorySize = size; + if (mHistorySize >= 0 && countUndos(null) > mHistorySize) { + forgetUndos(null, countUndos(null) - mHistorySize); + } + } + + /** + * Return the current maximum number of undo states. + */ + public int getHistorySize() { + return mHistorySize; + } + + /** + * Perform undo of last/top <var>count</var> undo states. The states impacted + * by this can be limited through <var>owners</var>. + * @param owners Optional set of owners that should be impacted. If null, all + * undo states will be visible and available for undo. If non-null, only those + * states that contain one of the owners specified here will be visible. + * @param count Number of undo states to pop. + * @return Returns the number of undo states that were actually popped. + */ + public int undo(UndoOwner[] owners, int count) { + if (mWorking != null) { + throw new IllegalStateException("Can't be called during an update"); + } + + int num = 0; + int i = -1; + + mInUndo = true; + + UndoState us = getTopUndo(null); + if (us != null) { + us.makeExecuted(); + } + + while (count > 0 && (i=findPrevState(mUndos, owners, i)) >= 0) { + UndoState state = mUndos.remove(i); + state.undo(); + mRedos.add(state); + count--; + num++; + } + + mInUndo = false; + + return num; + } + + /** + * Perform redo of last/top <var>count</var> undo states in the transient redo stack. + * The states impacted by this can be limited through <var>owners</var>. + * @param owners Optional set of owners that should be impacted. If null, all + * undo states will be visible and available for undo. If non-null, only those + * states that contain one of the owners specified here will be visible. + * @param count Number of undo states to pop. + * @return Returns the number of undo states that were actually redone. + */ + public int redo(UndoOwner[] owners, int count) { + if (mWorking != null) { + throw new IllegalStateException("Can't be called during an update"); + } + + int num = 0; + int i = -1; + + mInUndo = true; + + while (count > 0 && (i=findPrevState(mRedos, owners, i)) >= 0) { + UndoState state = mRedos.remove(i); + state.redo(); + mUndos.add(state); + count--; + num++; + } + + mInUndo = false; + + return num; + } + + /** + * Returns true if we are currently inside of an undo/redo operation. This is + * useful for editors to know whether they should be generating new undo state + * when they see edit operations happening. + */ + public boolean isInUndo() { + return mInUndo; + } + + public int forgetUndos(UndoOwner[] owners, int count) { + if (count < 0) { + count = mUndos.size(); + } + + int removed = 0; + for (int i=0; i<mUndos.size() && removed < count; i++) { + UndoState state = mUndos.get(i); + if (count > 0 && matchOwners(state, owners)) { + state.destroy(); + mUndos.remove(i); + removed++; + } + } + + return removed; + } + + public int forgetRedos(UndoOwner[] owners, int count) { + if (count < 0) { + count = mRedos.size(); + } + + int removed = 0; + for (int i=0; i<mRedos.size() && removed < count; i++) { + UndoState state = mRedos.get(i); + if (count > 0 && matchOwners(state, owners)) { + state.destroy(); + mRedos.remove(i); + removed++; + } + } + + return removed; + } + + /** + * Return the number of undo states on the undo stack. + * @param owners If non-null, only those states containing an operation with one of + * the owners supplied here will be counted. + */ + public int countUndos(UndoOwner[] owners) { + if (owners == null) { + return mUndos.size(); + } + + int count=0; + int i=0; + while ((i=findNextState(mUndos, owners, i)) >= 0) { + count++; + i++; + } + return count; + } + + /** + * Return the number of redo states on the undo stack. + * @param owners If non-null, only those states containing an operation with one of + * the owners supplied here will be counted. + */ + public int countRedos(UndoOwner[] owners) { + if (owners == null) { + return mRedos.size(); + } + + int count=0; + int i=0; + while ((i=findNextState(mRedos, owners, i)) >= 0) { + count++; + i++; + } + return count; + } + + /** + * Return the user-visible label for the top undo state on the stack. + * @param owners If non-null, will select the top-most undo state containing an + * operation with one of the owners supplied here. + */ + public CharSequence getUndoLabel(UndoOwner[] owners) { + UndoState state = getTopUndo(owners); + return state != null ? state.getLabel() : null; + } + + /** + * Return the user-visible label for the top redo state on the stack. + * @param owners If non-null, will select the top-most undo state containing an + * operation with one of the owners supplied here. + */ + public CharSequence getRedoLabel(UndoOwner[] owners) { + UndoState state = getTopRedo(owners); + return state != null ? state.getLabel() : null; + } + + /** + * Start creating a new undo state. Multiple calls to this function will nest until + * they are all matched by a later call to {@link #endUpdate}. + * @param label Optional user-visible label for this new undo state. + */ + public void beginUpdate(CharSequence label) { + if (mInUndo) { + throw new IllegalStateException("Can't being update while performing undo/redo"); + } + if (mUpdateCount <= 0) { + createWorkingState(); + mMerged = false; + mUpdateCount = 0; + } + + mWorking.updateLabel(label); + mUpdateCount++; + } + + private void createWorkingState() { + mWorking = new UndoState(this, mCommitId++); + if (mCommitId < 0) { + mCommitId = 1; + } + } + + /** + * Returns true if currently inside of a {@link #beginUpdate}. + */ + public boolean isInUpdate() { + return mUpdateCount > 0; + } + + /** + * Forcibly set a new for the new undo state being built within a {@link #beginUpdate}. + * Any existing label will be replaced with this one. + */ + public void setUndoLabel(CharSequence label) { + if (mWorking == null) { + throw new IllegalStateException("Must be called during an update"); + } + mWorking.setLabel(label); + } + + /** + * Set a new for the new undo state being built within a {@link #beginUpdate}, but + * only if there is not a label currently set for it. + */ + public void suggestUndoLabel(CharSequence label) { + if (mWorking == null) { + throw new IllegalStateException("Must be called during an update"); + } + mWorking.updateLabel(label); + } + + /** + * Return the number of times {@link #beginUpdate} has been called without a matching + * {@link #endUpdate} call. + */ + public int getUpdateNestingLevel() { + return mUpdateCount; + } + + /** + * Check whether there is an {@link UndoOperation} in the current {@link #beginUpdate} + * undo state. + * @param owner Optional owner of the operation to look for. If null, will succeed + * if there is any operation; if non-null, will only succeed if there is an operation + * with the given owner. + * @return Returns true if there is a matching operation in the current undo state. + */ + public boolean hasOperation(UndoOwner owner) { + if (mWorking == null) { + throw new IllegalStateException("Must be called during an update"); + } + return mWorking.hasOperation(owner); + } + + /** + * Return the most recent {@link UndoOperation} that was added to the update. + * @param mergeMode May be either {@link #MERGE_MODE_NONE} or {@link #MERGE_MODE_ANY}. + */ + public UndoOperation<?> getLastOperation(int mergeMode) { + return getLastOperation(null, null, mergeMode); + } + + /** + * Return the most recent {@link UndoOperation} that was added to the update and + * has the given owner. + * @param owner Optional owner of last operation to retrieve. If null, the last + * operation regardless of owner will be retrieved; if non-null, the last operation + * matching the given owner will be retrieved. + * @param mergeMode May be either {@link #MERGE_MODE_NONE}, {@link #MERGE_MODE_UNIQUE}, + * or {@link #MERGE_MODE_ANY}. + */ + public UndoOperation<?> getLastOperation(UndoOwner owner, int mergeMode) { + return getLastOperation(null, owner, mergeMode); + } + + /** + * Return the most recent {@link UndoOperation} that was added to the update and + * has the given owner. + * @param clazz Optional class of the last operation to retrieve. If null, the + * last operation regardless of class will be retrieved; if non-null, the last + * operation whose class is the same as the given class will be retrieved. + * @param owner Optional owner of last operation to retrieve. If null, the last + * operation regardless of owner will be retrieved; if non-null, the last operation + * matching the given owner will be retrieved. + * @param mergeMode May be either {@link #MERGE_MODE_NONE}, {@link #MERGE_MODE_UNIQUE}, + * or {@link #MERGE_MODE_ANY}. + */ + public <T extends UndoOperation> T getLastOperation(Class<T> clazz, UndoOwner owner, + int mergeMode) { + if (mWorking == null) { + throw new IllegalStateException("Must be called during an update"); + } + if (mergeMode != MERGE_MODE_NONE && !mMerged && !mWorking.hasData()) { + UndoState state = getTopUndo(null); + UndoOperation<?> last; + if (state != null && (mergeMode == MERGE_MODE_ANY || !state.hasMultipleOwners()) + && state.canMerge() && (last=state.getLastOperation(clazz, owner)) != null) { + if (last.allowMerge()) { + mWorking.destroy(); + mWorking = state; + mUndos.remove(state); + mMerged = true; + return (T)last; + } + } + } + + return mWorking.getLastOperation(clazz, owner); + } + + /** + * Add a new UndoOperation to the current update. + * @param op The new operation to add. + * @param mergeMode May be either {@link #MERGE_MODE_NONE}, {@link #MERGE_MODE_UNIQUE}, + * or {@link #MERGE_MODE_ANY}. + */ + public void addOperation(UndoOperation<?> op, int mergeMode) { + if (mWorking == null) { + throw new IllegalStateException("Must be called during an update"); + } + UndoOwner owner = op.getOwner(); + if (owner.mManager != this) { + throw new IllegalArgumentException( + "Given operation's owner is not in this undo manager."); + } + if (mergeMode != MERGE_MODE_NONE && !mMerged && !mWorking.hasData()) { + UndoState state = getTopUndo(null); + if (state != null && (mergeMode == MERGE_MODE_ANY || !state.hasMultipleOwners()) + && state.canMerge() && state.hasOperation(op.getOwner())) { + mWorking.destroy(); + mWorking = state; + mUndos.remove(state); + mMerged = true; + } + } + mWorking.addOperation(op); + } + + /** + * Finish the creation of an undo state, matching a previous call to + * {@link #beginUpdate}. + */ + public void endUpdate() { + if (mWorking == null) { + throw new IllegalStateException("Must be called during an update"); + } + mUpdateCount--; + + if (mUpdateCount == 0) { + pushWorkingState(); + } + } + + private void pushWorkingState() { + int N = mUndos.size() + 1; + + if (mWorking.hasData()) { + mUndos.add(mWorking); + forgetRedos(null, -1); + mWorking.commit(); + if (N >= 2) { + // The state before this one can no longer be merged, ever. + // The only way to get back to it is for the user to perform + // an undo. + mUndos.get(N-2).makeExecuted(); + } + } else { + mWorking.destroy(); + } + mWorking = null; + + if (mHistorySize >= 0 && N > mHistorySize) { + forgetUndos(null, N - mHistorySize); + } + } + + /** + * Commit the last finished undo state. This undo state can no longer be + * modified with further {@link #MERGE_MODE_UNIQUE} or + * {@link #MERGE_MODE_ANY} merge modes. If called while inside of an update, + * this will push any changes in the current update on to the undo stack + * and result with a fresh undo state, behaving as if {@link #endUpdate()} + * had been called enough to unwind the current update, then the last state + * committed, and {@link #beginUpdate} called to restore the update nesting. + * @param owner The optional owner to determine whether to perform the commit. + * If this is non-null, the commit will only execute if the current top undo + * state contains an operation with the given owner. + * @return Returns an integer identifier for the committed undo state, which + * can later be used to try to uncommit the state to perform further edits on it. + */ + public int commitState(UndoOwner owner) { + if (mWorking != null && mWorking.hasData()) { + if (owner == null || mWorking.hasOperation(owner)) { + mWorking.setCanMerge(false); + int commitId = mWorking.getCommitId(); + pushWorkingState(); + createWorkingState(); + mMerged = true; + return commitId; + } + } else { + UndoState state = getTopUndo(null); + if (state != null && (owner == null || state.hasOperation(owner))) { + state.setCanMerge(false); + return state.getCommitId(); + } + } + return -1; + } + + /** + * Attempt to undo a previous call to {@link #commitState}. This will work + * if the undo state at the top of the stack has the given id, and has not been + * involved in an undo operation. Otherwise false is returned. + * @param commitId The identifier for the state to be uncommitted, as returned + * by {@link #commitState}. + * @param owner Optional owner that must appear in the committed state. + * @return Returns true if the uncommit is successful, else false. + */ + public boolean uncommitState(int commitId, UndoOwner owner) { + if (mWorking != null && mWorking.getCommitId() == commitId) { + if (owner == null || mWorking.hasOperation(owner)) { + return mWorking.setCanMerge(true); + } + } else { + UndoState state = getTopUndo(null); + if (state != null && (owner == null || state.hasOperation(owner))) { + if (state.getCommitId() == commitId) { + return state.setCanMerge(true); + } + } + } + return false; + } + + UndoState getTopUndo(UndoOwner[] owners) { + if (mUndos.size() <= 0) { + return null; + } + int i = findPrevState(mUndos, owners, -1); + return i >= 0 ? mUndos.get(i) : null; + } + + UndoState getTopRedo(UndoOwner[] owners) { + if (mRedos.size() <= 0) { + return null; + } + int i = findPrevState(mRedos, owners, -1); + return i >= 0 ? mRedos.get(i) : null; + } + + boolean matchOwners(UndoState state, UndoOwner[] owners) { + if (owners == null) { + return true; + } + for (int i=0; i<owners.length; i++) { + if (state.matchOwner(owners[i])) { + return true; + } + } + return false; + } + + int findPrevState(ArrayList<UndoState> states, UndoOwner[] owners, int from) { + final int N = states.size(); + + if (from == -1) { + from = N-1; + } + if (from >= N) { + return -1; + } + if (owners == null) { + return from; + } + + while (from >= 0) { + UndoState state = states.get(from); + if (matchOwners(state, owners)) { + return from; + } + from--; + } + + return -1; + } + + int findNextState(ArrayList<UndoState> states, UndoOwner[] owners, int from) { + final int N = states.size(); + + if (from < 0) { + from = 0; + } + if (from >= N) { + return -1; + } + if (owners == null) { + return from; + } + + while (from < N) { + UndoState state = states.get(from); + if (matchOwners(state, owners)) { + return from; + } + from++; + } + + return -1; + } + + final static class UndoState { + private final UndoManager mManager; + private final int mCommitId; + private final ArrayList<UndoOperation<?>> mOperations = new ArrayList<UndoOperation<?>>(); + private ArrayList<UndoOperation<?>> mRecent; + private CharSequence mLabel; + private boolean mCanMerge = true; + private boolean mExecuted; + + UndoState(UndoManager manager, int commitId) { + mManager = manager; + mCommitId = commitId; + } + + UndoState(UndoManager manager, Parcel p, ClassLoader loader) { + mManager = manager; + mCommitId = p.readInt(); + mCanMerge = p.readInt() != 0; + mExecuted = p.readInt() != 0; + mLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p); + final int N = p.readInt(); + for (int i=0; i<N; i++) { + UndoOwner owner = mManager.restoreOwner(p); + UndoOperation op = (UndoOperation)p.readParcelable(loader); + op.mOwner = owner; + mOperations.add(op); + } + } + + void writeToParcel(Parcel p) { + if (mRecent != null) { + throw new IllegalStateException("Can't save state before committing"); + } + p.writeInt(mCommitId); + p.writeInt(mCanMerge ? 1 : 0); + p.writeInt(mExecuted ? 1 : 0); + TextUtils.writeToParcel(mLabel, p, 0); + final int N = mOperations.size(); + p.writeInt(N); + for (int i=0; i<N; i++) { + UndoOperation op = mOperations.get(i); + mManager.saveOwner(op.mOwner, p); + p.writeParcelable(op, 0); + } + } + + int getCommitId() { + return mCommitId; + } + + void setLabel(CharSequence label) { + mLabel = label; + } + + void updateLabel(CharSequence label) { + if (mLabel != null) { + mLabel = label; + } + } + + CharSequence getLabel() { + return mLabel; + } + + boolean setCanMerge(boolean state) { + // Don't allow re-enabling of merging if state has been executed. + if (state && mExecuted) { + return false; + } + mCanMerge = state; + return true; + } + + void makeExecuted() { + mExecuted = true; + } + + boolean canMerge() { + return mCanMerge && !mExecuted; + } + + int countOperations() { + return mOperations.size(); + } + + boolean hasOperation(UndoOwner owner) { + final int N = mOperations.size(); + if (owner == null) { + return N != 0; + } + for (int i=0; i<N; i++) { + if (mOperations.get(i).getOwner() == owner) { + return true; + } + } + return false; + } + + boolean hasMultipleOwners() { + final int N = mOperations.size(); + if (N <= 1) { + return false; + } + UndoOwner owner = mOperations.get(0).getOwner(); + for (int i=1; i<N; i++) { + if (mOperations.get(i).getOwner() != owner) { + return true; + } + } + return false; + } + + void addOperation(UndoOperation<?> op) { + if (mOperations.contains(op)) { + throw new IllegalStateException("Already holds " + op); + } + mOperations.add(op); + if (mRecent == null) { + mRecent = new ArrayList<UndoOperation<?>>(); + mRecent.add(op); + } + op.mOwner.mOpCount++; + } + + <T extends UndoOperation> T getLastOperation(Class<T> clazz, UndoOwner owner) { + final int N = mOperations.size(); + if (clazz == null && owner == null) { + return N > 0 ? (T)mOperations.get(N-1) : null; + } + // First look for the top-most operation with the same owner. + for (int i=N-1; i>=0; i--) { + UndoOperation<?> op = mOperations.get(i); + if (owner != null && op.getOwner() != owner) { + continue; + } + // Return this operation if it has the same class that the caller wants. + // Note that we don't search deeper for the class, because we don't want + // to end up with a different order of operations for the same owner. + if (clazz != null && op.getClass() != clazz) { + return null; + } + return (T)op; + } + + return null; + } + + boolean matchOwner(UndoOwner owner) { + for (int i=mOperations.size()-1; i>=0; i--) { + if (mOperations.get(i).matchOwner(owner)) { + return true; + } + } + return false; + } + + boolean hasData() { + for (int i=mOperations.size()-1; i>=0; i--) { + if (mOperations.get(i).hasData()) { + return true; + } + } + return false; + } + + void commit() { + final int N = mRecent != null ? mRecent.size() : 0; + for (int i=0; i<N; i++) { + mRecent.get(i).commit(); + } + mRecent = null; + } + + void undo() { + for (int i=mOperations.size()-1; i>=0; i--) { + mOperations.get(i).undo(); + } + } + + void redo() { + final int N = mOperations.size(); + for (int i=0; i<N; i++) { + mOperations.get(i).redo(); + } + } + + void destroy() { + for (int i=mOperations.size()-1; i>=0; i--) { + UndoOwner owner = mOperations.get(i).mOwner; + owner.mOpCount--; + if (owner.mOpCount <= 0) { + if (owner.mOpCount < 0) { + throw new IllegalStateException("Underflow of op count on owner " + owner + + " in op " + mOperations.get(i)); + } + mManager.removeOwner(owner); + } + } + } + } +} diff --git a/core/java/android/content/UndoOperation.java b/core/java/android/content/UndoOperation.java new file mode 100644 index 0000000..8084b1f --- /dev/null +++ b/core/java/android/content/UndoOperation.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * A single undoable operation. You must subclass this to implement the state + * and behavior for your operation. Instances of this class are placed and + * managed in an {@link UndoManager}. + */ +public abstract class UndoOperation<DATA> implements Parcelable { + UndoOwner mOwner; + + /** + * Create a new instance of the operation. + * @param owner Who owns the data being modified by this undo state; must be + * returned by {@link UndoManager#getOwner(String, Object) UndoManager.getOwner}. + */ + public UndoOperation(UndoOwner owner) { + mOwner = owner; + } + + /** + * Construct from a Parcel. + */ + protected UndoOperation(Parcel src, ClassLoader loader) { + } + + /** + * Owning object as given to {@link #UndoOperation(UndoOwner)}. + */ + public UndoOwner getOwner() { + return mOwner; + } + + /** + * Synonym for {@link #getOwner()}.{@link android.content.UndoOwner#getData()}. + */ + public DATA getOwnerData() { + return (DATA)mOwner.getData(); + } + + /** + * Return true if this undo operation is a member of the given owner. + * The default implementation is <code>owner == getOwner()</code>. You + * can override this to provide more sophisticated dependencies between + * owners. + */ + public boolean matchOwner(UndoOwner owner) { + return owner == getOwner(); + } + + /** + * Return true if this operation actually contains modification data. The + * default implementation always returns true. If you return false, the + * operation will be dropped when the final undo state is being built. + */ + public boolean hasData() { + return true; + } + + /** + * Return true if this operation can be merged with a later operation. + * The default implementation always returns true. + */ + public boolean allowMerge() { + return true; + } + + /** + * Called when this undo state is being committed to the undo stack. + * The implementation should perform the initial edits and save any state that + * may be needed to undo them. + */ + public abstract void commit(); + + /** + * Called when this undo state is being popped off the undo stack (in to + * the temporary redo stack). The implementation should remove the original + * edits and thus restore the target object to its prior value. + */ + public abstract void undo(); + + /** + * Called when this undo state is being pushed back from the transient + * redo stack to the main undo stack. The implementation should re-apply + * the edits that were previously removed by {@link #undo}. + */ + public abstract void redo(); + + public int describeContents() { + return 0; + } +} diff --git a/core/java/android/content/UndoOwner.java b/core/java/android/content/UndoOwner.java new file mode 100644 index 0000000..a279de6 --- /dev/null +++ b/core/java/android/content/UndoOwner.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content; + +/** + * Representation of an owner of {@link UndoOperation} objects in an {@link UndoManager}. + */ +public class UndoOwner { + final String mTag; + + UndoManager mManager; + Object mData; + int mOpCount; + + // For saving/restoring state. + int mStateSeq; + int mSavedIdx; + + UndoOwner(String tag) { + mTag = tag; + } + + /** + * Return the unique tag name identifying this owner. This is the tag + * supplied to {@link UndoManager#getOwner(String, Object) UndoManager.getOwner} + * and is immutable. + */ + public String getTag() { + return mTag; + } + + /** + * Return the actual data object of the owner. This is the data object + * supplied to {@link UndoManager#getOwner(String, Object) UndoManager.getOwner}. An + * owner may have a null data if it was restored from a previously saved state with + * no getOwner call to associate it with its data. + */ + public Object getData() { + return mData; + } +} diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java index 2812477..4dbcf23 100644 --- a/core/java/android/content/pm/ComponentInfo.java +++ b/core/java/android/content/pm/ComponentInfo.java @@ -116,6 +116,17 @@ public class ComponentInfo extends PackageItemInfo { public final int getIconResource() { return icon != 0 ? icon : applicationInfo.icon; } + + /** + * Return the logo resource identifier to use for this component. If + * the component defines a logo, that is used; else, the application + * logo is used. + * + * @return The logo associated with this component. + */ + public final int getLogoResource() { + return logo != 0 ? logo : applicationInfo.logo; + } protected void dumpFront(Printer pw, String prefix) { super.dumpFront(pw, prefix); diff --git a/core/java/android/content/pm/KeySet.java b/core/java/android/content/pm/KeySet.java new file mode 100644 index 0000000..0ef09a4 --- /dev/null +++ b/core/java/android/content/pm/KeySet.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content.pm; + +import android.os.Binder; + +/** @hide */ +public class KeySet { + + private Binder token; + + /** @hide */ + public KeySet(Binder token) { + this.token = token; + } + + Binder getToken() { + return token; + } +}
\ No newline at end of file diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 34e0c12..1b997f0 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -45,14 +45,20 @@ import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateFactory; +import java.security.cert.CertPath; +import java.security.cert.X509Certificate; import java.security.spec.EncodedKeySpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import java.util.ArrayList; import java.util.Enumeration; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.zip.ZipEntry; @@ -714,6 +720,13 @@ public class PackageParser { mParseError = PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES; return false; } + + // Add the signing KeySet to the system + pkg.mSigningKeys = new HashSet<PublicKey>(); + for (int i=0; i < certs.length; i++) { + pkg.mSigningKeys.add(certs[i].getPublicKey()); + } + } catch (CertificateEncodingException e) { Slog.w(TAG, "Exception reading " + mArchiveSourcePath, e); mParseError = PackageManager.INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING; @@ -1027,6 +1040,10 @@ public class PackageParser { if (!parseApplication(pkg, res, parser, attrs, flags, outError)) { return null; } + } else if (tagName.equals("keys")) { + if (!parseKeys(pkg, res, parser, attrs, outError)) { + return null; + } } else if (tagName.equals("permission-group")) { if (parsePermissionGroup(pkg, flags, res, parser, attrs, outError) == null) { return null; @@ -1519,7 +1536,71 @@ public class PackageParser { } return buildCompoundName(pkg, procSeq, "taskAffinity", outError); } - + + private boolean parseKeys(Package owner, Resources res, + XmlPullParser parser, AttributeSet attrs, String[] outError) + throws XmlPullParserException, IOException { + // we've encountered the 'keys' tag + // all the keys and keysets that we want must be defined here + // so we're going to iterate over the parser and pull out the things we want + int outerDepth = parser.getDepth(); + + int type; + PublicKey currentKey = null; + Map<PublicKey, Set<String>> definedKeySets = new HashMap<PublicKey, Set<String>>(); + while ((type = parser.next()) != XmlPullParser.END_DOCUMENT + && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { + if (type == XmlPullParser.END_TAG) { + continue; + } + String tagname = parser.getName(); + if (tagname.equals("publicKey")) { + final TypedArray sa = res.obtainAttributes(attrs, + com.android.internal.R.styleable.PublicKey); + final String encodedKey = sa.getNonResourceString( + com.android.internal.R.styleable.PublicKey_value); + currentKey = parsePublicKey(encodedKey); + definedKeySets.put(currentKey, new HashSet<String>()); + sa.recycle(); + } else if (tagname.equals("keyset")) { + final TypedArray sa = res.obtainAttributes(attrs, + com.android.internal.R.styleable.KeySet); + final String name = sa.getNonResourceString( + com.android.internal.R.styleable.KeySet_name); + definedKeySets.get(currentKey).add(name); + sa.recycle(); + } else if (RIGID_PARSER) { + Slog.w(TAG, "Bad element under <keys>: " + parser.getName() + + " at " + mArchiveSourcePath + " " + + parser.getPositionDescription()); + return false; + } else { + Slog.w(TAG, "Unknown element under <keys>: " + parser.getName() + + " at " + mArchiveSourcePath + " " + + parser.getPositionDescription()); + XmlUtils.skipCurrentTag(parser); + continue; + } + } + + owner.mKeySetMapping = new HashMap<String, Set<PublicKey>>(); + for (Map.Entry<PublicKey, Set<String>> e : definedKeySets.entrySet()) { + PublicKey key = e.getKey(); + Set<String> keySetNames = e.getValue(); + for (String alias : keySetNames) { + if (owner.mKeySetMapping.containsKey(alias)) { + owner.mKeySetMapping.get(alias).add(key); + } else { + Set<PublicKey> keys = new HashSet<PublicKey>(); + keys.add(key); + owner.mKeySetMapping.put(alias, keys); + } + } + } + + return true; + } + private PermissionGroup parsePermissionGroup(Package owner, int flags, Resources res, XmlPullParser parser, AttributeSet attrs, String[] outError) throws XmlPullParserException, IOException { @@ -3083,20 +3164,28 @@ public class PackageParser { Slog.i(TAG, "verifier " + packageName + " public key was null; skipping"); } + PublicKey publicKey = parsePublicKey(encodedPublicKey); + if (publicKey != null) { + return new VerifierInfo(packageName, publicKey); + } + + return null; + } + + public static final PublicKey parsePublicKey(String encodedPublicKey) { EncodedKeySpec keySpec; try { final byte[] encoded = Base64.decode(encodedPublicKey, Base64.DEFAULT); keySpec = new X509EncodedKeySpec(encoded); } catch (IllegalArgumentException e) { - Slog.i(TAG, "Could not parse verifier " + packageName + " public key; invalid Base64"); + Slog.i(TAG, "Could not parse verifier public key; invalid Base64"); return null; } /* First try the key as an RSA key. */ try { final KeyFactory keyFactory = KeyFactory.getInstance("RSA"); - final PublicKey publicKey = keyFactory.generatePublic(keySpec); - return new VerifierInfo(packageName, publicKey); + return keyFactory.generatePublic(keySpec); } catch (NoSuchAlgorithmException e) { Log.wtf(TAG, "Could not parse public key because RSA isn't included in build"); return null; @@ -3107,8 +3196,7 @@ public class PackageParser { /* Now try it as a DSA key. */ try { final KeyFactory keyFactory = KeyFactory.getInstance("DSA"); - final PublicKey publicKey = keyFactory.generatePublic(keySpec); - return new VerifierInfo(packageName, publicKey); + return keyFactory.generatePublic(keySpec); } catch (NoSuchAlgorithmException e) { Log.wtf(TAG, "Could not parse public key because DSA isn't included in build"); return null; @@ -3360,6 +3448,12 @@ public class PackageParser { */ public ManifestDigest manifestDigest; + /** + * Data used to feed the KeySetManager + */ + public Set<PublicKey> mSigningKeys; + public Map<String, Set<PublicKey>> mKeySetMapping; + public Package(String _name) { packageName = _name; applicationInfo.packageName = _name; diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java index 288d55f..875e8de 100644 --- a/core/java/android/content/pm/RegisteredServicesCache.java +++ b/core/java/android/content/pm/RegisteredServicesCache.java @@ -82,7 +82,7 @@ public abstract class RegisteredServicesCache<V> { @GuardedBy("mServicesLock") private boolean mPersistentServicesFileDidNotExist; @GuardedBy("mServicesLock") - private final SparseArray<UserServices<V>> mUserServices = new SparseArray<UserServices<V>>(); + private final SparseArray<UserServices<V>> mUserServices = new SparseArray<UserServices<V>>(2); private static class UserServices<V> { @GuardedBy("mServicesLock") diff --git a/core/java/android/content/pm/ResolveInfo.java b/core/java/android/content/pm/ResolveInfo.java index 07117fe..de8e256 100644 --- a/core/java/android/content/pm/ResolveInfo.java +++ b/core/java/android/content/pm/ResolveInfo.java @@ -328,6 +328,7 @@ public class ResolveInfo implements Parcelable { implements Comparator<ResolveInfo> { public DisplayNameComparator(PackageManager pm) { mPM = pm; + mCollator.setStrength(Collator.PRIMARY); } public final int compare(ResolveInfo a, ResolveInfo b) { @@ -336,10 +337,10 @@ public class ResolveInfo implements Parcelable { CharSequence sb = b.loadLabel(mPM); if (sb == null) sb = b.activityInfo.name; - return sCollator.compare(sa.toString(), sb.toString()); + return mCollator.compare(sa.toString(), sb.toString()); } - private final Collator sCollator = Collator.getInstance(); + private final Collator mCollator = Collator.getInstance(); private PackageManager mPM; } } diff --git a/core/java/android/content/res/AssetFileDescriptor.java b/core/java/android/content/res/AssetFileDescriptor.java index 7d46710..e4cc77f 100644 --- a/core/java/android/content/res/AssetFileDescriptor.java +++ b/core/java/android/content/res/AssetFileDescriptor.java @@ -20,6 +20,7 @@ import android.os.Parcel; import android.os.ParcelFileDescriptor; import android.os.Parcelable; +import java.io.Closeable; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -30,7 +31,7 @@ import java.io.IOException; * opened FileDescriptor that can be used to read the data, as well as the * offset and length of that entry's data in the file. */ -public class AssetFileDescriptor implements Parcelable { +public class AssetFileDescriptor implements Parcelable, Closeable { /** * Length used with {@link #AssetFileDescriptor(ParcelFileDescriptor, long, long)} * and {@link #getDeclaredLength} when a length has not been declared. This means @@ -122,6 +123,7 @@ public class AssetFileDescriptor implements Parcelable { /** * Convenience for calling <code>getParcelFileDescriptor().close()</code>. */ + @Override public void close() throws IOException { mFd.close(); } diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index 42f4faf..cff974d 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -16,8 +16,6 @@ package android.content.res; -import android.os.Trace; -import android.view.View; import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParser; @@ -30,6 +28,7 @@ import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable.ConstantState; import android.os.Build; import android.os.Bundle; +import android.os.Trace; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; @@ -100,11 +99,11 @@ public class Resources { /*package*/ final Configuration mTmpConfig = new Configuration(); /*package*/ TypedValue mTmpValue = new TypedValue(); /*package*/ final LongSparseArray<WeakReference<Drawable.ConstantState> > mDrawableCache - = new LongSparseArray<WeakReference<Drawable.ConstantState> >(); + = new LongSparseArray<WeakReference<Drawable.ConstantState> >(0); /*package*/ final LongSparseArray<WeakReference<ColorStateList> > mColorStateListCache - = new LongSparseArray<WeakReference<ColorStateList> >(); + = new LongSparseArray<WeakReference<ColorStateList> >(0); /*package*/ final LongSparseArray<WeakReference<Drawable.ConstantState> > mColorDrawableCache - = new LongSparseArray<WeakReference<Drawable.ConstantState> >(); + = new LongSparseArray<WeakReference<Drawable.ConstantState> >(0); /*package*/ boolean mPreloading; /*package*/ TypedArray mCachedStyledAttributes = null; @@ -1985,6 +1984,13 @@ public class Resources { } } + /** + * @hide + */ + public LongSparseArray<Drawable.ConstantState> getPreloadedDrawables() { + return sPreloadedDrawables[0]; + } + private boolean verifyPreloadConfig(int changingConfigurations, int allowVarying, int resourceId, String name) { // We allow preloading of resources even if they vary by font scale (which diff --git a/core/java/android/database/AbstractCursor.java b/core/java/android/database/AbstractCursor.java index 300b4d1..b5b89dd 100644 --- a/core/java/android/database/AbstractCursor.java +++ b/core/java/android/database/AbstractCursor.java @@ -369,7 +369,9 @@ public abstract class AbstractCursor implements CrossProcessCursor { } public Uri getNotificationUri() { - return mNotifyUri; + synchronized (mSelfObserverLock) { + return mNotifyUri; + } } public boolean getWantsAllOnMoveCalls() { diff --git a/core/java/android/database/Cursor.java b/core/java/android/database/Cursor.java index 907833d..7381e2c 100644 --- a/core/java/android/database/Cursor.java +++ b/core/java/android/database/Cursor.java @@ -425,6 +425,16 @@ public interface Cursor extends Closeable { void setNotificationUri(ContentResolver cr, Uri uri); /** + * Return the URI at which notifications of changes in this Cursor's data + * will be delivered, as previously set by {@link #setNotificationUri}. + * @return Returns a URI that can be used with + * {@link ContentResolver#registerContentObserver(android.net.Uri, boolean, ContentObserver) + * ContentResolver.registerContentObserver} to find out about changes to this Cursor's + * data. May be null if no notification URI has been set. + */ + Uri getNotificationUri(); + + /** * onMove() will only be called across processes if this method returns true. * @return whether all cursor movement should result in a call to onMove(). */ diff --git a/core/java/android/database/CursorWrapper.java b/core/java/android/database/CursorWrapper.java index 7baeb8c..d8fcb17 100644 --- a/core/java/android/database/CursorWrapper.java +++ b/core/java/android/database/CursorWrapper.java @@ -194,6 +194,10 @@ public class CursorWrapper implements Cursor { mCursor.setNotificationUri(cr, uri); } + public Uri getNotificationUri() { + return mCursor.getNotificationUri(); + } + public void unregisterContentObserver(ContentObserver observer) { mCursor.unregisterContentObserver(observer); } diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java index 4e51080..ac42b76 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -31,6 +31,11 @@ import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; +import android.renderscript.Allocation; +import android.renderscript.Element; +import android.renderscript.RenderScript; +import android.renderscript.RSIllegalArgumentException; +import android.renderscript.Type; import android.util.Log; import android.text.TextUtils; import android.view.Surface; @@ -152,6 +157,7 @@ public class Camera { private PictureCallback mRawImageCallback; private PictureCallback mJpegCallback; private PreviewCallback mPreviewCallback; + private boolean mUsingPreviewAllocation; private PictureCallback mPostviewCallback; private AutoFocusCallback mAutoFocusCallback; private AutoFocusMoveCallback mAutoFocusMoveCallback; @@ -327,6 +333,7 @@ public class Camera { mJpegCallback = null; mPreviewCallback = null; mPostviewCallback = null; + mUsingPreviewAllocation = false; mZoomListener = null; Looper looper; @@ -587,6 +594,9 @@ public class Camera { mPreviewCallback = cb; mOneShot = false; mWithBuffer = false; + if (cb != null) { + mUsingPreviewAllocation = false; + } // Always use one-shot mode. We fake camera preview mode by // doing one-shot preview continuously. setHasPreviewCallback(cb != null, false); @@ -610,6 +620,9 @@ public class Camera { mPreviewCallback = cb; mOneShot = true; mWithBuffer = false; + if (cb != null) { + mUsingPreviewAllocation = false; + } setHasPreviewCallback(cb != null, false); } @@ -645,6 +658,9 @@ public class Camera { mPreviewCallback = cb; mOneShot = false; mWithBuffer = true; + if (cb != null) { + mUsingPreviewAllocation = false; + } setHasPreviewCallback(cb != null, true); } @@ -744,6 +760,134 @@ public class Camera { private native final void _addCallbackBuffer( byte[] callbackBuffer, int msgType); + /** + * <p>Create a {@link android.renderscript RenderScript} + * {@link android.renderscript.Allocation Allocation} to use as a + * destination of preview callback frames. Use + * {@link #setPreviewCallbackAllocation setPreviewCallbackAllocation} to use + * the created Allocation as a destination for camera preview frames.</p> + * + * <p>The Allocation will be created with a YUV type, and its contents must + * be accessed within Renderscript with the {@code rsGetElementAtYuv_*} + * accessor methods. Its size will be based on the current + * {@link Parameters#getPreviewSize preview size} configured for this + * camera.</p> + * + * @param rs the RenderScript context for this Allocation. + * @param usage additional usage flags to set for the Allocation. The usage + * flag {@link android.renderscript.Allocation#USAGE_IO_INPUT} will always + * be set on the created Allocation, but additional flags may be provided + * here. + * @return a new YUV-type Allocation with dimensions equal to the current + * preview size. + * @throws RSIllegalArgumentException if the usage flags are not compatible + * with an YUV Allocation. + * @see #setPreviewCallbackAllocation + * @hide + */ + public final Allocation createPreviewAllocation(RenderScript rs, int usage) + throws RSIllegalArgumentException { + Parameters p = getParameters(); + Size previewSize = p.getPreviewSize(); + Type.Builder yuvBuilder = new Type.Builder(rs, + Element.createPixel(rs, + Element.DataType.UNSIGNED_8, + Element.DataKind.PIXEL_YUV)); + // Use YV12 for wide compatibility. Changing this requires also + // adjusting camera service's format selection. + yuvBuilder.setYuvFormat(ImageFormat.YV12); + yuvBuilder.setX(previewSize.width); + yuvBuilder.setY(previewSize.height); + + Allocation a = Allocation.createTyped(rs, yuvBuilder.create(), + usage | Allocation.USAGE_IO_INPUT); + + return a; + } + + /** + * <p>Set an {@link android.renderscript.Allocation Allocation} as the + * target of preview callback data. Use this method for efficient processing + * of camera preview data with RenderScript. The Allocation must be created + * with the {@link #createPreviewAllocation createPreviewAllocation } + * method.</p> + * + * <p>Setting a preview allocation will disable any active preview callbacks + * set by {@link #setPreviewCallback setPreviewCallback} or + * {@link #setPreviewCallbackWithBuffer setPreviewCallbackWithBuffer}, and + * vice versa. Using a preview allocation still requires an active standard + * preview target to be set, either with + * {@link #setPreviewTexture setPreviewTexture} or + * {@link #setPreviewDisplay setPreviewDisplay}.</p> + * + * <p>To be notified when new frames are available to the Allocation, use + * {@link android.renderscript.Allocation#setIoInputNotificationHandler Allocation.setIoInputNotificationHandler}. To + * update the frame currently accessible from the Allocation to the latest + * preview frame, call + * {@link android.renderscript.Allocation#ioReceive Allocation.ioReceive}.</p> + * + * <p>To disable preview into the Allocation, call this method with a + * {@code null} parameter.</p> + * + * <p>Once a preview allocation is set, the preview size set by + * {@link Parameters#setPreviewSize setPreviewSize} cannot be changed. If + * you wish to change the preview size, first remove the preview allocation + * by calling {@code setPreviewCallbackAllocation(null)}, then change the + * preview size, create a new preview Allocation with + * {@link #createPreviewAllocation createPreviewAllocation}, and set it as + * the new preview callback allocation target.</p> + * + * <p>If you are using the preview data to create video or still images, + * strongly consider using {@link android.media.MediaActionSound} to + * properly indicate image capture or recording start/stop to the user.</p> + * + * @param previewAllocation the allocation to use as destination for preview + * @throws IOException if configuring the camera to use the Allocation for + * preview fails. + * @throws IllegalArgumentException if the Allocation's dimensions or other + * parameters don't meet the requirements. + * @see #createPreviewAllocation + * @see #setPreviewCallback + * @see #setPreviewCallbackWithBuffer + * @hide + */ + public final void setPreviewCallbackAllocation(Allocation previewAllocation) + throws IOException { + Surface previewSurface = null; + if (previewAllocation != null) { + Parameters p = getParameters(); + Size previewSize = p.getPreviewSize(); + if (previewSize.width != previewAllocation.getType().getX() || + previewSize.height != previewAllocation.getType().getY()) { + throw new IllegalArgumentException( + "Allocation dimensions don't match preview dimensions: " + + "Allocation is " + + previewAllocation.getType().getX() + + ", " + + previewAllocation.getType().getY() + + ". Preview is " + previewSize.width + ", " + + previewSize.height); + } + if ((previewAllocation.getUsage() & + Allocation.USAGE_IO_INPUT) == 0) { + throw new IllegalArgumentException( + "Allocation usage does not include USAGE_IO_INPUT"); + } + if (previewAllocation.getType().getElement().getDataKind() != + Element.DataKind.PIXEL_YUV) { + throw new IllegalArgumentException( + "Allocation is not of a YUV type"); + } + previewSurface = previewAllocation.getSurface(); + mUsingPreviewAllocation = true; + } else { + mUsingPreviewAllocation = false; + } + setPreviewCallbackSurface(previewSurface); + } + + private native final void setPreviewCallbackSurface(Surface s); + private class EventHandler extends Handler { private Camera mCamera; @@ -1492,6 +1636,17 @@ public class Camera { * @see #getParameters() */ public void setParameters(Parameters params) { + // If using preview allocations, don't allow preview size changes + if (mUsingPreviewAllocation) { + Size newPreviewSize = params.getPreviewSize(); + Size currentPreviewSize = getParameters().getPreviewSize(); + if (newPreviewSize.width != currentPreviewSize.width || + newPreviewSize.height != currentPreviewSize.height) { + throw new IllegalStateException("Cannot change preview size" + + " while a preview allocation is configured."); + } + } + native_setParameters(params.flatten()); } diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index 4881d14..7f82ce3 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -381,7 +381,6 @@ public class InputMethodService extends AbstractInputMethodService { if (DEBUG) Log.v(TAG, "unbindInput(): binding=" + mInputBinding + " ic=" + mInputConnection); onUnbindInput(); - mInputStarted = false; mInputBinding = null; mInputConnection = null; } @@ -719,7 +718,7 @@ public class InputMethodService extends AbstractInputMethodService { super.onDestroy(); mRootView.getViewTreeObserver().removeOnComputeInternalInsetsListener( mInsetsComputer); - finishViews(); + doFinishInput(); if (mWindowAdded) { // Disable exit animation for the current IME window // to avoid the race condition between the exit and enter animations diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 499ec77..d0f7511 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -98,6 +98,11 @@ public abstract class BatteryStats implements Parcelable { public static final int VIBRATOR_ON = 9; /** + * A constant indicating a foreground activity timer + */ + public static final int FOREGROUND_ACTIVITY = 10; + + /** * Include all of the data in the stats, including previously saved data. */ public static final int STATS_SINCE_CHARGED = 0; @@ -125,7 +130,7 @@ public abstract class BatteryStats implements Parcelable { /** * Bump the version on this if the checkin format changes. */ - private static final int BATTERY_STATS_CHECKIN_VERSION = 5; + private static final int BATTERY_STATS_CHECKIN_VERSION = 6; private static final long BYTES_PER_KB = 1024; private static final long BYTES_PER_MB = 1048576; // 1024^2 @@ -137,6 +142,7 @@ public abstract class BatteryStats implements Parcelable { private static final String PROCESS_DATA = "pr"; private static final String SENSOR_DATA = "sr"; private static final String VIBRATOR_DATA = "vib"; + private static final String FOREGROUND_DATA = "fg"; private static final String WAKELOCK_DATA = "wl"; private static final String KERNEL_WAKELOCK_DATA = "kwl"; private static final String NETWORK_DATA = "nt"; @@ -276,6 +282,8 @@ public abstract class BatteryStats implements Parcelable { public abstract void noteAudioTurnedOffLocked(); public abstract void noteVideoTurnedOnLocked(); public abstract void noteVideoTurnedOffLocked(); + public abstract void noteActivityResumedLocked(); + public abstract void noteActivityPausedLocked(); public abstract long getWifiRunningTime(long batteryRealtime, int which); public abstract long getFullWifiLockTime(long batteryRealtime, int which); public abstract long getWifiScanTime(long batteryRealtime, int which); @@ -283,6 +291,7 @@ public abstract class BatteryStats implements Parcelable { int which); public abstract long getAudioTurnedOnTime(long batteryRealtime, int which); public abstract long getVideoTurnedOnTime(long batteryRealtime, int which); + public abstract Timer getForegroundActivityTimer(); public abstract Timer getVibratorOnTimer(); /** @@ -1229,7 +1238,7 @@ public abstract class BatteryStats implements Parcelable { final int NU = uidStats.size(); String category = STAT_NAMES[which]; - + // Dump "battery" stat dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, which == STATS_SINCE_CHARGED ? getStartCount() : "N/A", @@ -1417,22 +1426,31 @@ public abstract class BatteryStats implements Parcelable { } } + Timer fgTimer = u.getForegroundActivityTimer(); + if (fgTimer != null) { + // Convert from microseconds to milliseconds with rounding + long totalTime = (fgTimer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000; + int count = fgTimer.getCountLocked(which); + if (totalTime != 0) { + dumpLine(pw, uid, category, FOREGROUND_DATA, totalTime, count); + } + } + Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); if (processStats.size() > 0) { for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent : processStats.entrySet()) { Uid.Proc ps = ent.getValue(); - - long userTime = ps.getUserTime(which); - long systemTime = ps.getSystemTime(which); - int starts = ps.getStarts(which); - - if (userTime != 0 || systemTime != 0 || starts != 0) { - dumpLine(pw, uid, category, PROCESS_DATA, - ent.getKey(), // proc - userTime * 10, // cpu time in ms - systemTime * 10, // user time in ms - starts); // process starts + + final long userMillis = ps.getUserTime(which) * 10; + final long systemMillis = ps.getSystemTime(which) * 10; + final long foregroundMillis = ps.getForegroundTime(which) * 10; + final long starts = ps.getStarts(which); + + if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0 + || starts != 0) { + dumpLine(pw, uid, category, PROCESS_DATA, ent.getKey(), userMillis, + systemMillis, foregroundMillis, starts); } } } @@ -1961,6 +1979,24 @@ public abstract class BatteryStats implements Parcelable { } } + Timer fgTimer = u.getForegroundActivityTimer(); + if (fgTimer != null) { + // Convert from microseconds to milliseconds with rounding + long totalTime = (fgTimer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000; + int count = fgTimer.getCountLocked(which); + if (totalTime != 0) { + sb.setLength(0); + sb.append(prefix); + sb.append(" Foreground activities: "); + formatTimeMs(sb, totalTime); + sb.append("realtime ("); + sb.append(count); + sb.append(" times)"); + pw.println(sb.toString()); + uidActivity = true; + } + } + Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); if (processStats.size() > 0) { for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent @@ -1968,23 +2004,26 @@ public abstract class BatteryStats implements Parcelable { Uid.Proc ps = ent.getValue(); long userTime; long systemTime; + long foregroundTime; int starts; int numExcessive; userTime = ps.getUserTime(which); systemTime = ps.getSystemTime(which); + foregroundTime = ps.getForegroundTime(which); starts = ps.getStarts(which); numExcessive = which == STATS_SINCE_CHARGED ? ps.countExcessivePowers() : 0; - if (userTime != 0 || systemTime != 0 || starts != 0 + if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0 || numExcessive != 0) { sb.setLength(0); sb.append(prefix); sb.append(" Proc "); sb.append(ent.getKey()); sb.append(":\n"); sb.append(prefix); sb.append(" CPU: "); formatTime(sb, userTime); sb.append("usr + "); - formatTime(sb, systemTime); sb.append("krn"); + formatTime(sb, systemTime); sb.append("krn ; "); + formatTime(sb, foregroundTime); sb.append("fg"); if (starts != 0) { sb.append("\n"); sb.append(prefix); sb.append(" "); sb.append(starts); sb.append(" proc starts"); @@ -2042,7 +2081,7 @@ public abstract class BatteryStats implements Parcelable { sb.append(sent.getKey()); sb.append(":\n"); sb.append(prefix); sb.append(" Created for: "); formatTimeMs(sb, startTime / 1000); - sb.append(" uptime\n"); + sb.append("uptime\n"); sb.append(prefix); sb.append(" Starts: "); sb.append(starts); sb.append(", launches: "); sb.append(launches); @@ -2215,7 +2254,7 @@ public abstract class BatteryStats implements Parcelable { * @param pw a Printer to receive the dump output. */ @SuppressWarnings("unused") - public void dumpLocked(PrintWriter pw) { + public void dumpLocked(PrintWriter pw, boolean isUnpluggedOnly) { prepareForDumpLocked(); long now = getHistoryBaseTime() + SystemClock.elapsedRealtime(); @@ -2267,28 +2306,22 @@ public abstract class BatteryStats implements Parcelable { if (didPid) { pw.println(""); } - - pw.println("Statistics since last charge:"); - pw.println(" System starts: " + getStartCount() - + ", currently on battery: " + getIsOnBattery()); - dumpLocked(pw, "", STATS_SINCE_CHARGED, -1); - pw.println(""); + + if (!isUnpluggedOnly) { + pw.println("Statistics since last charge:"); + pw.println(" System starts: " + getStartCount() + + ", currently on battery: " + getIsOnBattery()); + dumpLocked(pw, "", STATS_SINCE_CHARGED, -1); + pw.println(""); + } pw.println("Statistics since last unplugged:"); dumpLocked(pw, "", STATS_SINCE_UNPLUGGED, -1); } @SuppressWarnings("unused") - public void dumpCheckinLocked(PrintWriter pw, String[] args, List<ApplicationInfo> apps) { + public void dumpCheckinLocked( + PrintWriter pw, List<ApplicationInfo> apps, boolean isUnpluggedOnly) { prepareForDumpLocked(); - - boolean isUnpluggedOnly = false; - - for (String arg : args) { - if ("-u".equals(arg)) { - if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data"); - isUnpluggedOnly = true; - } - } if (apps != null) { SparseArray<ArrayList<String>> uids = new SparseArray<ArrayList<String>>(); diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index 6c9f2d1..71c3e4a 100644 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -436,6 +436,11 @@ public class Build { * Android 4.3: Jelly Bean MR2, the revenge of the beans. */ public static final int JELLY_BEAN_MR2 = 18; + + /** + * Android X.X: Key Lime Pie, another tasty treat. + */ + public static final int KEY_LIME_PIE = CUR_DEVELOPMENT; } /** The type of build, like "user" or "eng". */ diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java index fd01da9..362ae29 100644 --- a/core/java/android/os/Debug.java +++ b/core/java/android/os/Debug.java @@ -108,31 +108,78 @@ public final class Debug * process. The returns info broken down by dalvik, native, and other. All results are in kB. */ public static class MemoryInfo implements Parcelable { - /** The proportional set size for dalvik. */ + /** The proportional set size for dalvik heap. (Doesn't include other Dalvik overhead.) */ public int dalvikPss; - /** The private dirty pages used by dalvik. */ + /** The proportional set size that is swappable for dalvik heap. */ + /** @hide We may want to expose this, eventually. */ + public int dalvikSwappablePss; + /** The private dirty pages used by dalvik heap. */ public int dalvikPrivateDirty; - /** The shared dirty pages used by dalvik. */ + /** The shared dirty pages used by dalvik heap. */ public int dalvikSharedDirty; + /** The private clean pages used by dalvik heap. */ + /** @hide We may want to expose this, eventually. */ + public int dalvikPrivateClean; + /** The shared clean pages used by dalvik heap. */ + /** @hide We may want to expose this, eventually. */ + public int dalvikSharedClean; /** The proportional set size for the native heap. */ public int nativePss; + /** The proportional set size that is swappable for the native heap. */ + /** @hide We may want to expose this, eventually. */ + public int nativeSwappablePss; /** The private dirty pages used by the native heap. */ public int nativePrivateDirty; /** The shared dirty pages used by the native heap. */ public int nativeSharedDirty; + /** The private clean pages used by the native heap. */ + /** @hide We may want to expose this, eventually. */ + public int nativePrivateClean; + /** The shared clean pages used by the native heap. */ + /** @hide We may want to expose this, eventually. */ + public int nativeSharedClean; /** The proportional set size for everything else. */ public int otherPss; + /** The proportional set size that is swappable for everything else. */ + /** @hide We may want to expose this, eventually. */ + public int otherSwappablePss; /** The private dirty pages used by everything else. */ public int otherPrivateDirty; /** The shared dirty pages used by everything else. */ public int otherSharedDirty; + /** The private clean pages used by everything else. */ + /** @hide We may want to expose this, eventually. */ + public int otherPrivateClean; + /** The shared clean pages used by everything else. */ + /** @hide We may want to expose this, eventually. */ + public int otherSharedClean; /** @hide */ - public static final int NUM_OTHER_STATS = 10; + public static final int NUM_OTHER_STATS = 13; - private int[] otherStats = new int[NUM_OTHER_STATS*3]; + /** @hide */ + public static final int NUM_DVK_STATS = 5; + + /** @hide */ + public static final int NUM_CATEGORIES = 6; + + /** @hide */ + public static final int offsetPss = 0; + /** @hide */ + public static final int offsetSwappablePss = 1; + /** @hide */ + public static final int offsetPrivateDirty = 2; + /** @hide */ + public static final int offsetSharedDirty = 3; + /** @hide */ + public static final int offsetPrivateClean = 4; + /** @hide */ + public static final int offsetSharedClean = 5; + + + private int[] otherStats = new int[(NUM_OTHER_STATS+NUM_DVK_STATS)*NUM_CATEGORIES]; public MemoryInfo() { } @@ -144,6 +191,14 @@ public final class Debug return dalvikPss + nativePss + otherPss; } + + /** + * Return total PSS memory usage in kB. + */ + public int getTotalSwappablePss() { + return dalvikSwappablePss + nativeSwappablePss + otherSwappablePss; + } + /** * Return total private dirty memory usage in kB. */ @@ -158,35 +213,74 @@ public final class Debug return dalvikSharedDirty + nativeSharedDirty + otherSharedDirty; } + /** + * Return total shared clean memory usage in kB. + */ + public int getTotalPrivateClean() { + return dalvikPrivateClean + nativePrivateClean + otherPrivateClean; + } + + /** + * Return total shared clean memory usage in kB. + */ + public int getTotalSharedClean() { + return dalvikSharedClean + nativeSharedClean + otherSharedClean; + } + /* @hide */ public int getOtherPss(int which) { - return otherStats[which*3]; + return otherStats[which*NUM_CATEGORIES + offsetPss]; + } + + + /* @hide */ + public int getOtherSwappablePss(int which) { + return otherStats[which*NUM_CATEGORIES + offsetSwappablePss]; } + /* @hide */ public int getOtherPrivateDirty(int which) { - return otherStats[which*3 + 1]; + return otherStats[which*NUM_CATEGORIES + offsetPrivateDirty]; } /* @hide */ public int getOtherSharedDirty(int which) { - return otherStats[which*3 + 2]; + return otherStats[which*NUM_CATEGORIES + offsetSharedDirty]; } + /* @hide */ + public int getOtherPrivateClean(int which) { + return otherStats[which*NUM_CATEGORIES + offsetPrivateClean]; + } + + + /* @hide */ + public int getOtherSharedClean(int which) { + return otherStats[which*NUM_CATEGORIES + offsetSharedClean]; + } /* @hide */ public static String getOtherLabel(int which) { switch (which) { - case 0: return "Stack"; - case 1: return "Cursor"; - case 2: return "Ashmem"; - case 3: return "Other dev"; - case 4: return ".so mmap"; - case 5: return ".jar mmap"; - case 6: return ".apk mmap"; - case 7: return ".ttf mmap"; - case 8: return ".dex mmap"; - case 9: return "Other mmap"; + case 0: return "Dalvik Other"; + case 1: return "Stack"; + case 2: return "Cursor"; + case 3: return "Ashmem"; + case 4: return "Other dev"; + case 5: return ".so mmap"; + case 6: return ".jar mmap"; + case 7: return ".apk mmap"; + case 8: return ".ttf mmap"; + case 9: return ".dex mmap"; + case 10: return "code mmap"; + case 11: return "image mmap"; + case 12: return "Other mmap"; + case 13: return ".Heap"; + case 14: return ".LOS"; + case 15: return ".LinearAlloc"; + case 16: return ".GC"; + case 17: return ".JITCache"; default: return "????"; } } @@ -197,27 +291,45 @@ public final class Debug public void writeToParcel(Parcel dest, int flags) { dest.writeInt(dalvikPss); + dest.writeInt(dalvikSwappablePss); dest.writeInt(dalvikPrivateDirty); dest.writeInt(dalvikSharedDirty); + dest.writeInt(dalvikPrivateClean); + dest.writeInt(dalvikSharedClean); dest.writeInt(nativePss); + dest.writeInt(nativeSwappablePss); dest.writeInt(nativePrivateDirty); dest.writeInt(nativeSharedDirty); + dest.writeInt(nativePrivateClean); + dest.writeInt(nativeSharedClean); dest.writeInt(otherPss); + dest.writeInt(otherSwappablePss); dest.writeInt(otherPrivateDirty); dest.writeInt(otherSharedDirty); + dest.writeInt(otherPrivateClean); + dest.writeInt(otherSharedClean); dest.writeIntArray(otherStats); } public void readFromParcel(Parcel source) { dalvikPss = source.readInt(); + dalvikSwappablePss = source.readInt(); dalvikPrivateDirty = source.readInt(); dalvikSharedDirty = source.readInt(); + dalvikPrivateClean = source.readInt(); + dalvikSharedClean = source.readInt(); nativePss = source.readInt(); + nativeSwappablePss = source.readInt(); nativePrivateDirty = source.readInt(); nativeSharedDirty = source.readInt(); + nativePrivateClean = source.readInt(); + nativeSharedClean = source.readInt(); otherPss = source.readInt(); + otherSwappablePss = source.readInt(); otherPrivateDirty = source.readInt(); otherSharedDirty = source.readInt(); + otherPrivateClean = source.readInt(); + otherSharedClean = source.readInt(); otherStats = source.createIntArray(); } @@ -1397,7 +1509,7 @@ href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Lo /** * Return a String describing the calling method and location at a particular stack depth. - * @param callStack the Thread stack + * @param callStack the Thread stack * @param depth the depth of stack to return information for. * @return the String describing the caller at that depth. */ diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java index 61eef1f..70a1edc 100644 --- a/core/java/android/os/Environment.java +++ b/core/java/android/os/Environment.java @@ -19,6 +19,7 @@ package android.os; import android.os.storage.IMountService; import android.os.storage.StorageManager; import android.os.storage.StorageVolume; +import android.os.SystemProperties; import android.text.TextUtils; import android.util.Log; @@ -59,6 +60,10 @@ public class Environment { private static volatile StorageVolume sPrimaryVolume; private static StorageVolume getPrimaryVolume() { + if (SystemProperties.getBoolean("config.disable_storage", false)) { + return null; + } + if (sPrimaryVolume == null) { synchronized (sLock) { if (sPrimaryVolume == null) { diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index 6d6d147..23492ff 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -25,7 +25,7 @@ interface IPowerManager { // WARNING: The first two methods must remain the first two methods because their // transaction numbers must not change unless IPowerManager.cpp is also updated. - void acquireWakeLock(IBinder lock, int flags, String tag, in WorkSource ws); + void acquireWakeLock(IBinder lock, int flags, String tag, String packageName, in WorkSource ws); void releaseWakeLock(IBinder lock, int flags); void updateWakeLockWorkSource(IBinder lock, in WorkSource ws); diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java index d5cf771..78c859e 100644 --- a/core/java/android/os/Looper.java +++ b/core/java/android/os/Looper.java @@ -289,6 +289,16 @@ public final class Looper { return mQueue; } + /** + * Return whether this looper's thread is currently idle, waiting for new work + * to do. This is intrinsically racy, since its state can change before you get + * the result back. + * @hide + */ + public boolean isIdling() { + return mQueue.isIdling(); + } + public void dump(Printer pw, String prefix) { pw = PrefixPrinter.create(pw, prefix); pw.println(this.toString()); diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java index bf7e5ca..1e8983e 100644 --- a/core/java/android/os/MessageQueue.java +++ b/core/java/android/os/MessageQueue.java @@ -52,6 +52,7 @@ public final class MessageQueue { private native static void nativeDestroy(int ptr); private native static void nativePollOnce(int ptr, int timeoutMillis); private native static void nativeWake(int ptr); + private native static boolean nativeIsIdling(int ptr); /** * Callback interface for discovering when a thread is going to block @@ -379,6 +380,10 @@ public final class MessageQueue { } } + boolean isIdling() { + return nativeIsIdling(mPtr); + } + void removeMessages(Handler h, int what, Object object) { if (h == null) { return; diff --git a/core/java/android/os/ParcelableParcel.java b/core/java/android/os/ParcelableParcel.java new file mode 100644 index 0000000..11785f1 --- /dev/null +++ b/core/java/android/os/ParcelableParcel.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +/** + * Parcelable containing a raw Parcel of data. + * @hide + */ +public class ParcelableParcel implements Parcelable { + final Parcel mParcel; + final ClassLoader mClassLoader; + + public ParcelableParcel(ClassLoader loader) { + mParcel = Parcel.obtain(); + mClassLoader = loader; + } + + public ParcelableParcel(Parcel src, ClassLoader loader) { + mParcel = Parcel.obtain(); + mClassLoader = loader; + int size = src.readInt(); + int pos = src.dataPosition(); + mParcel.appendFrom(src, src.dataPosition(), size); + src.setDataPosition(pos + size); + } + + public Parcel getParcel() { + mParcel.setDataPosition(0); + return mParcel; + } + + public ClassLoader getClassLoader() { + return mClassLoader; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(mParcel.dataSize()); + dest.appendFrom(mParcel, 0, mParcel.dataSize()); + } + + public static final Parcelable.ClassLoaderCreator<ParcelableParcel> CREATOR + = new Parcelable.ClassLoaderCreator<ParcelableParcel>() { + public ParcelableParcel createFromParcel(Parcel in) { + return new ParcelableParcel(in, null); + } + + public ParcelableParcel createFromParcel(Parcel in, ClassLoader loader) { + return new ParcelableParcel(in, loader); + } + + public ParcelableParcel[] newArray(int size) { + return new ParcelableParcel[size]; + } + }; +} diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 736762f..52e5f38 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -224,7 +224,7 @@ public final class PowerManager { /** * Flag for {@link WakeLock#release release(int)} to defer releasing a - * {@link #WAKE_BIT_PROXIMITY_SCREEN_OFF} wake lock until the proximity sensor returns + * {@link #PROXIMITY_SCREEN_OFF_WAKE_LOCK} wake lock until the proximity sensor returns * a negative value. * * {@hide} @@ -407,7 +407,7 @@ public final class PowerManager { */ public WakeLock newWakeLock(int levelAndFlags, String tag) { validateWakeLockParameters(levelAndFlags, tag); - return new WakeLock(levelAndFlags, tag); + return new WakeLock(levelAndFlags, tag, mContext.getBasePackageName()); } /** @hide */ @@ -624,6 +624,7 @@ public final class PowerManager { public final class WakeLock { private final int mFlags; private final String mTag; + private final String mPackageName; private final IBinder mToken; private int mCount; private boolean mRefCounted = true; @@ -636,9 +637,10 @@ public final class PowerManager { } }; - WakeLock(int flags, String tag) { + WakeLock(int flags, String tag, String packageName) { mFlags = flags; mTag = tag; + mPackageName = packageName; mToken = new Binder(); } @@ -714,7 +716,7 @@ public final class PowerManager { // been explicitly released by the keyguard. mHandler.removeCallbacks(mReleaser); try { - mService.acquireWakeLock(mToken, mFlags, mTag, mWorkSource); + mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource); } catch (RemoteException e) { } mHeld = true; diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index 476b4ea..93b1255 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -650,6 +650,12 @@ public class Process { public static final native int myPid(); /** + * Returns the identifier of this process' parent. + * @hide + */ + public static native int myPpid(); + + /** * Returns the identifier of the calling thread, which be used with * {@link #setThreadPriority(int, int)}. */ diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java index 480fe7d..5e20dec 100644 --- a/core/java/android/os/RecoverySystem.java +++ b/core/java/android/os/RecoverySystem.java @@ -244,12 +244,17 @@ public class RecoverySystem { // The signature cert matches a trusted key. Now verify that // the digest in the cert matches the actual file data. - // The verifier in recovery *only* handles SHA1withRSA - // signatures. SignApk.java always uses SHA1withRSA, no - // matter what the cert says to use. Ignore - // cert.getSigAlgName(), and instead use whatever - // algorithm is used by the signature (which should be - // SHA1withRSA). + // The verifier in recovery only handles SHA1withRSA and + // SHA256withRSA signatures. SignApk chooses which to use + // based on the signature algorithm of the cert: + // + // "SHA256withRSA" cert -> "SHA256withRSA" signature + // "SHA1withRSA" cert -> "SHA1withRSA" signature + // "MD5withRSA" cert -> "SHA1withRSA" signature (for backwards compatibility) + // any other cert -> SignApk fails + // + // Here we ignore whatever the cert says, and instead use + // whatever algorithm is used by the signature. String da = sigInfo.getDigestAlgorithm(); String dea = sigInfo.getDigestEncryptionAlgorithm(); diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java index d02a320..c1d4ae9 100644 --- a/core/java/android/os/RemoteCallbackList.java +++ b/core/java/android/os/RemoteCallbackList.java @@ -16,6 +16,8 @@ package android.os; +import android.util.ArrayMap; + import java.util.HashMap; /** @@ -47,8 +49,8 @@ import java.util.HashMap; * implements the {@link #onCallbackDied} method. */ public class RemoteCallbackList<E extends IInterface> { - /*package*/ HashMap<IBinder, Callback> mCallbacks - = new HashMap<IBinder, Callback>(); + /*package*/ ArrayMap<IBinder, Callback> mCallbacks + = new ArrayMap<IBinder, Callback>(); private Object[] mActiveBroadcast; private int mBroadcastCount = -1; private boolean mKilled = false; @@ -159,7 +161,8 @@ public class RemoteCallbackList<E extends IInterface> { */ public void kill() { synchronized (mCallbacks) { - for (Callback cb : mCallbacks.values()) { + for (int cbi=mCallbacks.size()-1; cbi>=0; cbi--) { + Callback cb = mCallbacks.valueAt(cbi); cb.mCallback.asBinder().unlinkToDeath(cb, 0); } mCallbacks.clear(); @@ -238,11 +241,10 @@ public class RemoteCallbackList<E extends IInterface> { if (active == null || active.length < N) { mActiveBroadcast = active = new Object[N]; } - int i=0; - for (Callback cb : mCallbacks.values()) { - active[i++] = cb; + for (int i=0; i<N; i++) { + active[i] = mCallbacks.valueAt(i); } - return i; + return N; } } diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java index 3267939..31da091 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -24,6 +24,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; +import android.util.ArrayMap; import android.util.Log; import android.util.Printer; import android.util.Singleton; @@ -1069,7 +1070,7 @@ public final class StrictMode { // Map from violation stacktrace hashcode -> uptimeMillis of // last violation. No locking needed, as this is only // accessed by the same thread. - private final HashMap<Integer, Long> mLastViolationTime = new HashMap<Integer, Long>(); + private ArrayMap<Integer, Long> mLastViolationTime; public AndroidBlockGuardPolicy(final int policyMask) { mPolicyMask = policyMask; @@ -1279,8 +1280,13 @@ public final class StrictMode { // Not perfect, but fast and good enough for dup suppression. Integer crashFingerprint = info.hashCode(); long lastViolationTime = 0; - if (mLastViolationTime.containsKey(crashFingerprint)) { - lastViolationTime = mLastViolationTime.get(crashFingerprint); + if (mLastViolationTime != null) { + Long vtime = mLastViolationTime.get(crashFingerprint); + if (vtime != null) { + lastViolationTime = vtime; + } + } else { + mLastViolationTime = new ArrayMap<Integer, Long>(1); } long now = SystemClock.uptimeMillis(); mLastViolationTime.put(crashFingerprint, now); diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java index e53cb5e..bb3d296 100644 --- a/core/java/android/os/Trace.java +++ b/core/java/android/os/Trace.java @@ -67,6 +67,8 @@ public final class Trace { public static final long TRACE_TAG_RESOURCES = 1L << 13; /** @hide */ public static final long TRACE_TAG_DALVIK = 1L << 14; + /** @hide */ + public static final long TRACE_TAG_RS = 1L << 15; private static final long TRACE_TAG_NOT_READY = 1L << 63; private static final int MAX_SECTION_NAME_LEN = 127; diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java new file mode 100644 index 0000000..c26f6d4 --- /dev/null +++ b/core/java/android/provider/DocumentsContract.java @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.provider; + +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Intent; +import android.content.res.AssetFileDescriptor; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Point; +import android.net.Uri; +import android.os.Bundle; +import android.util.Log; + +import libcore.io.IoUtils; + +import java.io.IOException; +import java.io.InputStream; + +/** + * The contract between a storage backend and the platform. Contains definitions + * for the supported URIs and columns. + */ +public final class DocumentsContract { + private static final String TAG = "Documents"; + + // content://com.example/docs/0/ + // content://com.example/docs/0/contents/ + // content://com.example/search/?query=pony + + /** + * MIME type of a document which is a directory that may contain additional + * documents. + * + * @see #buildContentsUri(Uri) + */ + public static final String MIME_TYPE_DIRECTORY = "vnd.android.cursor.dir/doc"; + + /** {@hide} */ + public static final String META_DATA_DOCUMENT_PROVIDER = "android.content.DOCUMENT_PROVIDER"; + + /** + * {@link DocumentColumns#GUID} value representing the root directory of a + * storage backend. + */ + public static final String ROOT_GUID = "0"; + + /** + * Flag indicating that a document is a directory that supports creation of + * new files within it. + * + * @see DocumentColumns#FLAGS + * @see #buildContentsUri(Uri) + */ + public static final int FLAG_SUPPORTS_CREATE = 1; + + /** + * Flag indicating that a document is renamable. + * + * @see DocumentColumns#FLAGS + * @see #renameDocument(ContentResolver, Uri, String) + */ + public static final int FLAG_SUPPORTS_RENAME = 1 << 1; + + /** + * Flag indicating that a document can be represented as a thumbnail. + * + * @see DocumentColumns#FLAGS + * @see #getThumbnail(ContentResolver, Uri, Point) + */ + public static final int FLAG_SUPPORTS_THUMBNAIL = 1 << 2; + + /** + * Optimal dimensions for a document thumbnail request, stored as a + * {@link Point} object. This is only a hint, and the returned thumbnail may + * have different dimensions. + */ + public static final String EXTRA_THUMBNAIL_SIZE = "thumbnail_size"; + + private static final String PATH_DOCS = "docs"; + private static final String PATH_CONTENTS = "contents"; + private static final String PATH_SEARCH = "search"; + + private static final String PARAM_QUERY = "query"; + + /** + * Build URI representing the given {@link DocumentColumns#GUID} in a + * storage backend. + */ + public static Uri buildDocumentUri(String authority, String guid) { + return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) + .authority(authority).appendPath(PATH_DOCS).appendPath(guid).build(); + } + + /** + * Build URI representing a search for matching documents in a storage + * backend. + */ + public static Uri buildSearchUri(String authority, String query) { + return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority) + .appendPath(PATH_SEARCH).appendQueryParameter(PARAM_QUERY, query).build(); + } + + /** + * Build URI representing the contents of the given directory in a storage + * backend. The given document must be {@link #MIME_TYPE_DIRECTORY}. + */ + public static Uri buildContentsUri(Uri documentUri) { + return documentUri.buildUpon().appendPath(PATH_CONTENTS).build(); + } + + /** + * These are standard columns for document URIs. Storage backend providers + * <em>must</em> support at least these columns when queried. + * + * @see Intent#ACTION_OPEN_DOCUMENT + * @see Intent#ACTION_CREATE_DOCUMENT + */ + public interface DocumentColumns extends OpenableColumns { + /** + * The globally unique ID for a document within a storage backend. + * Values <em>must</em> never change once returned. + * <p> + * Type: STRING + * + * @see DocumentsContract#ROOT_GUID + */ + public static final String GUID = "guid"; + + /** + * MIME type of a document, matching the value returned by + * {@link ContentResolver#getType(android.net.Uri)}. + * <p> + * Type: STRING + * + * @see DocumentsContract#MIME_TYPE_DIRECTORY + */ + public static final String MIME_TYPE = "mime_type"; + + /** + * Timestamp when a document was last modified, in milliseconds since + * January 1, 1970 00:00:00.0 UTC. + * <p> + * Type: INTEGER (long) + * + * @see System#currentTimeMillis() + */ + public static final String LAST_MODIFIED = "last_modified"; + + /** + * Flags that apply to a specific document. + * <p> + * Type: INTEGER (int) + */ + public static final String FLAGS = "flags"; + } + + /** + * Return thumbnail representing the document at the given URI. Callers are + * responsible for their own caching. Given document must have + * {@link #FLAG_SUPPORTS_THUMBNAIL} set. + * + * @return decoded thumbnail, or {@code null} if problem was encountered. + */ + public static Bitmap getThumbnail(ContentResolver resolver, Uri documentUri, Point size) { + final Bundle opts = new Bundle(); + opts.putParcelable(EXTRA_THUMBNAIL_SIZE, size); + + InputStream is = null; + try { + is = new AssetFileDescriptor.AutoCloseInputStream( + resolver.openTypedAssetFileDescriptor(documentUri, "image/*", opts)); + return BitmapFactory.decodeStream(is); + } catch (IOException e) { + Log.w(TAG, "Failed to load thumbnail for " + documentUri + ": " + e); + return null; + } finally { + IoUtils.closeQuietly(is); + } + } + + /** + * Rename the document at the given URI. Given document must have + * {@link #FLAG_SUPPORTS_RENAME} set. + * + * @return if rename was successful. + */ + public static boolean renameDocument( + ContentResolver resolver, Uri documentUri, String displayName) { + final ContentValues values = new ContentValues(); + values.put(DocumentColumns.DISPLAY_NAME, displayName); + return (resolver.update(documentUri, values, null, null) == 1); + } +} diff --git a/core/java/android/provider/DrmStore.java b/core/java/android/provider/DrmStore.java deleted file mode 100644 index 34f2f0d..0000000 --- a/core/java/android/provider/DrmStore.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.provider; - -import android.content.ContentResolver; -import android.content.ContentValues; -import android.content.Context; -import android.drm.mobile1.DrmRawContent; -import android.drm.mobile1.DrmRights; -import android.drm.mobile1.DrmRightsManager; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.net.Uri; -import android.util.Log; - -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; -import java.io.IOException; -import java.io.OutputStream; - -/** - * The DRM provider contains forward locked DRM content. - * - * @hide - */ -public final class DrmStore -{ - private static final String TAG = "DrmStore"; - - public static final String AUTHORITY = "drm"; - - /** - * This is in the Manifest class of the drm provider, but that isn't visible - * in the framework. - */ - private static final String ACCESS_DRM_PERMISSION = "android.permission.ACCESS_DRM"; - - /** - * Fields for DRM database - */ - - public interface Columns extends BaseColumns { - /** - * The data stream for the file - * <P>Type: DATA STREAM</P> - */ - public static final String DATA = "_data"; - - /** - * The size of the file in bytes - * <P>Type: INTEGER (long)</P> - */ - public static final String SIZE = "_size"; - - /** - * The title of the file content - * <P>Type: TEXT</P> - */ - public static final String TITLE = "title"; - - /** - * The MIME type of the file - * <P>Type: TEXT</P> - */ - public static final String MIME_TYPE = "mime_type"; - - } - - public interface Images extends Columns { - - public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/images"); - } - - public interface Audio extends Columns { - - public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/audio"); - } - - /** - * Utility function for inserting a file into the DRM content provider. - * - * @param cr The content resolver to use - * @param file The file to insert - * @param title The title for the content (or null) - * @return uri to the DRM record or null - */ - public static final Intent addDrmFile(ContentResolver cr, File file, String title) { - FileInputStream fis = null; - Intent result = null; - - try { - fis = new FileInputStream(file); - if (title == null) { - title = file.getName(); - int lastDot = title.lastIndexOf('.'); - if (lastDot > 0) { - title = title.substring(0, lastDot); - } - } - result = addDrmFile(cr, fis, title); - } catch (Exception e) { - Log.e(TAG, "pushing file failed", e); - } finally { - try { - if (fis != null) - fis.close(); - } catch (IOException e) { - Log.e(TAG, "IOException in DrmStore.addDrmFile()", e); - } - } - - return result; - } - - /** - * Utility function for inserting a file stream into the DRM content provider. - * - * @param cr The content resolver to use - * @param fis The FileInputStream to insert - * @param title The title for the content (or null) - * @return uri to the DRM record or null - */ - public static final Intent addDrmFile(ContentResolver cr, FileInputStream fis, String title) { - OutputStream os = null; - Intent result = null; - - try { - DrmRawContent content = new DrmRawContent(fis, (int) fis.available(), - DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING); - String mimeType = content.getContentType(); - long size = fis.getChannel().size(); - - DrmRightsManager manager = manager = DrmRightsManager.getInstance(); - DrmRights rights = manager.queryRights(content); - InputStream stream = content.getContentInputStream(rights); - - Uri contentUri = null; - if (mimeType.startsWith("audio/")) { - contentUri = DrmStore.Audio.CONTENT_URI; - } else if (mimeType.startsWith("image/")) { - contentUri = DrmStore.Images.CONTENT_URI; - } else { - Log.w(TAG, "unsupported mime type " + mimeType); - } - - if (contentUri != null) { - ContentValues values = new ContentValues(3); - values.put(DrmStore.Columns.TITLE, title); - values.put(DrmStore.Columns.SIZE, size); - values.put(DrmStore.Columns.MIME_TYPE, mimeType); - - Uri uri = cr.insert(contentUri, values); - if (uri != null) { - os = cr.openOutputStream(uri); - - byte[] buffer = new byte[1000]; - int count; - - while ((count = stream.read(buffer)) != -1) { - os.write(buffer, 0, count); - } - result = new Intent(); - result.setDataAndType(uri, mimeType); - - } - } - } catch (Exception e) { - Log.e(TAG, "pushing file failed", e); - } finally { - try { - if (fis != null) - fis.close(); - if (os != null) - os.close(); - } catch (IOException e) { - Log.e(TAG, "IOException in DrmStore.addDrmFile()", e); - } - } - - return result; - } - - /** - * Utility function to enforce any permissions required to access DRM - * content. - * - * @param context A context used for checking calling permission. - */ - public static void enforceAccessDrmPermission(Context context) { - if (context.checkCallingOrSelfPermission(ACCESS_DRM_PERMISSION) != - PackageManager.PERMISSION_GRANTED) { - throw new SecurityException("Requires DRM permission"); - } - } - -} diff --git a/core/java/android/provider/OpenableColumns.java b/core/java/android/provider/OpenableColumns.java index f548bae..faf96b7 100644 --- a/core/java/android/provider/OpenableColumns.java +++ b/core/java/android/provider/OpenableColumns.java @@ -16,11 +16,17 @@ package android.provider; +import android.content.ContentResolver; +import android.content.Intent; + /** - * These are standard columns for openable URIs. (See - * {@link android.content.Intent#CATEGORY_OPENABLE}.) If possible providers that have openable URIs - * should support these columns. To find the content type of a URI use - * {@link android.content.ContentResolver#getType(android.net.Uri)} as normal. + * These are standard columns for openable URIs. Providers that serve openable + * URIs <em>must</em> support at least these columns when queried. + * <p> + * To find the content type of a URI, use + * {@link ContentResolver#getType(android.net.Uri)}. + * + * @see Intent#CATEGORY_OPENABLE */ public interface OpenableColumns { diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 3c8187e..c1a296d 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -1010,6 +1010,14 @@ public final class Settings { MOVED_TO_GLOBAL.add(Settings.Global.WAIT_FOR_DEBUGGER); MOVED_TO_GLOBAL.add(Settings.Global.SHOW_PROCESSES); MOVED_TO_GLOBAL.add(Settings.Global.ALWAYS_FINISH_ACTIVITIES); + MOVED_TO_GLOBAL.add(Settings.Global.TZINFO_UPDATE_CONTENT_URL); + MOVED_TO_GLOBAL.add(Settings.Global.TZINFO_UPDATE_METADATA_URL); + MOVED_TO_GLOBAL.add(Settings.Global.SELINUX_UPDATE_CONTENT_URL); + MOVED_TO_GLOBAL.add(Settings.Global.SELINUX_UPDATE_METADATA_URL); + MOVED_TO_GLOBAL.add(Settings.Global.SMS_SHORT_CODES_UPDATE_CONTENT_URL); + MOVED_TO_GLOBAL.add(Settings.Global.SMS_SHORT_CODES_UPDATE_METADATA_URL); + MOVED_TO_GLOBAL.add(Settings.Global.CERT_PIN_UPDATE_CONTENT_URL); + MOVED_TO_GLOBAL.add(Settings.Global.CERT_PIN_UPDATE_METADATA_URL); } /** @hide */ diff --git a/core/java/android/speech/tts/TtsEngines.java b/core/java/android/speech/tts/TtsEngines.java index 2706bc7..5fbd22e 100644 --- a/core/java/android/speech/tts/TtsEngines.java +++ b/core/java/android/speech/tts/TtsEngines.java @@ -355,7 +355,18 @@ public class TtsEngines { return v1Locale; } - private String getDefaultLocale() { + /** + * Return the default device locale in form of 3 letter codes delimited by + * {@link #LOCALE_DELIMITER}: + * <ul> + * <li> "ISO 639-2/T language code" if locale have no country entry</li> + * <li> "ISO 639-2/T language code{@link #LOCALE_DELIMITER}ISO 3166 country code " + * if locale have no variant entry</li> + * <li> "ISO 639-2/T language code{@link #LOCALE_DELIMITER}ISO 3166 country code + * {@link #LOCALE_DELIMITER} variant" if locale have variant entry</li> + * </ul> + */ + public String getDefaultLocale() { final Locale locale = Locale.getDefault(); // Note that the default locale might have an empty variant diff --git a/core/java/android/text/method/ArrowKeyMovementMethod.java b/core/java/android/text/method/ArrowKeyMovementMethod.java index 30bb447..ba6f1d4 100644 --- a/core/java/android/text/method/ArrowKeyMovementMethod.java +++ b/core/java/android/text/method/ArrowKeyMovementMethod.java @@ -56,7 +56,7 @@ public class ArrowKeyMovementMethod extends BaseMovementMethod implements Moveme if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0 && MetaKeyKeyListener.getMetaState(buffer, - MetaKeyKeyListener.META_SELECTING) != 0) { + MetaKeyKeyListener.META_SELECTING, event) != 0) { return widget.showContextMenu(); } } diff --git a/core/java/android/text/method/BaseKeyListener.java b/core/java/android/text/method/BaseKeyListener.java index 4fede32..63607fa 100644 --- a/core/java/android/text/method/BaseKeyListener.java +++ b/core/java/android/text/method/BaseKeyListener.java @@ -75,7 +75,7 @@ public abstract class BaseKeyListener extends MetaKeyKeyListener } // Alt+Backspace or Alt+ForwardDelete deletes the current line, if possible. - if (event.isAltPressed() || getMetaState(content, META_ALT_ON) == 1) { + if (getMetaState(content, META_ALT_ON, event) == 1) { if (deleteLine(view, content)) { return true; } diff --git a/core/java/android/text/method/BaseMovementMethod.java b/core/java/android/text/method/BaseMovementMethod.java index 113a4be..155a2c4 100644 --- a/core/java/android/text/method/BaseMovementMethod.java +++ b/core/java/android/text/method/BaseMovementMethod.java @@ -135,7 +135,7 @@ public class BaseMovementMethod implements MovementMethod { */ protected int getMovementMetaState(Spannable buffer, KeyEvent event) { // We ignore locked modifiers and SHIFT. - int metaState = (event.getMetaState() | MetaKeyKeyListener.getMetaState(buffer)) + int metaState = MetaKeyKeyListener.getMetaState(buffer, event) & ~(MetaKeyKeyListener.META_ALT_LOCKED | MetaKeyKeyListener.META_SYM_LOCKED); return KeyEvent.normalizeMetaState(metaState) & ~KeyEvent.META_SHIFT_MASK; } diff --git a/core/java/android/text/method/DialerKeyListener.java b/core/java/android/text/method/DialerKeyListener.java index ce51fae..bb8b0de 100644 --- a/core/java/android/text/method/DialerKeyListener.java +++ b/core/java/android/text/method/DialerKeyListener.java @@ -53,7 +53,7 @@ public class DialerKeyListener extends NumberKeyListener * from the KeyEvent. */ protected int lookup(KeyEvent event, Spannable content) { - int meta = event.getMetaState() | getMetaState(content); + int meta = getMetaState(content, event); int number = event.getNumber(); /* diff --git a/core/java/android/text/method/LinkMovementMethod.java b/core/java/android/text/method/LinkMovementMethod.java index aff233d..3855ff3 100644 --- a/core/java/android/text/method/LinkMovementMethod.java +++ b/core/java/android/text/method/LinkMovementMethod.java @@ -36,6 +36,11 @@ public class LinkMovementMethod extends ScrollingMovementMethod { private static final int DOWN = 3; @Override + public boolean canSelectArbitrarily() { + return true; + } + + @Override protected boolean handleMovementKey(TextView widget, Spannable buffer, int keyCode, int movementMetaState, KeyEvent event) { switch (keyCode) { diff --git a/core/java/android/text/method/MetaKeyKeyListener.java b/core/java/android/text/method/MetaKeyKeyListener.java index 0a097f9..e9db5fd 100644 --- a/core/java/android/text/method/MetaKeyKeyListener.java +++ b/core/java/android/text/method/MetaKeyKeyListener.java @@ -135,6 +135,9 @@ public abstract class MetaKeyKeyListener { private static final Object SYM = new NoCopySpan.Concrete(); private static final Object SELECTING = new NoCopySpan.Concrete(); + private static final int PRESSED_RETURN_VALUE = 1; + private static final int LOCKED_RETURN_VALUE = 2; + /** * Resets all meta state to inactive. */ @@ -161,9 +164,34 @@ public abstract class MetaKeyKeyListener { } /** + * Gets the state of the meta keys for a specific key event. + * + * For input devices that use toggled key modifiers, the `toggled' state + * is stored into the text buffer. This method retrieves the meta state + * for this event, accounting for the stored state. If the event has been + * created by a device that does not support toggled key modifiers, like + * a virtual device for example, the stored state is ignored. + * + * @param text the buffer in which the meta key would have been pressed. + * @param event the event for which to evaluate the meta state. + * @return an integer in which each bit set to one represents a pressed + * or locked meta key. + */ + public static final int getMetaState(final CharSequence text, final KeyEvent event) { + int metaState = event.getMetaState(); + if (event.getKeyCharacterMap().getModifierBehavior() + == KeyCharacterMap.MODIFIER_BEHAVIOR_CHORDED_OR_TOGGLED) { + metaState |= getMetaState(text); + } + return metaState; + } + + // As META_SELECTING is @hide we should not mention it in public comments, hence the + // omission in @param meta + /** * Gets the state of a particular meta key. * - * @param meta META_SHIFT_ON, META_ALT_ON, META_SYM_ON, or META_SELECTING + * @param meta META_SHIFT_ON, META_ALT_ON, META_SYM_ON * @param text the buffer in which the meta key would have been pressed. * * @return 0 if inactive, 1 if active, 2 if locked. @@ -171,22 +199,53 @@ public abstract class MetaKeyKeyListener { public static final int getMetaState(CharSequence text, int meta) { switch (meta) { case META_SHIFT_ON: - return getActive(text, CAP, 1, 2); + return getActive(text, CAP, PRESSED_RETURN_VALUE, LOCKED_RETURN_VALUE); case META_ALT_ON: - return getActive(text, ALT, 1, 2); + return getActive(text, ALT, PRESSED_RETURN_VALUE, LOCKED_RETURN_VALUE); case META_SYM_ON: - return getActive(text, SYM, 1, 2); + return getActive(text, SYM, PRESSED_RETURN_VALUE, LOCKED_RETURN_VALUE); case META_SELECTING: - return getActive(text, SELECTING, 1, 2); + return getActive(text, SELECTING, PRESSED_RETURN_VALUE, LOCKED_RETURN_VALUE); default: return 0; } } + /** + * Gets the state of a particular meta key to use with a particular key event. + * + * If the key event has been created by a device that does not support toggled + * key modifiers, like a virtual keyboard for example, only the meta state in + * the key event is considered. + * + * @param meta META_SHIFT_ON, META_ALT_ON, META_SYM_ON + * @param text the buffer in which the meta key would have been pressed. + * @param event the event for which to evaluate the meta state. + * @return 0 if inactive, 1 if active, 2 if locked. + */ + public static final int getMetaState(final CharSequence text, final int meta, + final KeyEvent event) { + int metaState = event.getMetaState(); + if (event.getKeyCharacterMap().getModifierBehavior() + == KeyCharacterMap.MODIFIER_BEHAVIOR_CHORDED_OR_TOGGLED) { + metaState |= getMetaState(text); + } + if (META_SELECTING == meta) { + // #getMetaState(long, int) does not support META_SELECTING, but we want the same + // behavior as #getMetaState(CharSequence, int) so we need to do it here + if ((metaState & META_SELECTING) != 0) { + // META_SELECTING is only ever set to PRESSED and can't be LOCKED, so return 1 + return 1; + } + return 0; + } + return getMetaState(metaState, meta); + } + private static int getActive(CharSequence text, Object meta, int on, int lock) { if (!(text instanceof Spanned)) { @@ -430,18 +489,18 @@ public abstract class MetaKeyKeyListener { public static final int getMetaState(long state, int meta) { switch (meta) { case META_SHIFT_ON: - if ((state & META_CAP_LOCKED) != 0) return 2; - if ((state & META_SHIFT_ON) != 0) return 1; + if ((state & META_CAP_LOCKED) != 0) return LOCKED_RETURN_VALUE; + if ((state & META_SHIFT_ON) != 0) return PRESSED_RETURN_VALUE; return 0; case META_ALT_ON: - if ((state & META_ALT_LOCKED) != 0) return 2; - if ((state & META_ALT_ON) != 0) return 1; + if ((state & META_ALT_LOCKED) != 0) return LOCKED_RETURN_VALUE; + if ((state & META_ALT_ON) != 0) return PRESSED_RETURN_VALUE; return 0; case META_SYM_ON: - if ((state & META_SYM_LOCKED) != 0) return 2; - if ((state & META_SYM_ON) != 0) return 1; + if ((state & META_SYM_LOCKED) != 0) return LOCKED_RETURN_VALUE; + if ((state & META_SYM_ON) != 0) return PRESSED_RETURN_VALUE; return 0; default: @@ -599,4 +658,3 @@ public abstract class MetaKeyKeyListener { private static final int LOCKED = Spannable.SPAN_MARK_MARK | (4 << Spannable.SPAN_USER_SHIFT); } - diff --git a/core/java/android/text/method/NumberKeyListener.java b/core/java/android/text/method/NumberKeyListener.java index 5d4c732..988d566 100644 --- a/core/java/android/text/method/NumberKeyListener.java +++ b/core/java/android/text/method/NumberKeyListener.java @@ -41,7 +41,7 @@ public abstract class NumberKeyListener extends BaseKeyListener protected abstract char[] getAcceptedChars(); protected int lookup(KeyEvent event, Spannable content) { - return event.getMatch(getAcceptedChars(), event.getMetaState() | getMetaState(content)); + return event.getMatch(getAcceptedChars(), getMetaState(content, event)); } public CharSequence filter(CharSequence source, int start, int end, diff --git a/core/java/android/text/method/QwertyKeyListener.java b/core/java/android/text/method/QwertyKeyListener.java index 98316ae..0bd46bc 100644 --- a/core/java/android/text/method/QwertyKeyListener.java +++ b/core/java/android/text/method/QwertyKeyListener.java @@ -108,7 +108,7 @@ public class QwertyKeyListener extends BaseKeyListener { // QWERTY keyboard normal case - int i = event.getUnicodeChar(event.getMetaState() | getMetaState(content)); + int i = event.getUnicodeChar(getMetaState(content, event)); if (!mFullKeyboard) { int count = event.getRepeatCount(); diff --git a/core/java/android/util/ArrayMap.java b/core/java/android/util/ArrayMap.java new file mode 100644 index 0000000..6da7546 --- /dev/null +++ b/core/java/android/util/ArrayMap.java @@ -0,0 +1,617 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.util; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +/** + * ArrayMap is a generic key->value mapping data structure that is + * designed to be more memory efficient than a traditional {@link java.util.HashMap}. + * It keeps its mappings in an array data structure -- an integer array of hash + * codes for each item, and an Object array of the key/value pairs. This allows it to + * avoid having to create an extra object for every entry put in to the map, and it + * also tries to control the growth of the size of these arrays more aggressively + * (since growing them only requires copying the entries in the array, not rebuilding + * a hash map). + * + * <p>Note that this implementation is not intended to be appropriate for data structures + * that may contain large numbers of items. It is generally slower than a traditional + * HashMap, since lookups require a binary search and adds and removes require inserting + * and deleting entries in the array. For containers holding up to hundreds of items, + * the performance difference is not significant, less than 50%. For larger numbers of items + * this data structure should be avoided.</p> + * + * <p><b>Note:</b> unlike {@link java.util.HashMap}, this container does not support + * null keys.</p> + * + * <p>Because this container is intended to better balance memory use, unlike most other + * standard Java containers it will shrink its array as items are removed from it. Currently + * you have no control over this shrinking -- if you set a capacity and then remove an + * item, it may reduce the capacity to better match the current size. In the future an + * explicitly call to set the capacity should turn off this aggressive shrinking behavior.</p> + * + * @hide + */ +public final class ArrayMap<K, V> implements Map<K, V> { + private static final boolean DEBUG = false; + private static final String TAG = "ArrayMap"; + + /** + * The minimum amount by which the capacity of a ArrayMap will increase. + * This is tuned to be relatively space-efficient. + */ + private static final int BASE_SIZE = 4; + + /** + * Maximum number of entries to have in array caches. + */ + private static final int CACHE_SIZE = 10; + + /** + * Caches of small array objects to avoid spamming garbage. The cache + * Object[] variable is a pointer to a linked list of array objects. + * The first entry in the array is a pointer to the next array in the + * list; the second entry is a pointer to the int[] hash code array for it. + */ + static Object[] mBaseCache; + static int mBaseCacheSize; + static Object[] mTwiceBaseCache; + static int mTwiceBaseCacheSize; + + int[] mHashes; + Object[] mArray; + int mSize; + MapCollections<K, V> mCollections; + + private int indexOf(Object key, int hash) { + final int N = mSize; + + // Important fast case: if nothing is in here, nothing to look for. + if (N == 0) { + return ~0; + } + + int index = SparseArray.binarySearch(mHashes, N, hash); + + // If the hash code wasn't found, then we have no entry for this key. + if (index < 0) { + return index; + } + + // If the key at the returned index matches, that's what we want. + if (mArray[index<<1].equals(key)) { + return index; + } + + // Search for a matching key after the index. + int end; + for (end = index + 1; end < N && mHashes[end] == hash; end++) { + if (mArray[end << 1].equals(key)) return end; + } + + // Search for a matching key before the index. + for (int i = index - 1; i >= 0 && mHashes[i] == hash; i--) { + if (mArray[i << 1].equals(key)) return i; + } + + // Key not found -- return negative value indicating where a + // new entry for this key should go. We use the end of the + // hash chain to reduce the number of array entries that will + // need to be copied when inserting. + return ~end; + } + + private void allocArrays(final int size) { + if (size == (BASE_SIZE*2)) { + synchronized (ArrayMap.class) { + if (mTwiceBaseCache != null) { + final Object[] array = mTwiceBaseCache; + mArray = array; + mTwiceBaseCache = (Object[])array[0]; + mHashes = (int[])array[1]; + array[0] = array[1] = null; + mTwiceBaseCacheSize--; + if (DEBUG) Log.d(TAG, "Retrieving 2x cache " + mHashes + + " now have " + mTwiceBaseCacheSize + " entries"); + return; + } + } + } else if (size == BASE_SIZE) { + synchronized (ArrayMap.class) { + if (mBaseCache != null) { + final Object[] array = mBaseCache; + mArray = array; + mBaseCache = (Object[])array[0]; + mHashes = (int[])array[1]; + array[0] = array[1] = null; + mBaseCacheSize--; + if (DEBUG) Log.d(TAG, "Retrieving 1x cache " + mHashes + + " now have " + mBaseCacheSize + " entries"); + return; + } + } + } + + mHashes = new int[size]; + mArray = new Object[size<<1]; + } + + private static void freeArrays(final int[] hashes, final Object[] array, final int size) { + if (hashes.length == (BASE_SIZE*2)) { + synchronized (ArrayMap.class) { + if (mTwiceBaseCacheSize < CACHE_SIZE) { + array[0] = mTwiceBaseCache; + array[1] = hashes; + for (int i=(size<<1)-1; i>=2; i--) { + array[i] = null; + } + mTwiceBaseCache = array; + mTwiceBaseCacheSize++; + if (DEBUG) Log.d(TAG, "Storing 2x cache " + array + + " now have " + mTwiceBaseCacheSize + " entries"); + } + } + } else if (hashes.length == BASE_SIZE) { + synchronized (ArrayMap.class) { + if (mBaseCacheSize < CACHE_SIZE) { + array[0] = mBaseCache; + array[1] = hashes; + for (int i=(size<<1)-1; i>=2; i--) { + array[i] = null; + } + mBaseCache = array; + mBaseCacheSize++; + if (DEBUG) Log.d(TAG, "Storing 1x cache " + array + + " now have " + mBaseCacheSize + " entries"); + } + } + } + } + + /** + * Create a new empty ArrayMap. The default capacity of an array map is 0, and + * will grow once items are added to it. + */ + public ArrayMap() { + mHashes = SparseArray.EMPTY_INTS; + mArray = SparseArray.EMPTY_OBJECTS; + mSize = 0; + } + + /** + * Create a new ArrayMap with a given initial capacity. + */ + public ArrayMap(int capacity) { + if (capacity == 0) { + mHashes = SparseArray.EMPTY_INTS; + mArray = SparseArray.EMPTY_OBJECTS; + } else { + allocArrays(capacity); + } + mSize = 0; + } + + /** + * Make the array map empty. All storage is released. + */ + @Override + public void clear() { + if (mSize != 0) { + freeArrays(mHashes, mArray, mSize); + mHashes = SparseArray.EMPTY_INTS; + mArray = SparseArray.EMPTY_OBJECTS; + mSize = 0; + } + } + + /** + * Ensure the array map can hold at least <var>minimumCapacity</var> + * items. + */ + public void ensureCapacity(int minimumCapacity) { + if (mHashes.length < minimumCapacity) { + int[] ohashes = mHashes; + Object[] oarray = mArray; + allocArrays(minimumCapacity); + if (mSize > 0) { + System.arraycopy(ohashes, 0, mHashes, 0, mSize); + System.arraycopy(oarray, 0, mArray, 0, mSize<<1); + } + freeArrays(ohashes, oarray, mSize); + } + } + + /** + * Check whether a key exists in the array. + * + * @param key The key to search for. + * @return Returns true if the key exists, else false. + */ + @Override + public boolean containsKey(Object key) { + return indexOf(key, key.hashCode()) >= 0; + } + + private int indexOfValue(Object value) { + final int N = mSize*2; + final Object[] array = mArray; + if (value == null) { + for (int i=1; i<N; i+=2) { + if (array[i] == null) { + return i>>1; + } + } + } else { + for (int i=1; i<N; i+=2) { + if (value.equals(array[i])) { + return i>>1; + } + } + } + return -1; + } + + /** + * Check whether a value exists in the array. This requires a linear search + * through the entire array. + * + * @param value The value to search for. + * @return Returns true if the value exists, else false. + */ + @Override + public boolean containsValue(Object value) { + return indexOfValue(value) >= 0; + } + + /** + * Retrieve a value from the array. + * @param key The key of the value to retrieve. + * @return Returns the value associated with the given key, + * or null if there is no such key. + */ + @Override + public V get(Object key) { + final int index = indexOf(key, key.hashCode()); + return index >= 0 ? (V)mArray[(index<<1)+1] : null; + } + + /** + * Return the key at the given index in the array. + * @param index The desired index, must be between 0 and {@link #size()}-1. + * @return Returns the key stored at the given index. + */ + public K keyAt(int index) { + return (K)mArray[index << 1]; + } + + /** + * Return the value at the given index in the array. + * @param index The desired index, must be between 0 and {@link #size()}-1. + * @return Returns the value stored at the given index. + */ + public V valueAt(int index) { + return (V)mArray[(index << 1) + 1]; + } + + /** + * Set the value at a given index in the array. + * @param index The desired index, must be between 0 and {@link #size()}-1. + * @param value The new value to store at this index. + * @return Returns the previous value at the given index. + */ + public V setValueAt(int index, V value) { + index = (index << 1) + 1; + V old = (V)mArray[index]; + mArray[index] = value; + return old; + } + + /** + * Return true if the array map contains no items. + */ + @Override + public boolean isEmpty() { + return mSize <= 0; + } + + /** + * Add a new value to the array map. + * @param key The key under which to store the value. <b>Must not be null.</b> If + * this key already exists in the array, its value will be replaced. + * @param value The value to store for the given key. + * @return Returns the old value that was stored for the given key, or null if there + * was no such key. + */ + @Override + public V put(K key, V value) { + final int hash = key.hashCode(); + int index = indexOf(key, hash); + if (index >= 0) { + index = (index<<1) + 1; + final V old = (V)mArray[index]; + mArray[index] = value; + return old; + } + + index = ~index; + if (mSize >= mHashes.length) { + final int n = mSize >= (BASE_SIZE*2) ? (mSize+(mSize>>1)) + : (mSize >= BASE_SIZE ? (BASE_SIZE*2) : BASE_SIZE); + + if (DEBUG) Log.d(TAG, "put: grow from " + mHashes.length + " to " + n); + + final int[] ohashes = mHashes; + final Object[] oarray = mArray; + allocArrays(n); + + if (mHashes.length > 0) { + if (DEBUG) Log.d(TAG, "put: copy 0-" + mSize + " to 0"); + System.arraycopy(ohashes, 0, mHashes, 0, ohashes.length); + System.arraycopy(oarray, 0, mArray, 0, oarray.length); + } + + freeArrays(ohashes, oarray, mSize); + } + + if (index < mSize) { + if (DEBUG) Log.d(TAG, "put: move " + index + "-" + (mSize-index) + + " to " + (index+1)); + System.arraycopy(mHashes, index, mHashes, index + 1, mSize - index); + System.arraycopy(mArray, index << 1, mArray, (index + 1) << 1, (mSize - index) << 1); + } + + mHashes[index] = hash; + mArray[index<<1] = key; + mArray[(index<<1)+1] = value; + mSize++; + return null; + } + + /** + * Perform a {@link #put(Object, Object)} of all key/value pairs in <var>array</var> + * @param array The array whose contents are to be retrieved. + */ + public void putAll(ArrayMap<? extends K, ? extends V> array) { + final int N = array.mSize; + ensureCapacity(mSize + N); + for (int i=0; i<N; i++) { + put(array.keyAt(i), array.valueAt(i)); + } + } + + /** + * Remove an existing key from the array map. + * @param key The key of the mapping to remove. + * @return Returns the value that was stored under the key, or null if there + * was no such key. + */ + @Override + public V remove(Object key) { + int index = indexOf(key, key.hashCode()); + if (index >= 0) { + return removeAt(index); + } + + return null; + } + + /** + * Remove the key/value mapping at the given index. + * @param index The desired index, must be between 0 and {@link #size()}-1. + * @return Returns the value that was stored at this index. + */ + public V removeAt(int index) { + final V old = (V)mArray[(index << 1) + 1]; + if (mSize <= 1) { + // Now empty. + if (DEBUG) Log.d(TAG, "remove: shrink from " + mHashes.length + " to 0"); + freeArrays(mHashes, mArray, mSize); + mHashes = SparseArray.EMPTY_INTS; + mArray = SparseArray.EMPTY_OBJECTS; + mSize = 0; + } else { + if (mHashes.length > (BASE_SIZE*2) && mSize < mHashes.length/3) { + // Shrunk enough to reduce size of arrays. We don't allow it to + // shrink smaller than (BASE_SIZE*2) to avoid flapping between + // that and BASE_SIZE. + final int n = mSize > (BASE_SIZE*2) ? (mSize + (mSize>>1)) : (BASE_SIZE*2); + + if (DEBUG) Log.d(TAG, "remove: shrink from " + mHashes.length + " to " + n); + + final int[] ohashes = mHashes; + final Object[] oarray = mArray; + allocArrays(n); + + mSize--; + if (index > 0) { + if (DEBUG) Log.d(TAG, "remove: copy from 0-" + index + " to 0"); + System.arraycopy(ohashes, 0, mHashes, 0, index); + System.arraycopy(oarray, 0, mArray, 0, index << 1); + } + if (index < mSize) { + if (DEBUG) Log.d(TAG, "remove: copy from " + (index+1) + "-" + mSize + + " to " + index); + System.arraycopy(ohashes, index + 1, mHashes, index, mSize - index); + System.arraycopy(oarray, (index + 1) << 1, mArray, index << 1, + (mSize - index) << 1); + } + } else { + mSize--; + if (index < mSize) { + if (DEBUG) Log.d(TAG, "remove: move " + (index+1) + "-" + mSize + + " to " + index); + System.arraycopy(mHashes, index + 1, mHashes, index, mSize - index); + System.arraycopy(mArray, (index + 1) << 1, mArray, index << 1, + (mSize - index) << 1); + } + mArray[mSize << 1] = null; + mArray[(mSize << 1) + 1] = null; + } + } + return old; + } + + /** + * Return the number of items in this array map. + */ + @Override + public int size() { + return mSize; + } + + // ------------------------------------------------------------------------ + // Interop with traditional Java containers. Not as efficient as using + // specialized collection APIs. + // ------------------------------------------------------------------------ + + private MapCollections<K, V> getCollection() { + if (mCollections == null) { + mCollections = new MapCollections<K, V>() { + @Override + protected int colGetSize() { + return mSize; + } + + @Override + protected Object colGetEntry(int index, int offset) { + return mArray[(index<<1) + offset]; + } + + @Override + protected int colIndexOfKey(Object key) { + return indexOf(key, key.hashCode()); + } + + @Override + protected int colIndexOfValue(Object value) { + return indexOfValue(value); + } + + @Override + protected Map<K, V> colGetMap() { + return ArrayMap.this; + } + + @Override + protected void colPut(K key, V value) { + put(key, value); + } + + @Override + protected V colSetValue(int index, V value) { + return setValueAt(index, value); + } + + @Override + protected void colRemoveAt(int index) { + removeAt(index); + } + + @Override + protected void colClear() { + clear(); + } + }; + } + return mCollections; + } + + /** + * Determine if the array map contains all of the keys in the given collection. + * @param collection The collection whose contents are to be checked against. + * @return Returns true if this array map contains a key for every entry + * in <var>collection</var>, else returns false. + */ + public boolean containsAll(Collection<?> collection) { + return MapCollections.containsAllHelper(this, collection); + } + + /** + * Perform a {@link #put(Object, Object)} of all key/value pairs in <var>map</var> + * @param map The map whose contents are to be retrieved. + */ + @Override + public void putAll(Map<? extends K, ? extends V> map) { + ensureCapacity(mSize + map.size()); + for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) { + put(entry.getKey(), entry.getValue()); + } + } + + /** + * Remove all keys in the array map that exist in the given collection. + * @param collection The collection whose contents are to be used to remove keys. + * @return Returns true if any keys were removed from the array map, else false. + */ + public boolean removeAll(Collection<?> collection) { + return MapCollections.removeAllHelper(this, collection); + } + + /** + * Remove all keys in the array map that do <b>not</b> exist in the given collection. + * @param collection The collection whose contents are to be used to determine which + * keys to keep. + * @return Returns true if any keys were removed from the array map, else false. + */ + public boolean retainAll(Collection<?> collection) { + return MapCollections.retainAllHelper(this, collection); + } + + /** + * Return a {@link java.util.Set} for iterating over and interacting with all mappings + * in the array map. + * + * <p><b>Note:</b> this is a very inefficient way to access the array contents, it + * requires generating a number of temporary objects.</p> + * + * <p><b>Note:</b></p> the semantics of this + * Set are subtly different than that of a {@link java.util.HashMap}: most important, + * the {@link java.util.Map.Entry Map.Entry} object returned by its iterator is a single + * object that exists for the entire iterator, so you can <b>not</b> hold on to it + * after calling {@link java.util.Iterator#next() Iterator.next}.</p> + */ + @Override + public Set<Map.Entry<K, V>> entrySet() { + return getCollection().getEntrySet(); + } + + /** + * Return a {@link java.util.Set} for iterating over and interacting with all keys + * in the array map. + * + * <p><b>Note:</b> this is a fair inefficient way to access the array contents, it + * requires generating a number of temporary objects.</p> + */ + @Override + public Set<K> keySet() { + return getCollection().getKeySet(); + } + + /** + * Return a {@link java.util.Collection} for iterating over and interacting with all values + * in the array map. + * + * <p><b>Note:</b> this is a fair inefficient way to access the array contents, it + * requires generating a number of temporary objects.</p> + */ + @Override + public Collection<V> values() { + return getCollection().getValues(); + } +} diff --git a/core/java/android/util/LongSparseArray.java b/core/java/android/util/LongSparseArray.java index 630e5f3..660b743 100644 --- a/core/java/android/util/LongSparseArray.java +++ b/core/java/android/util/LongSparseArray.java @@ -41,13 +41,19 @@ public class LongSparseArray<E> implements Cloneable { /** * Creates a new LongSparseArray containing no mappings that will not * require any additional memory allocation to store the specified - * number of mappings. + * number of mappings. If you supply an initial capacity of 0, the + * sparse array will be initialized with a light-weight representation + * not requiring any additional array allocations. */ public LongSparseArray(int initialCapacity) { - initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity); - - mKeys = new long[initialCapacity]; - mValues = new Object[initialCapacity]; + if (initialCapacity == 0) { + mKeys = SparseLongArray.EMPTY_LONGS; + mValues = SparseArray.EMPTY_OBJECTS; + } else { + initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity); + mKeys = new long[initialCapacity]; + mValues = new Object[initialCapacity]; + } mSize = 0; } diff --git a/core/java/android/util/LongSparseLongArray.java b/core/java/android/util/LongSparseLongArray.java index 34b6126..503295c 100644 --- a/core/java/android/util/LongSparseLongArray.java +++ b/core/java/android/util/LongSparseLongArray.java @@ -42,13 +42,19 @@ public class LongSparseLongArray implements Cloneable { /** * Creates a new SparseLongArray containing no mappings that will not * require any additional memory allocation to store the specified - * number of mappings. + * number of mappings. If you supply an initial capacity of 0, the + * sparse array will be initialized with a light-weight representation + * not requiring any additional array allocations. */ public LongSparseLongArray(int initialCapacity) { - initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity); - - mKeys = new long[initialCapacity]; - mValues = new long[initialCapacity]; + if (initialCapacity == 0) { + mKeys = SparseLongArray.EMPTY_LONGS; + mValues = SparseLongArray.EMPTY_LONGS; + } else { + initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity); + mKeys = new long[initialCapacity]; + mValues = new long[initialCapacity]; + } mSize = 0; } diff --git a/core/java/android/util/MapCollections.java b/core/java/android/util/MapCollections.java new file mode 100644 index 0000000..f29fb65 --- /dev/null +++ b/core/java/android/util/MapCollections.java @@ -0,0 +1,496 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.util; + +import libcore.util.Objects; + +import java.lang.reflect.Array; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +/** + * Helper for writing standard Java collection interfaces to a data + * structure like {@link ArrayMap}. + * @hide + */ +abstract class MapCollections<K, V> { + EntrySet mEntrySet; + KeySet mKeySet; + ValuesCollection mValues; + + final class ArrayIterator<T> implements Iterator<T> { + final int mOffset; + int mSize; + int mIndex; + boolean mCanRemove = false; + + ArrayIterator(int offset) { + mOffset = offset; + mSize = colGetSize(); + } + + @Override + public boolean hasNext() { + return mIndex < mSize; + } + + @Override + public T next() { + Object res = colGetEntry(mIndex, mOffset); + mIndex++; + mCanRemove = true; + return (T)res; + } + + @Override + public void remove() { + if (!mCanRemove) { + throw new IllegalStateException(); + } + mIndex--; + mSize--; + mCanRemove = false; + colRemoveAt(mIndex); + } + } + + final class MapIterator implements Iterator<Map.Entry<K, V>>, Map.Entry<K, V> { + int mEnd; + int mIndex; + boolean mEntryValid = false; + + MapIterator() { + mEnd = colGetSize() - 1; + mIndex = -1; + } + + @Override + public boolean hasNext() { + return mIndex < mEnd; + } + + @Override + public Map.Entry<K, V> next() { + mIndex++; + mEntryValid = true; + return this; + } + + @Override + public void remove() { + if (!mEntryValid) { + throw new IllegalStateException(); + } + mIndex--; + mEnd--; + mEntryValid = false; + colRemoveAt(mIndex); + } + + @Override + public K getKey() { + if (!mEntryValid) { + throw new IllegalStateException( + "This container does not support retaining Map.Entry objects"); + } + return (K)colGetEntry(mIndex, 0); + } + + @Override + public V getValue() { + if (!mEntryValid) { + throw new IllegalStateException( + "This container does not support retaining Map.Entry objects"); + } + return (V)colGetEntry(mIndex, 1); + } + + @Override + public V setValue(V object) { + if (!mEntryValid) { + throw new IllegalStateException( + "This container does not support retaining Map.Entry objects"); + } + return colSetValue(mIndex, object); + } + + @Override + public final boolean equals(Object o) { + if (!mEntryValid) { + throw new IllegalStateException( + "This container does not support retaining Map.Entry objects"); + } + if (!(o instanceof Map.Entry)) { + return false; + } + Map.Entry<?, ?> e = (Map.Entry<?, ?>) o; + return Objects.equal(e.getKey(), colGetEntry(mIndex, 0)) + && Objects.equal(e.getValue(), colGetEntry(mIndex, 1)); + } + + @Override + public final int hashCode() { + if (!mEntryValid) { + throw new IllegalStateException( + "This container does not support retaining Map.Entry objects"); + } + final Object key = colGetEntry(mIndex, 0); + final Object value = colGetEntry(mIndex, 1); + return (key == null ? 0 : key.hashCode()) ^ + (value == null ? 0 : value.hashCode()); + } + + @Override + public final String toString() { + return getKey() + "=" + getValue(); + } + } + + final class EntrySet implements Set<Map.Entry<K, V>> { + @Override + public boolean add(Map.Entry<K, V> object) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(Collection<? extends Map.Entry<K, V>> collection) { + int oldSize = colGetSize(); + for (Map.Entry<K, V> entry : collection) { + colPut(entry.getKey(), entry.getValue()); + } + return oldSize != colGetSize(); + } + + @Override + public void clear() { + colClear(); + } + + @Override + public boolean contains(Object object) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean containsAll(Collection<?> collection) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isEmpty() { + return colGetSize() == 0; + } + + @Override + public Iterator<Map.Entry<K, V>> iterator() { + return new MapIterator(); + } + + @Override + public boolean remove(Object object) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean removeAll(Collection<?> collection) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean retainAll(Collection<?> collection) { + throw new UnsupportedOperationException(); + } + + @Override + public int size() { + return colGetSize(); + } + + @Override + public Object[] toArray() { + throw new UnsupportedOperationException(); + } + + @Override + public <T> T[] toArray(T[] array) { + throw new UnsupportedOperationException(); + } + }; + + final class KeySet implements Set<K> { + + @Override + public boolean add(K object) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(Collection<? extends K> collection) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + colClear(); + } + + @Override + public boolean contains(Object object) { + return colIndexOfKey(object) >= 0; + } + + @Override + public boolean containsAll(Collection<?> collection) { + return removeAllHelper(colGetMap(), collection); + } + + @Override + public boolean isEmpty() { + return colGetSize() == 0; + } + + @Override + public Iterator<K> iterator() { + return new ArrayIterator<K>(0); + } + + @Override + public boolean remove(Object object) { + int index = colIndexOfKey(object); + if (index >= 0) { + colRemoveAt(index); + return true; + } + return false; + } + + @Override + public boolean removeAll(Collection<?> collection) { + return removeAllHelper(colGetMap(), collection); + } + + @Override + public boolean retainAll(Collection<?> collection) { + return retainAllHelper(colGetMap(), collection); + } + + @Override + public int size() { + return colGetSize(); + } + + @Override + public Object[] toArray() { + return toArrayHelper(1); + } + + @Override + public <T> T[] toArray(T[] array) { + return toArrayHelper(array, 1); + } + }; + + final class ValuesCollection implements Collection<V> { + + @Override + public boolean add(V object) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(Collection<? extends V> collection) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + colClear(); + } + + @Override + public boolean contains(Object object) { + return colIndexOfValue(object) >= 0; + } + + @Override + public boolean containsAll(Collection<?> collection) { + Iterator<?> it = collection.iterator(); + while (it.hasNext()) { + if (!contains(it.next())) { + return false; + } + } + return true; + } + + @Override + public boolean isEmpty() { + return colGetSize() == 0; + } + + @Override + public Iterator<V> iterator() { + return new ArrayIterator<V>(1); + } + + @Override + public boolean remove(Object object) { + int index = colIndexOfValue(object); + if (index >= 0) { + colRemoveAt(index); + return true; + } + return false; + } + + @Override + public boolean removeAll(Collection<?> collection) { + int N = colGetSize(); + boolean changed = false; + for (int i=0; i<N; i++) { + Object cur = colGetEntry(i, 1); + if (collection.contains(cur)) { + colRemoveAt(i); + i--; + N--; + changed = true; + } + } + return changed; + } + + @Override + public boolean retainAll(Collection<?> collection) { + int N = colGetSize(); + boolean changed = false; + for (int i=0; i<N; i++) { + Object cur = colGetEntry(i, 1); + if (!collection.contains(cur)) { + colRemoveAt(i); + i--; + N--; + changed = true; + } + } + return changed; + } + + @Override + public int size() { + return colGetSize(); + } + + @Override + public Object[] toArray() { + return toArrayHelper(1); + } + + @Override + public <T> T[] toArray(T[] array) { + return toArrayHelper(array, 1); + } + }; + + public static <K, V> boolean containsAllHelper(Map<K, V> map, Collection<?> collection) { + Iterator<?> it = collection.iterator(); + while (it.hasNext()) { + if (!map.containsKey(it.next())) { + return false; + } + } + return true; + } + + public static <K, V> boolean removeAllHelper(Map<K, V> map, Collection<?> collection) { + int oldSize = map.size(); + Iterator<?> it = collection.iterator(); + while (it.hasNext()) { + map.remove(it.next()); + } + return oldSize != map.size(); + } + + public static <K, V> boolean retainAllHelper(Map<K, V> map, Collection<?> collection) { + int oldSize = map.size(); + Iterator<K> it = map.keySet().iterator(); + while (it.hasNext()) { + if (!collection.contains(it.next())) { + it.remove(); + } + } + return oldSize != map.size(); + } + + + public Object[] toArrayHelper(int offset) { + final int N = colGetSize(); + Object[] result = new Object[N]; + for (int i=0; i<N; i++) { + result[i] = colGetEntry(i, offset); + } + return result; + } + + public <T> T[] toArrayHelper(T[] array, int offset) { + final int N = colGetSize(); + if (array.length < N) { + @SuppressWarnings("unchecked") T[] newArray + = (T[]) Array.newInstance(array.getClass().getComponentType(), N); + array = newArray; + } + for (int i=0; i<N; i++) { + array[i] = (T)colGetEntry(i, offset); + } + if (array.length > N) { + array[N] = null; + } + return array; + } + + public Set<Map.Entry<K, V>> getEntrySet() { + if (mEntrySet == null) { + mEntrySet = new EntrySet(); + } + return mEntrySet; + } + + public Set<K> getKeySet() { + if (mKeySet == null) { + mKeySet = new KeySet(); + } + return mKeySet; + } + + public Collection<V> getValues() { + if (mValues == null) { + mValues = new ValuesCollection(); + } + return mValues; + } + + protected abstract int colGetSize(); + protected abstract Object colGetEntry(int index, int offset); + protected abstract int colIndexOfKey(Object key); + protected abstract int colIndexOfValue(Object key); + protected abstract Map<K, V> colGetMap(); + protected abstract void colPut(K key, V value); + protected abstract V colSetValue(int index, V value); + protected abstract void colRemoveAt(int index); + protected abstract void colClear(); +} diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java index 7e8fee5..001fc5b 100644 --- a/core/java/android/util/SparseArray.java +++ b/core/java/android/util/SparseArray.java @@ -25,6 +25,8 @@ import com.android.internal.util.ArrayUtils; */ public class SparseArray<E> implements Cloneable { private static final Object DELETED = new Object(); + static final int[] EMPTY_INTS = new int[0]; + static final Object[] EMPTY_OBJECTS = new Object[0]; private boolean mGarbage = false; private int[] mKeys; @@ -41,13 +43,19 @@ public class SparseArray<E> implements Cloneable { /** * Creates a new SparseArray containing no mappings that will not * require any additional memory allocation to store the specified - * number of mappings. + * number of mappings. If you supply an initial capacity of 0, the + * sparse array will be initialized with a light-weight representation + * not requiring any additional array allocations. */ public SparseArray(int initialCapacity) { - initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity); - - mKeys = new int[initialCapacity]; - mValues = new Object[initialCapacity]; + if (initialCapacity == 0) { + mKeys = EMPTY_INTS; + mValues = EMPTY_OBJECTS; + } else { + initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity); + mKeys = new int[initialCapacity]; + mValues = new Object[initialCapacity]; + } mSize = 0; } @@ -79,7 +87,7 @@ public class SparseArray<E> implements Cloneable { */ @SuppressWarnings("unchecked") public E get(int key, E valueIfKeyNotFound) { - int i = binarySearch(mKeys, 0, mSize, key); + int i = binarySearch(mKeys, mSize, key); if (i < 0 || mValues[i] == DELETED) { return valueIfKeyNotFound; @@ -92,7 +100,7 @@ public class SparseArray<E> implements Cloneable { * Removes the mapping from the specified key, if there was any. */ public void delete(int key) { - int i = binarySearch(mKeys, 0, mSize, key); + int i = binarySearch(mKeys, mSize, key); if (i >= 0) { if (mValues[i] != DELETED) { @@ -153,7 +161,7 @@ public class SparseArray<E> implements Cloneable { * was one. */ public void put(int key, E value) { - int i = binarySearch(mKeys, 0, mSize, key); + int i = binarySearch(mKeys, mSize, key); if (i >= 0) { mValues[i] = value; @@ -170,7 +178,7 @@ public class SparseArray<E> implements Cloneable { gc(); // Search again because indices may have changed. - i = ~binarySearch(mKeys, 0, mSize, key); + i = ~binarySearch(mKeys, mSize, key); } if (mSize >= mKeys.length) { @@ -261,7 +269,7 @@ public class SparseArray<E> implements Cloneable { gc(); } - return binarySearch(mKeys, 0, mSize, key); + return binarySearch(mKeys, mSize, key); } /** @@ -335,23 +343,23 @@ public class SparseArray<E> implements Cloneable { mSize = pos + 1; } - private static int binarySearch(int[] a, int start, int len, int key) { - int high = start + len, low = start - 1, guess; - - while (high - low > 1) { - guess = (high + low) / 2; - - if (a[guess] < key) - low = guess; - else - high = guess; + // This is Arrays.binarySearch(), but doesn't do any argument validation. + static int binarySearch(int[] array, int size, int value) { + int lo = 0; + int hi = size - 1; + + while (lo <= hi) { + int mid = (lo + hi) >>> 1; + int midVal = array[mid]; + + if (midVal < value) { + lo = mid + 1; + } else if (midVal > value) { + hi = mid - 1; + } else { + return mid; // value found + } } - - if (high == start + len) - return ~(start + len); - else if (a[high] == key) - return high; - else - return ~high; + return ~lo; // value not present } } diff --git a/core/java/android/util/SparseBooleanArray.java b/core/java/android/util/SparseBooleanArray.java index 76c47c6..73e3629 100644 --- a/core/java/android/util/SparseBooleanArray.java +++ b/core/java/android/util/SparseBooleanArray.java @@ -25,6 +25,8 @@ import com.android.internal.util.ArrayUtils; * than using a HashMap to map Integers to Booleans. */ public class SparseBooleanArray implements Cloneable { + static final boolean[] EMPTY_BOOLEANS = new boolean[0]; + /** * Creates a new SparseBooleanArray containing no mappings. */ @@ -35,13 +37,19 @@ public class SparseBooleanArray implements Cloneable { /** * Creates a new SparseBooleanArray containing no mappings that will not * require any additional memory allocation to store the specified - * number of mappings. + * number of mappings. If you supply an initial capacity of 0, the + * sparse array will be initialized with a light-weight representation + * not requiring any additional array allocations. */ public SparseBooleanArray(int initialCapacity) { - initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity); - - mKeys = new int[initialCapacity]; - mValues = new boolean[initialCapacity]; + if (initialCapacity == 0) { + mKeys = SparseArray.EMPTY_INTS; + mValues = EMPTY_BOOLEANS; + } else { + initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity); + mKeys = new int[initialCapacity]; + mValues = new boolean[initialCapacity]; + } mSize = 0; } @@ -71,7 +79,7 @@ public class SparseBooleanArray implements Cloneable { * if no such mapping has been made. */ public boolean get(int key, boolean valueIfKeyNotFound) { - int i = binarySearch(mKeys, 0, mSize, key); + int i = SparseArray.binarySearch(mKeys, mSize, key); if (i < 0) { return valueIfKeyNotFound; @@ -84,7 +92,7 @@ public class SparseBooleanArray implements Cloneable { * Removes the mapping from the specified key, if there was any. */ public void delete(int key) { - int i = binarySearch(mKeys, 0, mSize, key); + int i = SparseArray.binarySearch(mKeys, mSize, key); if (i >= 0) { System.arraycopy(mKeys, i + 1, mKeys, i, mSize - (i + 1)); @@ -99,7 +107,7 @@ public class SparseBooleanArray implements Cloneable { * was one. */ public void put(int key, boolean value) { - int i = binarySearch(mKeys, 0, mSize, key); + int i = SparseArray.binarySearch(mKeys, mSize, key); if (i >= 0) { mValues[i] = value; @@ -164,7 +172,7 @@ public class SparseBooleanArray implements Cloneable { * key is not mapped. */ public int indexOfKey(int key) { - return binarySearch(mKeys, 0, mSize, key); + return SparseArray.binarySearch(mKeys, mSize, key); } /** @@ -220,26 +228,6 @@ public class SparseBooleanArray implements Cloneable { mSize = pos + 1; } - private static int binarySearch(int[] a, int start, int len, int key) { - int high = start + len, low = start - 1, guess; - - while (high - low > 1) { - guess = (high + low) / 2; - - if (a[guess] < key) - low = guess; - else - high = guess; - } - - if (high == start + len) - return ~(start + len); - else if (a[high] == key) - return high; - else - return ~high; - } - private int[] mKeys; private boolean[] mValues; private int mSize; diff --git a/core/java/android/util/SparseIntArray.java b/core/java/android/util/SparseIntArray.java index 8d11177..122f7f5 100644 --- a/core/java/android/util/SparseIntArray.java +++ b/core/java/android/util/SparseIntArray.java @@ -24,7 +24,6 @@ import com.android.internal.util.ArrayUtils; * than using a HashMap to map Integers to Integers. */ public class SparseIntArray implements Cloneable { - private int[] mKeys; private int[] mValues; private int mSize; @@ -39,13 +38,19 @@ public class SparseIntArray implements Cloneable { /** * Creates a new SparseIntArray containing no mappings that will not * require any additional memory allocation to store the specified - * number of mappings. + * number of mappings. If you supply an initial capacity of 0, the + * sparse array will be initialized with a light-weight representation + * not requiring any additional array allocations. */ public SparseIntArray(int initialCapacity) { - initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity); - - mKeys = new int[initialCapacity]; - mValues = new int[initialCapacity]; + if (initialCapacity == 0) { + mKeys = SparseArray.EMPTY_INTS; + mValues = SparseArray.EMPTY_INTS; + } else { + initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity); + mKeys = new int[initialCapacity]; + mValues = new int[initialCapacity]; + } mSize = 0; } @@ -75,7 +80,7 @@ public class SparseIntArray implements Cloneable { * if no such mapping has been made. */ public int get(int key, int valueIfKeyNotFound) { - int i = binarySearch(mKeys, 0, mSize, key); + int i = SparseArray.binarySearch(mKeys, mSize, key); if (i < 0) { return valueIfKeyNotFound; @@ -88,7 +93,7 @@ public class SparseIntArray implements Cloneable { * Removes the mapping from the specified key, if there was any. */ public void delete(int key) { - int i = binarySearch(mKeys, 0, mSize, key); + int i = SparseArray.binarySearch(mKeys, mSize, key); if (i >= 0) { removeAt(i); @@ -110,7 +115,7 @@ public class SparseIntArray implements Cloneable { * was one. */ public void put(int key, int value) { - int i = binarySearch(mKeys, 0, mSize, key); + int i = SparseArray.binarySearch(mKeys, mSize, key); if (i >= 0) { mValues[i] = value; @@ -175,7 +180,7 @@ public class SparseIntArray implements Cloneable { * key is not mapped. */ public int indexOfKey(int key) { - return binarySearch(mKeys, 0, mSize, key); + return SparseArray.binarySearch(mKeys, mSize, key); } /** @@ -230,24 +235,4 @@ public class SparseIntArray implements Cloneable { mValues[pos] = value; mSize = pos + 1; } - - private static int binarySearch(int[] a, int start, int len, int key) { - int high = start + len, low = start - 1, guess; - - while (high - low > 1) { - guess = (high + low) / 2; - - if (a[guess] < key) - low = guess; - else - high = guess; - } - - if (high == start + len) - return ~(start + len); - else if (a[high] == key) - return high; - else - return ~high; - } } diff --git a/core/java/android/util/SparseLongArray.java b/core/java/android/util/SparseLongArray.java index 2f7a6fe..c608996 100644 --- a/core/java/android/util/SparseLongArray.java +++ b/core/java/android/util/SparseLongArray.java @@ -24,6 +24,7 @@ import com.android.internal.util.ArrayUtils; * than using a HashMap to map Integers to Longs. */ public class SparseLongArray implements Cloneable { + static final long[] EMPTY_LONGS = new long[0]; private int[] mKeys; private long[] mValues; @@ -39,13 +40,19 @@ public class SparseLongArray implements Cloneable { /** * Creates a new SparseLongArray containing no mappings that will not * require any additional memory allocation to store the specified - * number of mappings. + * number of mappings. If you supply an initial capacity of 0, the + * sparse array will be initialized with a light-weight representation + * not requiring any additional array allocations. */ public SparseLongArray(int initialCapacity) { - initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity); - - mKeys = new int[initialCapacity]; - mValues = new long[initialCapacity]; + if (initialCapacity == 0) { + mKeys = SparseArray.EMPTY_INTS; + mValues = EMPTY_LONGS; + } else { + initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity); + mKeys = new int[initialCapacity]; + mValues = new long[initialCapacity]; + } mSize = 0; } @@ -75,7 +82,7 @@ public class SparseLongArray implements Cloneable { * if no such mapping has been made. */ public long get(int key, long valueIfKeyNotFound) { - int i = binarySearch(mKeys, 0, mSize, key); + int i = SparseArray.binarySearch(mKeys, mSize, key); if (i < 0) { return valueIfKeyNotFound; @@ -88,7 +95,7 @@ public class SparseLongArray implements Cloneable { * Removes the mapping from the specified key, if there was any. */ public void delete(int key) { - int i = binarySearch(mKeys, 0, mSize, key); + int i = SparseArray.binarySearch(mKeys, mSize, key); if (i >= 0) { removeAt(i); @@ -110,7 +117,7 @@ public class SparseLongArray implements Cloneable { * was one. */ public void put(int key, long value) { - int i = binarySearch(mKeys, 0, mSize, key); + int i = SparseArray.binarySearch(mKeys, mSize, key); if (i >= 0) { mValues[i] = value; @@ -164,7 +171,7 @@ public class SparseLongArray implements Cloneable { * key is not mapped. */ public int indexOfKey(int key) { - return binarySearch(mKeys, 0, mSize, key); + return SparseArray.binarySearch(mKeys, mSize, key); } /** @@ -222,24 +229,4 @@ public class SparseLongArray implements Cloneable { mKeys = nkeys; mValues = nvalues; } - - private static int binarySearch(int[] a, int start, int len, long key) { - int high = start + len, low = start - 1, guess; - - while (high - low > 1) { - guess = (high + low) / 2; - - if (a[guess] < key) - low = guess; - else - high = guess; - } - - if (high == start + len) - return ~(start + len); - else if (a[high] == key) - return high; - else - return ~high; - } } diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index 2ec9a7d..cc7d948 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -21,6 +21,7 @@ import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.DrawFilter; import android.graphics.Matrix; +import android.graphics.NinePatch; import android.graphics.Paint; import android.graphics.PaintFlagsDrawFilter; import android.graphics.Path; @@ -273,6 +274,18 @@ class GLES20Canvas extends HardwareCanvas { private static native int nGetStencilSize(); + void setCountOverdrawEnabled(boolean enabled) { + nSetCountOverdrawEnabled(mRenderer, enabled); + } + + static native void nSetCountOverdrawEnabled(int renderer, boolean enabled); + + float getOverdraw() { + return nGetOverdraw(mRenderer); + } + + static native float nGetOverdraw(int renderer); + /////////////////////////////////////////////////////////////////////////// // Functor /////////////////////////////////////////////////////////////////////////// @@ -314,21 +327,21 @@ class GLES20Canvas extends HardwareCanvas { * * @see #flushCaches(int) */ - public static final int FLUSH_CACHES_LAYERS = 0; + static final int FLUSH_CACHES_LAYERS = 0; /** * Must match Caches::FlushMode values * * @see #flushCaches(int) */ - public static final int FLUSH_CACHES_MODERATE = 1; + static final int FLUSH_CACHES_MODERATE = 1; /** * Must match Caches::FlushMode values * * @see #flushCaches(int) */ - public static final int FLUSH_CACHES_FULL = 2; + static final int FLUSH_CACHES_FULL = 2; /** * Flush caches to reclaim as much memory as possible. The amount of memory @@ -338,10 +351,8 @@ class GLES20Canvas extends HardwareCanvas { * {@link #FLUSH_CACHES_FULL}. * * @param level Hint about the amount of memory to reclaim - * - * @hide */ - public static void flushCaches(int level) { + static void flushCaches(int level) { nFlushCaches(level); } @@ -353,21 +364,28 @@ class GLES20Canvas extends HardwareCanvas { * * @hide */ - public static void terminateCaches() { + static void terminateCaches() { nTerminateCaches(); } private static native void nTerminateCaches(); - /** - * @hide - */ - public static void initCaches() { - nInitCaches(); + static boolean initCaches() { + return nInitCaches(); } - private static native void nInitCaches(); - + private static native boolean nInitCaches(); + + /////////////////////////////////////////////////////////////////////////// + // Atlas + /////////////////////////////////////////////////////////////////////////// + + static void initAtlas(GraphicBuffer buffer, int[] map) { + nInitAtlas(buffer, map, map.length); + } + + private static native void nInitAtlas(GraphicBuffer buffer, int[] map, int count); + /////////////////////////////////////////////////////////////////////////// // Display list /////////////////////////////////////////////////////////////////////////// @@ -718,20 +736,21 @@ class GLES20Canvas extends HardwareCanvas { } @Override - public void drawPatch(Bitmap bitmap, byte[] chunks, RectF dst, Paint paint) { + public void drawPatch(NinePatch patch, RectF dst, Paint paint) { + Bitmap bitmap = patch.getBitmap(); if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps"); // Shaders are ignored when drawing patches int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE; try { final int nativePaint = paint == null ? 0 : paint.mNativePaint; - nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, chunks, + nDrawPatch(mRenderer, bitmap.mNativeBitmap, patch.mChunk, dst.left, dst.top, dst.right, dst.bottom, nativePaint); } finally { if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier); } } - private static native void nDrawPatch(int renderer, int bitmap, byte[] buffer, byte[] chunks, + private static native void nDrawPatch(int renderer, int bitmap, byte[] chunks, float left, float top, float right, float bottom, int paint); @Override @@ -741,14 +760,14 @@ class GLES20Canvas extends HardwareCanvas { int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE; try { final int nativePaint = paint == null ? 0 : paint.mNativePaint; - nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, nativePaint); + nDrawBitmap(mRenderer, bitmap.mNativeBitmap, left, top, nativePaint); } finally { if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); } } - private static native void nDrawBitmap( - int renderer, int bitmap, byte[] buffer, float left, float top, int paint); + private static native void nDrawBitmap(int renderer, int bitmap, + float left, float top, int paint); @Override public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) { @@ -757,15 +776,13 @@ class GLES20Canvas extends HardwareCanvas { int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE; try { final int nativePaint = paint == null ? 0 : paint.mNativePaint; - nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, - matrix.native_instance, nativePaint); + nDrawBitmap(mRenderer, bitmap.mNativeBitmap, matrix.native_instance, nativePaint); } finally { if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); } } - private static native void nDrawBitmap(int renderer, int bitmap, byte[] buff, - int matrix, int paint); + private static native void nDrawBitmap(int renderer, int bitmap, int matrix, int paint); @Override public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) { @@ -787,7 +804,7 @@ class GLES20Canvas extends HardwareCanvas { bottom = src.bottom; } - nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom, + nDrawBitmap(mRenderer, bitmap.mNativeBitmap, left, top, right, bottom, dst.left, dst.top, dst.right, dst.bottom, nativePaint); } finally { if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); @@ -814,14 +831,14 @@ class GLES20Canvas extends HardwareCanvas { bottom = src.bottom; } - nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom, + nDrawBitmap(mRenderer, bitmap.mNativeBitmap, left, top, right, bottom, dst.left, dst.top, dst.right, dst.bottom, nativePaint); } finally { if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); } } - private static native void nDrawBitmap(int renderer, int bitmap, byte[] buffer, + private static native void nDrawBitmap(int renderer, int bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float left, float top, float right, float bottom, int paint); @@ -891,14 +908,14 @@ class GLES20Canvas extends HardwareCanvas { int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE; try { final int nativePaint = paint == null ? 0 : paint.mNativePaint; - nDrawBitmapMesh(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, meshWidth, meshHeight, + nDrawBitmapMesh(mRenderer, bitmap.mNativeBitmap, meshWidth, meshHeight, verts, vertOffset, colors, colorOffset, nativePaint); } finally { if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); } } - private static native void nDrawBitmapMesh(int renderer, int bitmap, byte[] buffer, + private static native void nDrawBitmapMesh(int renderer, int bitmap, int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset, int paint); diff --git a/core/java/android/view/GLES20DisplayList.java b/core/java/android/view/GLES20DisplayList.java index 3272504..d367267 100644 --- a/core/java/android/view/GLES20DisplayList.java +++ b/core/java/android/view/GLES20DisplayList.java @@ -18,6 +18,7 @@ package android.view; import android.graphics.Bitmap; import android.graphics.Matrix; +import android.graphics.NinePatch; import java.util.ArrayList; @@ -29,7 +30,8 @@ class GLES20DisplayList extends DisplayList { // alive as long as the DisplayList is alive. The Bitmap and DisplayList lists // are populated by the GLES20RecordingCanvas during appropriate drawing calls and are // cleared at the start of a new drawing frame or when the view is detached from the window. - final ArrayList<Bitmap> mBitmaps = new ArrayList<Bitmap>(5); + final ArrayList<Bitmap> mBitmaps = new ArrayList<Bitmap>(10); + final ArrayList<NinePatch> mNinePatches = new ArrayList<NinePatch>(10); final ArrayList<DisplayList> mChildDisplayLists = new ArrayList<DisplayList>(); private GLES20RecordingCanvas mCanvas; @@ -83,7 +85,12 @@ class GLES20DisplayList extends DisplayList { } mValid = false; + clearReferences(); + } + + void clearReferences() { mBitmaps.clear(); + mNinePatches.clear(); mChildDisplayLists.clear(); } diff --git a/core/java/android/view/GLES20RecordingCanvas.java b/core/java/android/view/GLES20RecordingCanvas.java index 7da2451..ec059d5 100644 --- a/core/java/android/view/GLES20RecordingCanvas.java +++ b/core/java/android/view/GLES20RecordingCanvas.java @@ -19,6 +19,7 @@ package android.view; import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Matrix; +import android.graphics.NinePatch; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Rect; @@ -62,8 +63,7 @@ class GLES20RecordingCanvas extends GLES20Canvas { } void start() { - mDisplayList.mBitmaps.clear(); - mDisplayList.mChildDisplayLists.clear(); + mDisplayList.clearReferences(); } int end(int nativeDisplayList) { @@ -80,9 +80,10 @@ class GLES20RecordingCanvas extends GLES20Canvas { } @Override - public void drawPatch(Bitmap bitmap, byte[] chunks, RectF dst, Paint paint) { - super.drawPatch(bitmap, chunks, dst, paint); - mDisplayList.mBitmaps.add(bitmap); + public void drawPatch(NinePatch patch, RectF dst, Paint paint) { + super.drawPatch(patch, dst, paint); + mDisplayList.mBitmaps.add(patch.getBitmap()); + mDisplayList.mNinePatches.add(patch); // Shaders in the Paint are ignored when drawing a Bitmap } diff --git a/core/java/android/view/GLES20RenderLayer.java b/core/java/android/view/GLES20RenderLayer.java index 685dc70..68ba77c 100644 --- a/core/java/android/view/GLES20RenderLayer.java +++ b/core/java/android/view/GLES20RenderLayer.java @@ -100,12 +100,17 @@ class GLES20RenderLayer extends GLES20Layer { @Override HardwareCanvas start(Canvas currentCanvas) { + return start(currentCanvas, null); + } + + @Override + HardwareCanvas start(Canvas currentCanvas, Rect dirty) { if (currentCanvas instanceof GLES20Canvas) { ((GLES20Canvas) currentCanvas).interrupt(); } HardwareCanvas canvas = getCanvas(); canvas.setViewport(mWidth, mHeight); - canvas.onPreDraw(null); + canvas.onPreDraw(dirty); return canvas; } diff --git a/core/java/android/view/GLES20TextureLayer.java b/core/java/android/view/GLES20TextureLayer.java index e863e49..a4cc630 100644 --- a/core/java/android/view/GLES20TextureLayer.java +++ b/core/java/android/view/GLES20TextureLayer.java @@ -63,6 +63,11 @@ class GLES20TextureLayer extends GLES20Layer { } @Override + HardwareCanvas start(Canvas currentCanvas, Rect dirty) { + return null; + } + + @Override void end(Canvas currentCanvas) { } diff --git a/core/java/android/view/GraphicBuffer.aidl b/core/java/android/view/GraphicBuffer.aidl new file mode 100644 index 0000000..6dc6bed --- /dev/null +++ b/core/java/android/view/GraphicBuffer.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +parcelable GraphicBuffer; diff --git a/core/java/android/view/GraphicBuffer.java b/core/java/android/view/GraphicBuffer.java new file mode 100644 index 0000000..b4576f3 --- /dev/null +++ b/core/java/android/view/GraphicBuffer.java @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +import android.graphics.Canvas; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Simple wrapper for the native GraphicBuffer class. + * + * @hide + */ +@SuppressWarnings("UnusedDeclaration") +public class GraphicBuffer implements Parcelable { + // Note: keep usage flags in sync with GraphicBuffer.h and gralloc.h + public static final int USAGE_SW_READ_NEVER = 0x0; + public static final int USAGE_SW_READ_RARELY = 0x2; + public static final int USAGE_SW_READ_OFTEN = 0x3; + public static final int USAGE_SW_READ_MASK = 0xF; + + public static final int USAGE_SW_WRITE_NEVER = 0x0; + public static final int USAGE_SW_WRITE_RARELY = 0x20; + public static final int USAGE_SW_WRITE_OFTEN = 0x30; + public static final int USAGE_SW_WRITE_MASK = 0xF0; + + public static final int USAGE_SOFTWARE_MASK = USAGE_SW_READ_MASK | USAGE_SW_WRITE_MASK; + + public static final int USAGE_PROTECTED = 0x4000; + + public static final int USAGE_HW_TEXTURE = 0x100; + public static final int USAGE_HW_RENDER = 0x200; + public static final int USAGE_HW_2D = 0x400; + public static final int USAGE_HW_COMPOSER = 0x800; + public static final int USAGE_HW_VIDEO_ENCODER = 0x10000; + public static final int USAGE_HW_MASK = 0x71F00; + + private final int mWidth; + private final int mHeight; + private final int mFormat; + private final int mUsage; + // Note: do not rename, this field is used by native code + private final int mNativeObject; + + // These two fields are only used by lock/unlockCanvas() + private Canvas mCanvas; + private int mSaveCount; + + /** + * Creates new <code>GraphicBuffer</code> instance. This method will return null + * if the buffer cannot be created. + * + * @param width The width in pixels of the buffer + * @param height The height in pixels of the buffer + * @param format The format of each pixel as specified in {@link PixelFormat} + * @param usage Hint indicating how the buffer will be used + * + * @return A <code>GraphicBuffer</code> instance or null + */ + public static GraphicBuffer create(int width, int height, int format, int usage) { + int nativeObject = nCreateGraphicBuffer(width, height, format, usage); + if (nativeObject != 0) { + return new GraphicBuffer(width, height, format, usage, nativeObject); + } + return null; + } + + /** + * Private use only. See {@link #create(int, int, int, int)}. + */ + private GraphicBuffer(int width, int height, int format, int usage, int nativeObject) { + mWidth = width; + mHeight = height; + mFormat = format; + mUsage = usage; + mNativeObject = nativeObject; + } + + /** + * Returns the width of this buffer in pixels. + */ + public int getWidth() { + return mWidth; + } + + /** + * Returns the height of this buffer in pixels. + */ + public int getHeight() { + return mHeight; + } + + /** + * Returns the pixel format of this buffer. The pixel format must be one of + * the formats defined in {@link PixelFormat}. + */ + public int getFormat() { + return mFormat; + } + + /** + * Returns the usage hint set on this buffer. + */ + public int getUsage() { + return mUsage; + } + + /** + * <p>Start editing the pixels in the buffer. A null is returned if the buffer + * cannot be locked for editing.</p> + * + * <p>The content of the buffer is preserved between unlockCanvas() + * and lockCanvas().</p> + * + * @return A Canvas used to draw into the buffer, or null. + * + * @see #lockCanvas(android.graphics.Rect) + * @see #unlockCanvasAndPost(android.graphics.Canvas) + */ + public Canvas lockCanvas() { + return lockCanvas(null); + } + + /** + * Just like {@link #lockCanvas()} but allows specification of a dirty + * rectangle. + * + * @param dirty Area of the buffer that may be modified. + + * @return A Canvas used to draw into the surface or null + * + * @see #lockCanvas() + * @see #unlockCanvasAndPost(android.graphics.Canvas) + */ + public Canvas lockCanvas(Rect dirty) { + if (mCanvas == null) { + mCanvas = new Canvas(); + } + + if (nLockCanvas(mNativeObject, mCanvas, dirty)) { + mSaveCount = mCanvas.save(); + return mCanvas; + } + + return null; + } + + /** + * Finish editing pixels in the buffer. + * + * @param canvas The Canvas previously returned by lockCanvas() + * + * @see #lockCanvas() + * @see #lockCanvas(android.graphics.Rect) + */ + public void unlockCanvasAndPost(Canvas canvas) { + if (mCanvas != null && canvas == mCanvas) { + canvas.restoreToCount(mSaveCount); + mSaveCount = 0; + + nUnlockCanvasAndPost(mNativeObject, mCanvas); + } + } + + @Override + protected void finalize() throws Throwable { + try { + nDestroyGraphicBuffer(mNativeObject); + } finally { + super.finalize(); + } + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(mWidth); + dest.writeInt(mHeight); + dest.writeInt(mFormat); + dest.writeInt(mUsage); + nWriteGraphicBufferToParcel(mNativeObject, dest); + } + + public static final Parcelable.Creator<GraphicBuffer> CREATOR = + new Parcelable.Creator<GraphicBuffer>() { + public GraphicBuffer createFromParcel(Parcel in) { + int width = in.readInt(); + int height = in.readInt(); + int format = in.readInt(); + int usage = in.readInt(); + int nativeObject = nReadGraphicBufferFromParcel(in); + if (nativeObject != 0) { + return new GraphicBuffer(width, height, format, usage, nativeObject); + } + return null; + } + + public GraphicBuffer[] newArray(int size) { + return new GraphicBuffer[size]; + } + }; + + private static native int nCreateGraphicBuffer(int width, int height, int format, int usage); + private static native void nDestroyGraphicBuffer(int nativeObject); + private static native void nWriteGraphicBufferToParcel(int nativeObject, Parcel dest); + private static native int nReadGraphicBufferFromParcel(Parcel in); + private static native boolean nLockCanvas(int nativeObject, Canvas canvas, Rect dirty); + private static native boolean nUnlockCanvasAndPost(int nativeObject, Canvas canvas); +} diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java index 18b838b..23383d9 100644 --- a/core/java/android/view/HardwareLayer.java +++ b/core/java/android/view/HardwareLayer.java @@ -158,14 +158,22 @@ abstract class HardwareLayer { /** * This must be invoked before drawing onto this layer. * - * @param currentCanvas + * @param currentCanvas The canvas whose rendering needs to be interrupted */ abstract HardwareCanvas start(Canvas currentCanvas); /** + * This must be invoked before drawing onto this layer. + * + * @param dirty The dirty area to repaint + * @param currentCanvas The canvas whose rendering needs to be interrupted + */ + abstract HardwareCanvas start(Canvas currentCanvas, Rect dirty); + + /** * This must be invoked after drawing onto this layer. * - * @param currentCanvas + * @param currentCanvas The canvas whose rendering needs to be resumed */ abstract void end(Canvas currentCanvas); diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index 8308459..c07b187 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -17,6 +17,7 @@ package android.view; import android.content.ComponentCallbacks2; +import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.SurfaceTexture; @@ -24,7 +25,10 @@ import android.opengl.EGL14; import android.opengl.GLUtils; import android.opengl.ManagedEGLContext; import android.os.Handler; +import android.os.IBinder; import android.os.Looper; +import android.os.RemoteException; +import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemProperties; import android.os.Trace; @@ -42,7 +46,6 @@ import javax.microedition.khronos.opengles.GL; import java.io.File; import java.io.PrintWriter; -import java.util.Arrays; import java.util.concurrent.locks.ReentrantLock; import static javax.microedition.khronos.egl.EGL10.*; @@ -162,15 +165,32 @@ public abstract class HardwareRenderer { "debug.hwui.show_layers_updates"; /** - * Turn on to show overdraw level. + * Controls overdraw debugging. * * Possible values: - * "true", to enable overdraw debugging * "false", to disable overdraw debugging + * "show", to show overdraw areas on screen + * "count", to display an overdraw counter * * @hide */ - public static final String DEBUG_SHOW_OVERDRAW_PROPERTY = "debug.hwui.show_overdraw"; + public static final String DEBUG_OVERDRAW_PROPERTY = "debug.hwui.overdraw"; + + /** + * Value for {@link #DEBUG_OVERDRAW_PROPERTY}. When the property is set to this + * value, overdraw will be shown on screen by coloring pixels. + * + * @hide + */ + public static final String OVERDRAW_PROPERTY_SHOW = "show"; + + /** + * Value for {@link #DEBUG_OVERDRAW_PROPERTY}. When the property is set to this + * value, an overdraw counter will be shown on screen. + * + * @hide + */ + public static final String OVERDRAW_PROPERTY_COUNT = "count"; /** * Turn on to debug non-rectangular clip operations. @@ -386,6 +406,17 @@ public abstract class HardwareRenderer { private static native void nBeginFrame(int[] size); /** + * Returns the current system time according to the renderer. + * This method is used for debugging only and should not be used + * as a clock. + */ + static long getSystemTime() { + return nGetSystemTime(); + } + + private static native long nGetSystemTime(); + + /** * Preserves the back buffer of the current surface after a buffer swap. * Calling this method sets the EGL_SWAP_BEHAVIOR attribute of the current * surface to EGL_BUFFER_PRESERVED. Calling this method requires an EGL @@ -762,6 +793,17 @@ public abstract class HardwareRenderer { private static final int PROFILE_DRAW_THRESHOLD_STROKE_WIDTH = 2; private static final int PROFILE_DRAW_DP_PER_MS = 7; + private static final String[] VISUALIZERS = { + PROFILE_PROPERTY_VISUALIZE_BARS, + PROFILE_PROPERTY_VISUALIZE_LINES + }; + + private static final String[] OVERDRAW = { + OVERDRAW_PROPERTY_SHOW, + OVERDRAW_PROPERTY_COUNT + }; + private static final int OVERDRAW_TYPE_COUNT = 1; + static EGL10 sEgl; static EGLDisplay sEglDisplay; static EGLConfig sEglConfig; @@ -807,7 +849,9 @@ public abstract class HardwareRenderer { Paint mProfilePaint; boolean mDebugDirtyRegions; - boolean mShowOverdraw; + int mDebugOverdraw = -1; + HardwareLayer mDebugOverdrawLayer; + Paint mDebugOverdrawPaint; final int mGlVersion; final boolean mTranslucent; @@ -819,6 +863,8 @@ public abstract class HardwareRenderer { private final int[] mSurfaceSize = new int[2]; private final FunctorsRunnable mFunctorsRunnable = new FunctorsRunnable(); + private long mDrawDelta = Long.MAX_VALUE; + GlRenderer(int glVersion, boolean translucent) { mGlVersion = glVersion; mTranslucent = translucent; @@ -826,18 +872,13 @@ public abstract class HardwareRenderer { loadSystemProperties(null); } - private static final String[] VISUALIZERS = { - PROFILE_PROPERTY_VISUALIZE_BARS, - PROFILE_PROPERTY_VISUALIZE_LINES - }; - @Override boolean loadSystemProperties(Surface surface) { boolean value; boolean changed = false; String profiling = SystemProperties.get(PROFILE_PROPERTY); - int graphType = Arrays.binarySearch(VISUALIZERS, profiling); + int graphType = search(VISUALIZERS, profiling); value = graphType >= 0; if (graphType != mProfileVisualizerType) { @@ -894,11 +935,19 @@ public abstract class HardwareRenderer { } } - value = SystemProperties.getBoolean( - HardwareRenderer.DEBUG_SHOW_OVERDRAW_PROPERTY, false); - if (value != mShowOverdraw) { + String overdraw = SystemProperties.get(HardwareRenderer.DEBUG_OVERDRAW_PROPERTY); + int debugOverdraw = search(OVERDRAW, overdraw); + if (debugOverdraw != mDebugOverdraw) { changed = true; - mShowOverdraw = value; + mDebugOverdraw = debugOverdraw; + + if (mDebugOverdraw != OVERDRAW_TYPE_COUNT) { + if (mDebugOverdrawLayer != null) { + mDebugOverdrawLayer.destroy(); + mDebugOverdrawLayer = null; + mDebugOverdrawPaint = null; + } + } } if (nLoadProperties()) { @@ -908,6 +957,13 @@ public abstract class HardwareRenderer { return changed; } + private static int search(String[] values, String value) { + for (int i = 0; i < values.length; i++) { + if (values[i].equals(value)) return i; + } + return -1; + } + @Override void dumpGfxInfo(PrintWriter pw) { if (mProfileEnabled) { @@ -968,7 +1024,7 @@ public abstract class HardwareRenderer { if (fallback) { // we'll try again if it was context lost setRequested(false); - Log.w(LOG_TAG, "Mountain View, we've had a problem here. " + Log.w(LOG_TAG, "Mountain View, we've had a problem here. " + "Switching back to software rendering."); } } @@ -976,7 +1032,7 @@ public abstract class HardwareRenderer { @Override boolean initialize(Surface surface) throws Surface.OutOfResourcesException { if (isRequested() && !isEnabled()) { - initializeEgl(); + boolean contextCreated = initializeEgl(); mGl = createEglSurface(surface); mDestroyed = false; @@ -991,6 +1047,10 @@ public abstract class HardwareRenderer { mCanvas.setName(mName); } setEnabled(true); + + if (contextCreated) { + initAtlas(); + } } return mCanvas != null; @@ -1010,7 +1070,7 @@ public abstract class HardwareRenderer { abstract int[] getConfig(boolean dirtyRegions); - void initializeEgl() { + boolean initializeEgl() { synchronized (sEglLock) { if (sEgl == null && sEglConfig == null) { sEgl = (EGL10) EGLContext.getEGL(); @@ -1043,7 +1103,10 @@ public abstract class HardwareRenderer { if (mEglContext == null) { mEglContext = createContext(sEgl, sEglDisplay, sEglConfig); sEglContextStorage.set(createManagedContext(mEglContext)); + return true; } + + return false; } private EGLConfig loadEglConfig() { @@ -1181,6 +1244,7 @@ public abstract class HardwareRenderer { } abstract void initCaches(); + abstract void initAtlas(); EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) { int[] attribs = { EGL14.EGL_CONTEXT_CLIENT_VERSION, mGlVersion, EGL_NONE }; @@ -1193,6 +1257,7 @@ public abstract class HardwareRenderer { "Could not create an EGL context. eglCreateContext failed with error: " + GLUtils.getEGLErrorString(sEgl.eglGetError())); } + return context; } @@ -1361,6 +1426,7 @@ public abstract class HardwareRenderer { int saveCount = 0; int status = DisplayList.STATUS_DONE; + long start = getSystemTime(); try { status = prepareFrame(dirty); @@ -1380,10 +1446,15 @@ public abstract class HardwareRenderer { canvas.restoreToCount(saveCount); view.mRecreateDisplayList = false; - mFrameCount++; + mDrawDelta = getSystemTime() - start; + + if (mDrawDelta > 0) { + mFrameCount++; - debugDirtyRegions(dirty, canvas); - drawProfileData(attachInfo); + debugOverdraw(attachInfo, dirty, canvas, displayList); + debugDirtyRegions(dirty, canvas); + drawProfileData(attachInfo); + } } onPostDraw(); @@ -1399,7 +1470,66 @@ public abstract class HardwareRenderer { } } + abstract void countOverdraw(HardwareCanvas canvas); + abstract float getOverdraw(HardwareCanvas canvas); + + private void debugOverdraw(View.AttachInfo attachInfo, Rect dirty, + HardwareCanvas canvas, DisplayList displayList) { + + if (mDebugOverdraw == OVERDRAW_TYPE_COUNT) { + // TODO: Use an alpha layer allocated from a GraphicBuffer + // The alpha format will help with rendering performance and + // the GraphicBuffer will let us skip the read pixels step + if (mDebugOverdrawLayer == null) { + mDebugOverdrawLayer = createHardwareLayer(mWidth, mHeight, true); + } else if (mDebugOverdrawLayer.getWidth() != mWidth || + mDebugOverdrawLayer.getHeight() != mHeight) { + mDebugOverdrawLayer.resize(mWidth, mHeight); + } + + if (!mDebugOverdrawLayer.isValid()) { + mDebugOverdraw = -1; + return; + } + + HardwareCanvas layerCanvas = mDebugOverdrawLayer.start(canvas, dirty); + countOverdraw(layerCanvas); + final int restoreCount = layerCanvas.save(); + layerCanvas.drawDisplayList(displayList, null, DisplayList.FLAG_CLIP_CHILDREN); + layerCanvas.restoreToCount(restoreCount); + mDebugOverdrawLayer.end(canvas); + + float overdraw = getOverdraw(layerCanvas); + DisplayMetrics metrics = attachInfo.mRootView.getResources().getDisplayMetrics(); + + drawOverdrawCounter(canvas, overdraw, metrics.density); + } + } + + private void drawOverdrawCounter(HardwareCanvas canvas, float overdraw, float density) { + final String text = String.format("%.2fx", overdraw); + final Paint paint = setupPaint(density); + // HSBtoColor will clamp the values in the 0..1 range + paint.setColor(Color.HSBtoColor(0.28f - 0.28f * overdraw / 3.5f, 0.8f, 1.0f)); + + canvas.drawText(text, density * 4.0f, mHeight - paint.getFontMetrics().bottom, paint); + } + + private Paint setupPaint(float density) { + if (mDebugOverdrawPaint == null) { + mDebugOverdrawPaint = new Paint(); + mDebugOverdrawPaint.setAntiAlias(true); + mDebugOverdrawPaint.setShadowLayer(density * 3.0f, 0.0f, 0.0f, 0xff000000); + mDebugOverdrawPaint.setTextSize(density * 20.0f); + } + return mDebugOverdrawPaint; + } + private DisplayList buildDisplayList(View view, HardwareCanvas canvas) { + if (mDrawDelta <= 0) { + return view.mDisplayList; + } + view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED) == View.PFLAG_INVALIDATED; view.mPrivateFlags &= ~View.PFLAG_INVALIDATED; @@ -1788,7 +1918,31 @@ public abstract class HardwareRenderer { @Override void initCaches() { - GLES20Canvas.initCaches(); + if (GLES20Canvas.initCaches()) { + // Caches were (re)initialized, rebind atlas + initAtlas(); + } + } + + @Override + void initAtlas() { + IBinder binder = ServiceManager.getService("assetatlas"); + if (binder == null) return; + + IAssetAtlas atlas = IAssetAtlas.Stub.asInterface(binder); + try { + if (atlas.isCompatible(android.os.Process.myPpid())) { + GraphicBuffer buffer = atlas.getBuffer(); + if (buffer != null) { + int[] map = atlas.getMap(); + if (map != null) { + GLES20Canvas.initAtlas(buffer, map); + } + } + } + } catch (RemoteException e) { + Log.w(LOG_TAG, "Could not acquire atlas", e); + } } @Override @@ -1985,6 +2139,16 @@ public abstract class HardwareRenderer { } @Override + void countOverdraw(HardwareCanvas canvas) { + ((GLES20Canvas) canvas).setCountOverdrawEnabled(true); + } + + @Override + float getOverdraw(HardwareCanvas canvas) { + return ((GLES20Canvas) canvas).getOverdraw(); + } + + @Override public SurfaceTexture createSurfaceTexture(HardwareLayer layer) { return ((GLES20TextureLayer) layer).getSurfaceTexture(); } diff --git a/core/java/android/view/IAssetAtlas.aidl b/core/java/android/view/IAssetAtlas.aidl new file mode 100644 index 0000000..5f1e238 --- /dev/null +++ b/core/java/android/view/IAssetAtlas.aidl @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2013, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +import android.view.GraphicBuffer; + +/** + * Programming interface to the system assets atlas. This atlas, when + * present, holds preloaded drawable in a single, shareable graphics + * buffer. This allows multiple processes to share the same data to + * save up on memory. + * + * @hide + */ +interface IAssetAtlas { + /** + * Indicates whether the atlas is compatible with the specified + * parent process id. If the atlas' ppid does not match, this + * method will return false. + */ + boolean isCompatible(int ppid); + + /** + * Returns the atlas buffer (texture) or null if the atlas is + * not available yet. + */ + GraphicBuffer getBuffer(); + + /** + * Returns the map of the bitmaps stored in the atlas or null + * if the atlas is not available yet. + * + * Each bitmap is represented by several entries in the array: + * int0: SkBitmap*, the native bitmap object + * int1: x position + * int2: y position + * int3: rotated, 1 if the bitmap must be rotated, 0 otherwise + */ + int[] getMap(); +} diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 8ed4a86..ad3082e 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -80,8 +80,8 @@ interface IWindowManager void setEventDispatching(boolean enabled); void addWindowToken(IBinder token, int type); void removeWindowToken(IBinder token); - void addAppToken(int addPos, IApplicationToken token, - int groupId, int requestedOrientation, boolean fullscreen, boolean showWhenLocked); + void addAppToken(int addPos, IApplicationToken token, int groupId, int stackId, + int requestedOrientation, boolean fullscreen, boolean showWhenLocked); void setAppGroupId(IBinder token, int groupId); void setAppOrientation(IApplicationToken token, int requestedOrientation); int getAppOrientation(IApplicationToken token); @@ -97,15 +97,12 @@ interface IWindowManager void executeAppTransition(); void setAppStartingWindow(IBinder token, String pkg, int theme, in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes, - int icon, int windowFlags, IBinder transferFrom, boolean createIfNeeded); + int icon, int logo, int windowFlags, IBinder transferFrom, boolean createIfNeeded); void setAppWillBeHidden(IBinder token); void setAppVisibility(IBinder token, boolean visible); void startAppFreezingScreen(IBinder token, int configChanges); void stopAppFreezingScreen(IBinder token, boolean force); void removeAppToken(IBinder token); - void moveAppToken(int index, IBinder token); - void moveAppTokensToTop(in List<IBinder> tokens); - void moveAppTokensToBottom(in List<IBinder> tokens); // Re-evaluate the current orientation from the caller's state. // If there is a change, the new Configuration is returned and the diff --git a/core/java/android/view/InputEvent.java b/core/java/android/view/InputEvent.java index 07a937c..1ecdf30 100644 --- a/core/java/android/view/InputEvent.java +++ b/core/java/android/view/InputEvent.java @@ -70,6 +70,7 @@ public abstract class InputEvent implements Parcelable { * Gets the source of the event. * * @return The event source or {@link InputDevice#SOURCE_UNKNOWN} if unknown. + * @see InputDevice#getSources */ public abstract int getSource(); diff --git a/core/java/android/view/InputFilter.java b/core/java/android/view/InputFilter.java index c25b87b..4aba30c 100644 --- a/core/java/android/view/InputFilter.java +++ b/core/java/android/view/InputFilter.java @@ -40,7 +40,7 @@ import android.view.WindowManagerPolicy; * <li>Input events are then asynchronously delivered to the input filter's * {@link #onInputEvent(InputEvent)} method instead of being enqueued for dispatch to * applications as usual. The input filter only receives input events that were - * generated by input device; the input filter will not receive input events that were + * generated by an input device; the input filter will not receive input events that were * injected into the system by other means, such as by instrumentation.</li> * <li>The input filter processes and optionally transforms the stream of events. For example, * it may transform a sequence of motion events representing an accessibility gesture into @@ -68,7 +68,7 @@ import android.view.WindowManagerPolicy; * The input filter must take into account the fact that the input events coming from different * devices or even different sources all consist of distinct streams of input. * Use {@link InputEvent#getDeviceId()} and {@link InputEvent#getSource()} to identify - * the source of the event and its semantics. There are be multiple sources of keys, + * the source of the event and its semantics. There may be multiple sources of keys, * touches and other input: they must be kept separate. * </p> * <h3>Policy flags</h3> @@ -88,7 +88,7 @@ import android.view.WindowManagerPolicy; * The input filter should clear its internal state about the gesture and then send key or * motion events to the dispatcher to cancel any keys or pointers that are down. * </p><p> - * Corollary: Events that set sent to the dispatcher should usually include the + * Corollary: Events that get sent to the dispatcher should usually include the * {@link WindowManagerPolicy#FLAG_PASS_TO_USER} flag. Otherwise, they will be dropped! * </p><p> * It may be prudent to disable automatic key repeating for synthetic key events diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index ae4005b..e0786f7 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -71,8 +71,8 @@ public class Surface implements Parcelable { // Guarded state. final Object mLock = new Object(); // protects the native state private String mName; - int mNativeSurface; // package scope only for SurfaceControl access - private int mGenerationId; // incremented each time mNativeSurface changes + int mNativeObject; // package scope only for SurfaceControl access + private int mGenerationId; // incremented each time mNativeObject changes private final Canvas mCanvas = new CompatibleCanvas(); // A matrix to scale the matrix set by application. This is set to null for @@ -158,8 +158,8 @@ public class Surface implements Parcelable { */ public void release() { synchronized (mLock) { - if (mNativeSurface != 0) { - nativeRelease(mNativeSurface); + if (mNativeObject != 0) { + nativeRelease(mNativeObject); setNativeObjectLocked(0); } } @@ -183,8 +183,8 @@ public class Surface implements Parcelable { */ public boolean isValid() { synchronized (mLock) { - if (mNativeSurface == 0) return false; - return nativeIsValid(mNativeSurface); + if (mNativeObject == 0) return false; + return nativeIsValid(mNativeObject); } } @@ -210,7 +210,7 @@ public class Surface implements Parcelable { public boolean isConsumerRunningBehind() { synchronized (mLock) { checkNotReleasedLocked(); - return nativeIsConsumerRunningBehind(mNativeSurface); + return nativeIsConsumerRunningBehind(mNativeObject); } } @@ -233,7 +233,7 @@ public class Surface implements Parcelable { throws OutOfResourcesException, IllegalArgumentException { synchronized (mLock) { checkNotReleasedLocked(); - nativeLockCanvas(mNativeSurface, mCanvas, inOutDirty); + nativeLockCanvas(mNativeObject, mCanvas, inOutDirty); return mCanvas; } } @@ -252,7 +252,7 @@ public class Surface implements Parcelable { synchronized (mLock) { checkNotReleasedLocked(); - nativeUnlockCanvasAndPost(mNativeSurface, canvas); + nativeUnlockCanvasAndPost(mNativeObject, canvas); } } @@ -298,8 +298,8 @@ public class Surface implements Parcelable { int newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr); synchronized (mLock) { - if (mNativeSurface != 0) { - nativeRelease(mNativeSurface); + if (mNativeObject != 0) { + nativeRelease(mNativeObject); } setNativeObjectLocked(newNativeObject); } @@ -319,13 +319,13 @@ public class Surface implements Parcelable { if (other != this) { final int newPtr; synchronized (other.mLock) { - newPtr = other.mNativeSurface; + newPtr = other.mNativeObject; other.setNativeObjectLocked(0); } synchronized (mLock) { - if (mNativeSurface != 0) { - nativeRelease(mNativeSurface); + if (mNativeObject != 0) { + nativeRelease(mNativeObject); } setNativeObjectLocked(newPtr); } @@ -344,7 +344,7 @@ public class Surface implements Parcelable { synchronized (mLock) { mName = source.readString(); - setNativeObjectLocked(nativeReadFromParcel(mNativeSurface, source)); + setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source)); } } @@ -355,7 +355,7 @@ public class Surface implements Parcelable { } synchronized (mLock) { dest.writeString(mName); - nativeWriteToParcel(mNativeSurface, dest); + nativeWriteToParcel(mNativeObject, dest); } if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) { release(); @@ -370,19 +370,19 @@ public class Surface implements Parcelable { } private void setNativeObjectLocked(int ptr) { - if (mNativeSurface != ptr) { - if (mNativeSurface == 0 && ptr != 0) { + if (mNativeObject != ptr) { + if (mNativeObject == 0 && ptr != 0) { mCloseGuard.open("release"); - } else if (mNativeSurface != 0 && ptr == 0) { + } else if (mNativeObject != 0 && ptr == 0) { mCloseGuard.close(); } - mNativeSurface = ptr; + mNativeObject = ptr; mGenerationId += 1; } } private void checkNotReleasedLocked() { - if (mNativeSurface == 0) { + if (mNativeObject == 0) { throw new IllegalStateException("Surface has already been released."); } } diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index c6da84f..6b530ef 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -499,7 +499,7 @@ public class SurfaceControl { if (surface != null) { synchronized (surface.mLock) { - nativeSetDisplaySurface(displayToken, surface.mNativeSurface); + nativeSetDisplaySurface(displayToken, surface.mNativeObject); } } else { nativeSetDisplaySurface(displayToken, 0); diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 793fb5e..8b2b556 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -160,7 +160,6 @@ public class SurfaceView extends View { int mHeight = -1; int mFormat = -1; final Rect mSurfaceFrame = new Rect(); - Rect mTmpDirty; int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1; boolean mUpdateWindowNeeded; boolean mReportDrawNeeded; @@ -795,14 +794,6 @@ public class SurfaceView extends View { Canvas c = null; if (!mDrawingStopped && mWindow != null) { - if (dirty == null) { - if (mTmpDirty == null) { - mTmpDirty = new Rect(); - } - mTmpDirty.set(mSurfaceFrame); - dirty = mTmpDirty; - } - try { c = mSurface.lockCanvas(dirty); } catch (Exception e) { diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java index 5c3934d..f0acba1 100644 --- a/core/java/android/view/TextureView.java +++ b/core/java/android/view/TextureView.java @@ -648,13 +648,19 @@ public class TextureView extends View { * rectangle. Every pixel within that rectangle must be written; however * pixels outside the dirty rectangle will be preserved by the next call * to lockCanvas(). + * + * This method can return null if the underlying surface texture is not + * available (see {@link #isAvailable()} or if the surface texture is + * already connected to an image producer (for instance: the camera, + * OpenGL, a media player, etc.) * * @param dirty Area of the surface that will be modified. * @return A Canvas used to draw into the surface. * * @see #lockCanvas() - * @see #unlockCanvasAndPost(android.graphics.Canvas) + * @see #unlockCanvasAndPost(android.graphics.Canvas) + * @see #isAvailable() */ public Canvas lockCanvas(Rect dirty) { if (!isAvailable()) return null; @@ -664,7 +670,9 @@ public class TextureView extends View { } synchronized (mNativeWindowLock) { - nLockCanvas(mNativeWindow, mCanvas, dirty); + if (!nLockCanvas(mNativeWindow, mCanvas, dirty)) { + return null; + } } mSaveCount = mCanvas.save(); @@ -803,6 +811,6 @@ public class TextureView extends View { private static native void nSetDefaultBufferSize(SurfaceTexture surfaceTexture, int width, int height); - private static native void nLockCanvas(int nativeWindow, Canvas canvas, Rect dirty); + private static native boolean nLockCanvas(int nativeWindow, Canvas canvas, Rect dirty); private static native void nUnlockCanvasAndPost(int nativeWindow, Canvas canvas); } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 50638aa..6f88bb2 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -73,6 +73,7 @@ import android.view.animation.Transformation; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; +import android.view.transition.Scene; import android.widget.ScrollBarDrawable; import static android.os.Build.VERSION_CODES.*; @@ -1572,6 +1573,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ protected Object mTag; + private Scene mCurrentScene = null; + // for mPrivateFlags: /** {@hide} */ static final int PFLAG_WANTS_FOCUS = 0x00000001; @@ -2341,7 +2344,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * allows it to avoid artifacts when switching in and out of that mode, at * the expense that some of its user interface may be covered by screen * decorations when they are shown. You can perform layout of your inner - * UI elements to account for the navagation system UI through the + * UI elements to account for the navigation system UI through the * {@link #fitSystemWindows(Rect)} method. */ public static final int SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 0x00000200; @@ -2359,6 +2362,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, public static final int SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 0x00000400; /** + * Flag for {@link #setSystemUiVisibility(int)}: View would like to receive touch events + * when hiding the status bar with {@link #SYSTEM_UI_FLAG_FULLSCREEN} and/or hiding the + * navigation bar with {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION} instead of having the system + * clear these flags upon interaction. The system may compensate by temporarily overlaying + * transparent system ui while also delivering the event. + */ + public static final int SYSTEM_UI_FLAG_ALLOW_OVERLAY = 0x00000800; + + /** * @deprecated Use {@link #SYSTEM_UI_FLAG_LOW_PROFILE} instead. */ public static final int STATUS_BAR_HIDDEN = SYSTEM_UI_FLAG_LOW_PROFILE; @@ -2479,6 +2491,30 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * @hide + * + * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked + * out of the public fields to keep the undefined bits out of the developer's way. + * + * Flag to specify that the status bar should temporarily overlay underlying content + * that is otherwise assuming the status bar is hidden. The status bar may + * have some degree of transparency while in this temporary overlay mode. + */ + public static final int STATUS_BAR_OVERLAY = 0x04000000; + + /** + * @hide + * + * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked + * out of the public fields to keep the undefined bits out of the developer's way. + * + * Flag to specify that the navigation bar should temporarily overlay underlying content + * that is otherwise assuming the navigation bar is hidden. The navigation bar mayu + * have some degree of transparency while in this temporary overlay mode. + */ + public static final int NAVIGATION_BAR_OVERLAY = 0x08000000; + + /** + * @hide */ public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x0000FFFF; @@ -8556,7 +8592,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } - if ((flags & VISIBILITY_MASK) == VISIBLE) { + final int newVisibility = flags & VISIBILITY_MASK; + if (newVisibility == VISIBLE) { if ((changed & VISIBILITY_MASK) != 0) { /* * If this view is becoming visible, invalidate it in case it changed while @@ -8622,14 +8659,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } if ((changed & VISIBILITY_MASK) != 0) { + // If the view is invisible, cleanup its display list to free up resources + if (newVisibility != VISIBLE) { + cleanupDraw(); + } + if (mParent instanceof ViewGroup) { ((ViewGroup) mParent).onChildVisibilityChanged(this, - (changed & VISIBILITY_MASK), (flags & VISIBILITY_MASK)); + (changed & VISIBILITY_MASK), newVisibility); ((View) mParent).invalidate(true); } else if (mParent != null) { mParent.invalidateChild(this, null); } - dispatchVisibilityChanged(this, (flags & VISIBILITY_MASK)); + dispatchVisibilityChanged(this, newVisibility); } if ((changed & WILL_NOT_CACHE_DRAWING) != 0) { @@ -12009,6 +12051,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, destroyLayer(false); + cleanupDraw(); + + mCurrentAnimation = null; + mCurrentScene = null; + + resetAccessibilityStateChanged(); + } + + private void cleanupDraw() { if (mAttachInfo != null) { if (mDisplayList != null) { mDisplayList.markDirty(); @@ -12019,10 +12070,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // Should never happen clearDisplayList(); } + } - mCurrentAnimation = null; - - resetAccessibilityStateChanged(); + void invalidateInheritedLayoutMode(int layoutModeOfRoot) { } /** @@ -12640,6 +12690,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide */ protected void destroyHardwareResources() { + clearDisplayList(); destroyLayer(true); } @@ -15637,7 +15688,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private void setKeyedTag(int key, Object tag) { if (mKeyedTags == null) { - mKeyedTags = new SparseArray<Object>(); + mKeyedTags = new SparseArray<Object>(2); } mKeyedTags.put(key, tag); @@ -17742,6 +17793,31 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * Set the current Scene that this view is in. The current scene is set only + * on the root view of a scene, not for every view in that hierarchy. This + * information is used by Scene to determine whether there is a previous + * scene which should be exited before the new scene is entered. + * + * @param scene The new scene being set on the view + * + * @hide + */ + public void setCurrentScene(Scene scene) { + mCurrentScene = scene; + } + + /** + * Gets the current {@link Scene} set on this view. A scene is set on a view + * only if that view is the scene root. + * + * @return The current Scene set on this view. A value of null indicates that + * no Scene is current set. + */ + public Scene getCurrentScene() { + return mCurrentScene; + } + + /** * Interface definition for a callback to be invoked when a hardware key event is * dispatched to this view. The callback will be invoked before the key event is * given to the view. This is only useful for hardware keyboards; a software input diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 426c9d4..b0fbe84 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -204,7 +204,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager /** * Either {@link #LAYOUT_MODE_CLIP_BOUNDS} or {@link #LAYOUT_MODE_OPTICAL_BOUNDS}. */ - private int mLayoutMode = DEFAULT_LAYOUT_MODE; + private int mLayoutMode = LAYOUT_MODE_UNDEFINED; /** * NOTE: If you change the flags below make sure to reflect the changes @@ -345,6 +345,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager private static final int FLAG_PREVENT_DISPATCH_ATTACHED_TO_WINDOW = 0x400000; /** + * When true, indicates that a layoutMode has been explicitly set, either with + * an explicit call to {@link #setLayoutMode(int)} in code or from an XML resource. + * This distinguishes the situation in which a layout mode was inherited from + * one of the ViewGroup's ancestors and cached locally. + */ + private static final int FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET = 0x800000; + + /** * Indicates which types of drawing caches are to be kept in memory. * This field should be made private, so it is hidden from the SDK. * {@hide} @@ -373,6 +381,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // Layout Modes + private static final int LAYOUT_MODE_UNDEFINED = -1; + /** * This constant is a {@link #setLayoutMode(int) layoutMode}. * Clip bounds are the raw values of {@link #getLeft() left}, {@link #getTop() top}, @@ -389,7 +399,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager public static final int LAYOUT_MODE_OPTICAL_BOUNDS = 1; /** @hide */ - public static int DEFAULT_LAYOUT_MODE = LAYOUT_MODE_CLIP_BOUNDS; + public static int LAYOUT_MODE_DEFAULT = LAYOUT_MODE_CLIP_BOUNDS; /** * We clip to padding when FLAG_CLIP_TO_PADDING and FLAG_PADDING_NOT_NULL @@ -531,7 +541,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } break; case R.styleable.ViewGroup_layoutMode: - setLayoutMode(a.getInt(attr, DEFAULT_LAYOUT_MODE)); + setLayoutMode(a.getInt(attr, LAYOUT_MODE_UNDEFINED)); break; } } @@ -3448,6 +3458,24 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } } + private void clearCachedLayoutMode() { + if (!getBooleanFlag(FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET)) { + mLayoutMode = LAYOUT_MODE_UNDEFINED; + } + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + clearCachedLayoutMode(); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + clearCachedLayoutMode(); + } + /** * Adds a view during layout. This is useful if in your onLayout() method, * you need to add more views (as does the list view for example). @@ -4751,6 +4779,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager setBooleanFlag(FLAG_USE_CHILD_DRAWING_ORDER, enabled); } + private boolean getBooleanFlag(int flag) { + return (mGroupFlags & flag) == flag; + } + private void setBooleanFlag(int flag, boolean value) { if (value) { mGroupFlags |= flag; @@ -4794,24 +4826,63 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager mPersistentDrawingCache = drawingCacheToKeep & PERSISTENT_ALL_CACHES; } + private void setLayoutMode(int layoutMode, boolean explicitly) { + mLayoutMode = layoutMode; + setBooleanFlag(FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET, explicitly); + } + /** - * Returns the basis of alignment during layout operations on this view group: + * Recursively traverse the view hierarchy, resetting the layoutMode of any + * descendants that had inherited a different layoutMode from a previous parent. + * Recursion terminates when a descendant's mode is: + * <ul> + * <li>Undefined</li> + * <li>The same as the root node's</li> + * <li>A mode that had been explicitly set</li> + * <ul/> + * The first two clauses are optimizations. + * @param layoutModeOfRoot + */ + @Override + void invalidateInheritedLayoutMode(int layoutModeOfRoot) { + if (mLayoutMode == LAYOUT_MODE_UNDEFINED || + mLayoutMode == layoutModeOfRoot || + getBooleanFlag(FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET)) { + return; + } + setLayoutMode(LAYOUT_MODE_UNDEFINED, false); + + // apply recursively + for (int i = 0, N = getChildCount(); i < N; i++) { + getChildAt(i).invalidateInheritedLayoutMode(layoutModeOfRoot); + } + } + + /** + * Returns the basis of alignment during layout operations on this ViewGroup: * either {@link #LAYOUT_MODE_CLIP_BOUNDS} or {@link #LAYOUT_MODE_OPTICAL_BOUNDS}. + * <p> + * If no layoutMode was explicitly set, either programmatically or in an XML resource, + * the method returns the layoutMode of the view's parent ViewGroup if such a parent exists, + * otherwise the method returns a default value of {@link #LAYOUT_MODE_CLIP_BOUNDS}. * * @return the layout mode to use during layout operations * * @see #setLayoutMode(int) */ public int getLayoutMode() { + if (mLayoutMode == LAYOUT_MODE_UNDEFINED) { + int inheritedLayoutMode = (mParent instanceof ViewGroup) ? + ((ViewGroup) mParent).getLayoutMode() : LAYOUT_MODE_DEFAULT; + setLayoutMode(inheritedLayoutMode, false); + } return mLayoutMode; } /** - * Sets the basis of alignment during the layout of this view group. + * Sets the basis of alignment during the layout of this ViewGroup. * Valid values are either {@link #LAYOUT_MODE_CLIP_BOUNDS} or * {@link #LAYOUT_MODE_OPTICAL_BOUNDS}. - * <p> - * The default is {@link #LAYOUT_MODE_CLIP_BOUNDS}. * * @param layoutMode the layout mode to use during layout operations * @@ -4819,7 +4890,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager */ public void setLayoutMode(int layoutMode) { if (mLayoutMode != layoutMode) { - mLayoutMode = layoutMode; + invalidateInheritedLayoutMode(layoutMode); + setLayoutMode(layoutMode, layoutMode != LAYOUT_MODE_UNDEFINED); requestLayout(); } } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index bbf5ae9..bcc58a2 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -23,7 +23,6 @@ import android.content.ClipDescription; import android.content.ComponentCallbacks; import android.content.ComponentCallbacks2; import android.content.Context; -import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; @@ -108,13 +107,12 @@ public final class ViewRootImpl implements ViewParent, private static final boolean DEBUG_FPS = false; private static final boolean DEBUG_INPUT_PROCESSING = false || LOCAL_LOGV; - private static final boolean USE_RENDER_THREAD = false; - /** * Set this system property to true to force the view hierarchy to render * at 60 Hz. This can be used to measure the potential framerate. */ - private static final String PROPERTY_PROFILE_RENDERING = "viewancestor.profile_rendering"; + private static final String PROPERTY_PROFILE_RENDERING = "viewroot.profile_rendering"; + private static final String PROPERTY_MEDIA_DISABLED = "config.disable_media"; /** * Maximum time we allow the user to roll the trackball enough to generate @@ -130,10 +128,6 @@ public final class ViewRootImpl implements ViewParent, static final ArrayList<ComponentCallbacks> sConfigCallbacks = new ArrayList<ComponentCallbacks>(); - private static boolean sUseRenderThread = false; - private static boolean sRenderThreadQueried = false; - private static final Object[] sRenderThreadQueryLock = new Object[0]; - final Context mContext; final IWindowSession mWindowSession; final Display mDisplay; @@ -286,6 +280,8 @@ public final class ViewRootImpl implements ViewParent, private Choreographer.FrameCallback mRenderProfiler; private boolean mRenderProfilingEnabled; + private boolean mMediaDisabled; + // Variables to track frames per second, enabled via DEBUG_FPS flag private long mFpsStartTime = -1; private long mFpsPrevTime = -1; @@ -373,35 +369,6 @@ public final class ViewRootImpl implements ViewParent, loadSystemProperties(); } - /** - * @return True if the application requests the use of a separate render thread, - * false otherwise - */ - private static boolean isRenderThreadRequested(Context context) { - if (USE_RENDER_THREAD) { - synchronized (sRenderThreadQueryLock) { - if (!sRenderThreadQueried) { - final PackageManager packageManager = context.getPackageManager(); - final String packageName = context.getApplicationInfo().packageName; - try { - ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, - PackageManager.GET_META_DATA); - if (applicationInfo.metaData != null) { - sUseRenderThread = applicationInfo.metaData.getBoolean( - "android.graphics.renderThread", false); - } - } catch (PackageManager.NameNotFoundException e) { - } finally { - sRenderThreadQueried = true; - } - } - return sUseRenderThread; - } - } else { - return false; - } - } - public static void addFirstDrawHandler(Runnable callback) { synchronized (sFirstDrawHandlers) { if (!sFirstDrawComplete) { @@ -479,7 +446,7 @@ public final class ViewRootImpl implements ViewParent, // If the application owns the surface, don't enable hardware acceleration if (mSurfaceHolder == null) { - enableHardwareAcceleration(mView.getContext(), attrs); + enableHardwareAcceleration(attrs); } boolean restore = false; @@ -687,7 +654,7 @@ public final class ViewRootImpl implements ViewParent, } } - private void enableHardwareAcceleration(Context context, WindowManager.LayoutParams attrs) { + private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) { mAttachInfo.mHardwareAccelerated = false; mAttachInfo.mHardwareAccelerationRequested = false; @@ -727,11 +694,6 @@ public final class ViewRootImpl implements ViewParent, return; } - final boolean renderThread = isRenderThreadRequested(context); - if (renderThread) { - Log.i(HardwareRenderer.LOG_TAG, "Render threat initiated"); - } - if (mAttachInfo.mHardwareRenderer != null) { mAttachInfo.mHardwareRenderer.destroy(true); } @@ -5057,6 +5019,10 @@ public final class ViewRootImpl implements ViewParent, public void playSoundEffect(int effectId) { checkThread(); + if (mMediaDisabled) { + return; + } + try { final AudioManager audioManager = getAudioManager(); @@ -5202,6 +5168,9 @@ public final class ViewRootImpl implements ViewParent, mProfileRendering = SystemProperties.getBoolean(PROPERTY_PROFILE_RENDERING, false); profileRendering(mAttachInfo.mHasWindowFocus); + // Media (used by sound effects) + mMediaDisabled = SystemProperties.getBoolean(PROPERTY_MEDIA_DISABLED, false); + // Hardware rendering if (mAttachInfo.mHardwareRenderer != null) { if (mAttachInfo.mHardwareRenderer.loadSystemProperties(mHolder.getSurface())) { diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index 06974d3..39d48a7 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -1256,4 +1256,38 @@ public abstract class Window { * @param mask Flags specifying which options should be modified. Others will remain unchanged. */ public void setUiOptions(int uiOptions, int mask) { } + + /** + * Set the primary icon for this window. + * + * @param resId resource ID of a drawable to set + */ + public void setIcon(int resId) { } + + /** + * Set the default icon for this window. + * This will be overridden by any other icon set operation which could come from the + * theme or another explicit set. + * + * @hide + */ + public void setDefaultIcon(int resId) { } + + /** + * Set the logo for this window. A logo is often shown in place of an + * {@link #setIcon(int) icon} but is generally wider and communicates window title information + * as well. + * + * @param resId resource ID of a drawable to set + */ + public void setLogo(int resId) { } + + /** + * Set the default logo for this window. + * This will be overridden by any other logo set operation which could come from the + * theme or another explicit set. + * + * @hide + */ + public void setDefaultLogo(int resId) { } } diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 541c503..5144889 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -527,6 +527,14 @@ public interface WindowManager extends ViewManager { */ public static final int TYPE_RECENTS_OVERLAY = FIRST_SYSTEM_WINDOW+28; + + /** + * Window type: keyguard scrim window. Shows if keyguard needs to be restarted. + * In multiuser systems shows on all users' windows. + * @hide + */ + public static final int TYPE_KEYGUARD_SCRIM = FIRST_SYSTEM_WINDOW+29; + /** * End of types of system windows. */ diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index c0044b6..6291e62 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -420,6 +420,11 @@ public interface WindowManagerPolicy { public void shutdown(boolean confirm); public void rebootSafeMode(boolean confirm); + + /** + * Return the window manager lock needed to correctly call "Lw" methods. + */ + public Object getWindowManagerLock(); } /** Window has been added to the screen. */ @@ -637,7 +642,7 @@ public interface WindowManagerPolicy { */ public View addStartingWindow(IBinder appToken, String packageName, int theme, CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, - int labelRes, int icon, int windowFlags); + int labelRes, int icon, int logo, int windowFlags); /** * Called when the first window of an application has been displayed, while @@ -816,6 +821,14 @@ public interface WindowManagerPolicy { public int getSystemDecorRectLw(Rect systemRect); /** + * Return the rectangle of the screen that is available for applications to run in. + * This will be called immediately after {@link #beginLayoutLw}. + * + * @param r The rectangle to be filled with the boundaries available to applications. + */ + public void getContentRectLw(Rect r); + + /** * Called for each window attached to the window manager as layout is * proceeding. The implementation of this function must take care of * setting the window's frame, either here or in finishLayout(). diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java index 732699b..04ce7e2 100644 --- a/core/java/android/view/accessibility/AccessibilityManager.java +++ b/core/java/android/view/accessibility/AccessibilityManager.java @@ -16,14 +16,17 @@ package android.view.accessibility; +import android.Manifest; import android.accessibilityservice.AccessibilityServiceInfo; import android.content.Context; +import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; import android.os.Binder; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; +import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; @@ -132,29 +135,6 @@ public final class AccessibilityManager { } /** - * Creates the singleton AccessibilityManager to be shared across users. This - * has to be called before the local AccessibilityManager is created to ensure - * it registers itself in the system correctly. - * <p> - * Note: Calling this method requires INTERACT_ACROSS_USERS_FULL or - * INTERACT_ACROSS_USERS permission. - * </p> - * @param context Context in which this manager operates. - * @throws IllegalStateException if not called before the local - * AccessibilityManager is instantiated. - * - * @hide - */ - public static void createAsSharedAcrossUsers(Context context) { - synchronized (sInstanceSync) { - if (sInstance != null) { - throw new IllegalStateException("AccessibilityManager already created."); - } - createSingletonInstance(context, UserHandle.USER_CURRENT); - } - } - - /** * Get an AccessibilityManager instance (create one if necessary). * * @param context Context in which this manager operates. @@ -164,25 +144,27 @@ public final class AccessibilityManager { public static AccessibilityManager getInstance(Context context) { synchronized (sInstanceSync) { if (sInstance == null) { - createSingletonInstance(context, UserHandle.myUserId()); + final int userId; + if (Binder.getCallingUid() == Process.SYSTEM_UID + || context.checkCallingOrSelfPermission( + Manifest.permission.INTERACT_ACROSS_USERS) + == PackageManager.PERMISSION_GRANTED + || context.checkCallingOrSelfPermission( + Manifest.permission.INTERACT_ACROSS_USERS_FULL) + == PackageManager.PERMISSION_GRANTED) { + userId = UserHandle.USER_CURRENT; + } else { + userId = UserHandle.myUserId(); + } + IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE); + IAccessibilityManager service = IAccessibilityManager.Stub.asInterface(iBinder); + sInstance = new AccessibilityManager(context, service, userId); } } return sInstance; } /** - * Creates the singleton instance. - * - * @param context Context in which this manager operates. - * @param userId The user id under which to operate. - */ - private static void createSingletonInstance(Context context, int userId) { - IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE); - IAccessibilityManager service = IAccessibilityManager.Stub.asInterface(iBinder); - sInstance = new AccessibilityManager(context, service, userId); - } - - /** * Create an instance. * * @param context A {@link Context}. diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java index d6b973e..f730cf7 100644 --- a/core/java/android/view/inputmethod/BaseInputConnection.java +++ b/core/java/android/view/inputmethod/BaseInputConnection.java @@ -269,8 +269,9 @@ public class BaseInputConnection implements InputConnection { if (content != null) { beginBatchEdit(); removeComposingSpans(content); - endBatchEdit(); + // Note: sendCurrentText does nothing unless mDummyMode is set sendCurrentText(); + endBatchEdit(); } return true; } @@ -467,8 +468,9 @@ public class BaseInputConnection implements InputConnection { content.setSpan(COMPOSING, a, b, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING); - endBatchEdit(); + // Note: sendCurrentText does nothing unless mDummyMode is set sendCurrentText(); + endBatchEdit(); } return true; } diff --git a/core/java/android/view/transition/AutoTransition.java b/core/java/android/view/transition/AutoTransition.java new file mode 100644 index 0000000..d94cf2c --- /dev/null +++ b/core/java/android/view/transition/AutoTransition.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.view.transition; + +/** + * Utility class for creating a default transition that automatically fades, + * moves, and resizes views during a scene change. + */ +public class AutoTransition extends TransitionGroup { + + /** + * Constructs an AutoTransition object, which is a TransitionGroup which + * first fades out disappearing targets, then moves and resizes existing + * targets, and finally fades in appearing targets. + * + */ + public AutoTransition() { + setOrdering(SEQUENTIALLY); + addTransitions(new Fade(Fade.OUT), new Move(), new Fade(Fade.IN)); + } +} diff --git a/core/java/android/view/transition/Crossfade.java b/core/java/android/view/transition/Crossfade.java new file mode 100644 index 0000000..babf58f --- /dev/null +++ b/core/java/android/view/transition/Crossfade.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.view.transition; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.animation.RectEvaluator; +import android.animation.ValueAnimator; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.util.Log; +import android.view.SurfaceView; +import android.view.TextureView; +import android.view.View; +import android.view.ViewGroup; + +import java.util.HashMap; + +/** + * This transition captures bitmap representations of target views before and + * after the scene change and fades between them. + * + * <p>Note: This transition is not compatible with {@link TextureView} + * or {@link SurfaceView}.</p> + */ +public class Crossfade extends Transition { + // TODO: Add a hook that lets a Transition call user code to query whether it should run on + // a given target view. This would save bitmap comparisons in this transition, for example. + + private static final String LOG_TAG = "Crossfade"; + + private static final String PROPNAME_BITMAP = "android:crossfade:bitmap"; + private static final String PROPNAME_DRAWABLE = "android:crossfade:drawable"; + private static final String PROPNAME_BOUNDS = "android:crossfade:bounds"; + + private static RectEvaluator sRectEvaluator = new RectEvaluator(); + + @Override + protected boolean prePlay(ViewGroup sceneRoot, TransitionValues startValues, + TransitionValues endValues) { + if (startValues == null || endValues == null) { + return false; + } + final View view = startValues.view; + HashMap<String, Object> startVals = startValues.values; + HashMap<String, Object> endVals = endValues.values; + Bitmap startBitmap = (Bitmap) startVals.get(PROPNAME_BITMAP); + Bitmap endBitmap = (Bitmap) endVals.get(PROPNAME_BITMAP); + Drawable startDrawable = (Drawable) startVals.get(PROPNAME_DRAWABLE); + Drawable endDrawable = (Drawable) endVals.get(PROPNAME_DRAWABLE); + if (Transition.DBG) { + Log.d(LOG_TAG, "StartBitmap.sameAs(endBitmap) = " + startBitmap.sameAs(endBitmap) + + " for start, end: " + startBitmap + ", " + endBitmap); + } + if (startDrawable != null && endDrawable != null && !startBitmap.sameAs(endBitmap)) { + view.getOverlay().add(endDrawable); + view.getOverlay().add(startDrawable); + return true; + } else { + return false; + } + } + + @Override + protected Animator play(ViewGroup sceneRoot, TransitionValues startValues, + TransitionValues endValues) { + if (startValues == null || endValues == null) { + return null; + } + HashMap<String, Object> startVals = startValues.values; + HashMap<String, Object> endVals = endValues.values; + + final View view = endValues.view; + Rect startBounds = (Rect) startVals.get(PROPNAME_BOUNDS); + Rect endBounds = (Rect) endVals.get(PROPNAME_BOUNDS); + final BitmapDrawable startDrawable = (BitmapDrawable) startVals.get(PROPNAME_DRAWABLE); + final BitmapDrawable endDrawable = (BitmapDrawable) endVals.get(PROPNAME_DRAWABLE); + + // The transition works by placing the end drawable under the start drawable and + // gradually fading out the start drawable. So it's not really a cross-fade, but rather + // a reveal of the end scene over time. Also, animate the bounds of both drawables + // to mimic the change in the size of the view itself between scenes. + ObjectAnimator anim = ObjectAnimator.ofInt(startDrawable, "alpha", 0); + anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + // TODO: some way to auto-invalidate views based on drawable changes? callbacks? + view.invalidate(startDrawable.getBounds()); + } + }); + if (Transition.DBG) { + Log.d(LOG_TAG, "Crossfade: created anim " + anim + " for start, end values " + + startValues + ", " + endValues); + } + anim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + view.getOverlay().remove(startDrawable); + view.getOverlay().remove(endDrawable); + } + }); + AnimatorSet set = new AnimatorSet(); + set.playTogether(anim); + if (!startBounds.equals(endBounds)) { + if (Transition.DBG) { + Log.d(LOG_TAG, "animating from startBounds to endBounds: " + + startBounds + ", " + endBounds); + } + Animator anim2 = ObjectAnimator.ofObject(startDrawable, "bounds", + sRectEvaluator, startBounds, endBounds); + Animator anim3 = ObjectAnimator.ofObject(endDrawable, "bounds", + sRectEvaluator, startBounds, endBounds); + set.playTogether(anim2); + set.playTogether(anim3); + } + return set; + } + + @Override + protected void captureValues(TransitionValues values, boolean start) { + View view = values.view; + values.values.put(PROPNAME_BOUNDS, new Rect(0, 0, + view.getWidth(), view.getHeight())); + + if (Transition.DBG) { + Log.d(LOG_TAG, "Captured bounds " + values.values.get(PROPNAME_BOUNDS) + ": start = " + + start); + } + Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), + Bitmap.Config.ARGB_8888); + if (view instanceof TextureView) { + bitmap = ((TextureView) view).getBitmap(); + } else { + Canvas c = new Canvas(bitmap); + view.draw(c); + } + values.values.put(PROPNAME_BITMAP, bitmap); + // TODO: I don't have resources, can't call the non-deprecated method? + BitmapDrawable drawable = new BitmapDrawable(bitmap); + // TODO: lrtb will be wrong if the view has transXY set + drawable.setBounds(view.getLeft(), view.getTop(), view.getRight(), view.getBottom()); + values.values.put(PROPNAME_DRAWABLE, drawable); + } + +} diff --git a/core/java/android/view/transition/Fade.java b/core/java/android/view/transition/Fade.java new file mode 100644 index 0000000..8e4909d --- /dev/null +++ b/core/java/android/view/transition/Fade.java @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.view.transition; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ObjectAnimator; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; + +/** + * This transition tracks changes to the visibility of target views in the + * start and end scenes and fades views in or out when they become visible + * or non-visible. Visibility is determined by both the + * {@link View#setVisibility(int)} state of the view as well as whether it + * is parented in the current view hierarchy. + */ +public class Fade extends Visibility { + + private static final String LOG_TAG = "Fade"; + + /** + * Fading mode used in {@link #Fade(int)} to make the transition + * operate on targets that are appearing. Maybe be combined with + * {@link #OUT} to fade both in and out. + */ + public static final int IN = 0x1; + /** + * Fading mode used in {@link #Fade(int)} to make the transition + * operate on targets that are disappearing. Maybe be combined with + * {@link #IN} to fade both in and out. + */ + public static final int OUT = 0x2; + + private int mFadingMode; + + /** + * Constructs a Fade transition that will fade targets in and out. + */ + public Fade() { + this(IN | OUT); + } + + /** + * Constructs a Fade transition that will fade targets in + * and/or out, according to the value of fadingMode. + * + * @param fadingMode The behavior of this transition, a combination of + * {@link #IN} and {@link #OUT}. + */ + public Fade(int fadingMode) { + mFadingMode = fadingMode; + } + + /** + * Utility method to handle creating and running the Animator. + */ + private Animator runAnimation(View view, float startAlpha, float endAlpha, + Animator.AnimatorListener listener) { + final ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", startAlpha, endAlpha); + if (listener != null) { + anim.addListener(listener); + } + // TODO: Maybe extract a method into Transition to run an animation that handles the + // duration/startDelay stuff for all subclasses. + return anim; + } + + @Override + protected boolean preAppear(ViewGroup sceneRoot, View startView, int startVisibility, + View endView, int endVisibility) { + if ((mFadingMode & IN) != IN) { + return false; + } + endView.setAlpha(0); + return true; + } + + @Override + protected Animator appear(ViewGroup sceneRoot, View startView, int startVisibility, + View endView, int endVisibility) { + if ((mFadingMode & IN) != IN) { + return null; + } + // TODO: hack - retain original value from before preAppear + return runAnimation(endView, 0, 1, null); + // TODO: end listener to make sure we end at 1 no matter what + } + + @Override + protected boolean preDisappear(ViewGroup sceneRoot, View startView, int startVisibility, + View endView, int endVisibility) { + if ((mFadingMode & OUT) != OUT) { + return false; + } + if (Transition.DBG) { + Log.d(LOG_TAG, "Fade.predisappear: startView, startVis, endView, endVis = " + + startView + ", " + startVisibility + ", " + endView + ", " + endVisibility); + } + View view; + View overlayView = null; + View viewToKeep = null; + if (endView == null) { + // view was removed: add the start view to the Overlay + view = startView; + overlayView = view; + } else { + // visibility change + if (endVisibility == View.INVISIBLE) { + view = endView; + viewToKeep = view; + } else { + // Becoming GONE + if (startView == endView) { + view = endView; + viewToKeep = view; + } else { + view = startView; + overlayView = view; + } + } + } + // TODO: add automatic facility to Visibility superclass for keeping views around + if (overlayView != null) { + // TODO: Need to do this for general case of adding to overlay + sceneRoot.getOverlay().add(overlayView); + return true; + } + if (viewToKeep != null) { + // TODO: find a different way to do this, like just changing the view to be + // VISIBLE for the duration of the transition + viewToKeep.setVisibility((View.VISIBLE)); + return true; + } + return false; + } + + @Override + protected Animator disappear(ViewGroup sceneRoot, View startView, int startVisibility, + View endView, int endVisibility) { + if ((mFadingMode & OUT) != OUT) { + return null; + } + if (Transition.DBG) { + Log.d(LOG_TAG, "Fade.disappear: startView, startVis, endView, endVis = " + + startView + ", " + startVisibility + ", " + endView + ", " + endVisibility); + } + View view; + View overlayView = null; + View viewToKeep = null; + final int finalVisibility = endVisibility; + if (endView == null) { + // view was removed: add the start view to the Overlay + view = startView; + overlayView = view; + } else { + // visibility change + if (endVisibility == View.INVISIBLE) { + view = endView; + viewToKeep = view; + } else { + // Becoming GONE + if (startView == endView) { + view = endView; + viewToKeep = view; + } else { + view = startView; + overlayView = view; + } + } + } + // TODO: add automatic facility to Visibility superclass for keeping views around + final float startAlpha = view.getAlpha(); + float endAlpha = 0; + final View finalView = view; + final View finalOverlayView = overlayView; + final View finalViewToKeep = viewToKeep; + final ViewGroup finalSceneRoot = sceneRoot; + final Animator.AnimatorListener endListener = new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + finalView.setAlpha(startAlpha); + // TODO: restore view offset from overlay repositioning + if (finalViewToKeep != null) { + finalViewToKeep.setVisibility(finalVisibility); + } + if (finalOverlayView != null) { + finalSceneRoot.getOverlay().remove(finalOverlayView); + } + } + }; + return runAnimation(view, startAlpha, endAlpha, endListener); + } + +}
\ No newline at end of file diff --git a/core/java/android/view/transition/Move.java b/core/java/android/view/transition/Move.java new file mode 100644 index 0000000..3bd57bd --- /dev/null +++ b/core/java/android/view/transition/Move.java @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.view.transition; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ObjectAnimator; +import android.animation.PropertyValuesHolder; +import android.animation.RectEvaluator; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.graphics.drawable.BitmapDrawable; +import android.view.View; +import android.view.ViewGroup; + +import java.util.HashMap; + +/** + * This transition captures the layout bounds of target views before and after + * the scene change and animates those changes during the transition. + */ +public class Move extends Transition { + + private static final String PROPNAME_BOUNDS = "android:move:bounds"; + private static final String PROPNAME_PARENT = "android:move:parent"; + private static final String PROPNAME_WINDOW_X = "android:move:windowX"; + private static final String PROPNAME_WINDOW_Y = "android:move:windowY"; + int[] tempLocation = new int[2]; + boolean mResizeClip = false; + boolean mReparent = false; + + private static RectEvaluator sRectEvaluator = new RectEvaluator(); + + public void setResizeClip(boolean resizeClip) { + mResizeClip = resizeClip; + } + + /** + * Setting this flag tells Move to track the before/after parent + * of every view using this transition. The flag is not enabled by + * default because it requires the parent instances to be the same + * in the two scenes or else all parents must use ids to allow + * the transition to determine which parents are the same. + * + * @param reparent true if the transition should track the parent + * container of target views and animate parent changes. + */ + public void setReparent(boolean reparent) { + mReparent = reparent; + } + + @Override + protected void captureValues(TransitionValues values, boolean start) { + View view = values.view; + values.values.put(PROPNAME_BOUNDS, new Rect(view.getLeft(), view.getTop(), + view.getRight(), view.getBottom())); + values.values.put(PROPNAME_PARENT, values.view.getParent()); + values.view.getLocationInWindow(tempLocation); + values.values.put(PROPNAME_WINDOW_X, tempLocation[0]); + values.values.put(PROPNAME_WINDOW_Y, tempLocation[1]); + } + + @Override + protected Animator play(final ViewGroup sceneRoot, TransitionValues startValues, + TransitionValues endValues) { + if (startValues == null || endValues == null) { + return null; + } + final View view = endValues.view; + if (view.getParent() == null) { + // TODO: Might want to make it possible to Move an disappearing view. + // This workaround is here because if a parallel Fade is not running on the view + // Then it won't get added to the hierarchy and the animator below will not fire, + // causing the transition to not end + return null; + } + // TODO: need to handle non-VG case? + ViewGroup startParent = (ViewGroup) startValues.values.get(PROPNAME_PARENT); + ViewGroup endParent = (ViewGroup) endValues.values.get(PROPNAME_PARENT); + if (startParent == null || endParent == null) { + return null; + } + boolean parentsEqual = (startParent == endParent) || + (startParent.getId() == endParent.getId()); + if (!mReparent || parentsEqual) { + // Common case - view belongs to the same layout before/after. Just animate its bounds + Rect startBounds = (Rect) startValues.values.get(PROPNAME_BOUNDS); + Rect endBounds = (Rect) endValues.values.get(PROPNAME_BOUNDS); + int startLeft = startBounds.left; + int endLeft = endBounds.left; + int startTop = startBounds.top; + int endTop = endBounds.top; + int startRight = startBounds.right; + int endRight = endBounds.right; + int startBottom = startBounds.bottom; + int endBottom = endBounds.bottom; + int startWidth = startRight - startLeft; + int startHeight = startBottom - startTop; + int endWidth = endRight - endLeft; + int endHeight = endBottom - endTop; + int numChanges = 0; + if (startWidth != 0 && startHeight != 0 && endWidth != 0 && endHeight != 0) { + if (startLeft != endLeft) ++numChanges; + if (startTop != endTop) ++numChanges; + if (startRight != endRight) ++numChanges; + if (startBottom != endBottom) ++numChanges; + } + if (numChanges > 0) { + if (!mResizeClip) { + PropertyValuesHolder pvh[] = new PropertyValuesHolder[numChanges]; + int pvhIndex = 0; + if (startLeft != endLeft) { + pvh[pvhIndex++] = PropertyValuesHolder.ofInt("left", startLeft, endLeft); + } + if (startTop != endTop) { + pvh[pvhIndex++] = PropertyValuesHolder.ofInt("top", startTop, endTop); + } + if (startRight != endRight) { + pvh[pvhIndex++] = PropertyValuesHolder.ofInt("right", + startRight, endRight); + } + if (startBottom != endBottom) { + pvh[pvhIndex++] = PropertyValuesHolder.ofInt("bottom", + startBottom, endBottom); + } + ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(view, pvh); + if (view.getParent() instanceof ViewGroup) { + final ViewGroup parent = (ViewGroup) view.getParent(); + parent.suppressLayout(true); + anim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + parent.suppressLayout(false); + } + }); + } + return anim; + } else { + // Animate location with translationX/Y and size with clip bounds + float transXDelta = endLeft - startLeft; + float transYDelta = endTop - startTop; + int widthDelta = endWidth - startWidth; + int heightDelta = endHeight - startHeight; + numChanges = 0; + if (transXDelta != 0) numChanges++; + if (transYDelta != 0) numChanges++; + if (widthDelta != 0 || heightDelta != 0) numChanges++; + PropertyValuesHolder pvh[] = new PropertyValuesHolder[numChanges]; + int pvhIndex = 0; + if (transXDelta != 0) { + pvh[pvhIndex++] = PropertyValuesHolder.ofFloat("translationX", + view.getTranslationX(), 0); + } + if (transYDelta != 0) { + pvh[pvhIndex++] = PropertyValuesHolder.ofFloat("translationY", + view.getTranslationY(), 0); + } + if (widthDelta != 0 || heightDelta != 0) { + Rect tempStartBounds = new Rect(0, 0, startWidth, startHeight); + Rect tempEndBounds = new Rect(0, 0, endWidth, endHeight); + pvh[pvhIndex++] = PropertyValuesHolder.ofObject("clipBounds", + sRectEvaluator, tempStartBounds, tempEndBounds); + } + ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(view, pvh); + if (view.getParent() instanceof ViewGroup) { + final ViewGroup parent = (ViewGroup) view.getParent(); + parent.suppressLayout(true); + anim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + parent.suppressLayout(false); + } + }); + } + anim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + view.setClipBounds(null); + } + }); + return anim; + } + } + } else { + return (ObjectAnimator) endValues.values.get("drawableAnim"); + } + return null; + } + + @Override + protected boolean prePlay(final ViewGroup sceneRoot, TransitionValues startValues, + TransitionValues endValues) { + if (startValues == null || endValues == null) { + return false; + } + HashMap<String, Object> startParentVals = startValues.values; + HashMap<String, Object> endParentVals = endValues.values; + ViewGroup startParent = (ViewGroup) startParentVals.get(PROPNAME_PARENT); + ViewGroup endParent = (ViewGroup) endParentVals.get(PROPNAME_PARENT); + if (startParent == null || endParent == null) { + return false; + } + final View view = endValues.view; + boolean parentsEqual = (startParent == endParent) || + (startParent.getId() == endParent.getId()); + // TODO: Might want reparenting to be separate/subclass transition, or at least + // triggered by a property on Move. Otherwise, we're forcing the requirement that + // all parents in layouts have IDs to avoid layout-inflation resulting in a side-effect + // of reparenting the views. + if (!mReparent || parentsEqual) { + Rect startBounds = (Rect) startValues.values.get(PROPNAME_BOUNDS); + Rect endBounds = (Rect) endValues.values.get(PROPNAME_BOUNDS); + int startLeft = startBounds.left; + int endLeft = endBounds.left; + int startTop = startBounds.top; + int endTop = endBounds.top; + int startRight = startBounds.right; + int endRight = endBounds.right; + int startBottom = startBounds.bottom; + int endBottom = endBounds.bottom; + int startWidth = startRight - startLeft; + int startHeight = startBottom - startTop; + int endWidth = endRight - endLeft; + int endHeight = endBottom - endTop; + int numChanges = 0; + if (startWidth != 0 && startHeight != 0 && endWidth != 0 && endHeight != 0) { + if (startLeft != endLeft) ++numChanges; + if (startTop != endTop) ++numChanges; + if (startRight != endRight) ++numChanges; + if (startBottom != endBottom) ++numChanges; + } + if (numChanges > 0) { + if (!mResizeClip) { + if (startLeft != endLeft) view.setLeft(startLeft); + if (startTop != endTop) view.setTop(startTop); + if (startRight != endRight) view.setRight(startRight); + if (startBottom != endBottom) view.setBottom(startBottom); + } else { + if (startWidth != endWidth) view.setRight(endLeft + + Math.max(startWidth, endWidth)); + if (startHeight != endHeight) view.setBottom(endTop + + Math.max(startHeight, endHeight)); + // TODO: don't clobber TX/TY + if (startLeft != endLeft) view.setTranslationX(startLeft - endLeft); + if (startTop != endTop) view.setTranslationY(startTop - endTop); + } + return true; + } + } else { + int startX = (Integer) startValues.values.get(PROPNAME_WINDOW_X); + int startY = (Integer) startValues.values.get(PROPNAME_WINDOW_Y); + int endX = (Integer) endValues.values.get(PROPNAME_WINDOW_X); + int endY = (Integer) endValues.values.get(PROPNAME_WINDOW_Y); + // TODO: also handle size changes: check bounds and animate size changes + if (startX != endX || startY != endY) { + sceneRoot.getLocationInWindow(tempLocation); + Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), + Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + view.draw(canvas); + final BitmapDrawable drawable = new BitmapDrawable(bitmap); + view.setVisibility(View.INVISIBLE); + sceneRoot.getOverlay().add(drawable); + Rect startBounds = new Rect(startX - tempLocation[0], startY - tempLocation[1], + startX - tempLocation[0] + view.getWidth(), + startY - tempLocation[1] + view.getHeight()); + Rect endBounds = new Rect(endX - tempLocation[0], endY - tempLocation[1], + endX - tempLocation[0] + view.getWidth(), + endY - tempLocation[1] + view.getHeight()); + ObjectAnimator anim = ObjectAnimator.ofObject(drawable, "bounds", + sRectEvaluator, startBounds, endBounds); + anim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + sceneRoot.getOverlay().remove(drawable); + view.setVisibility(View.VISIBLE); + } + }); + endParentVals.put("drawableAnim", anim); + return true; + } + } + return false; + } +} diff --git a/core/java/android/view/transition/Recolor.java b/core/java/android/view/transition/Recolor.java new file mode 100644 index 0000000..7048be9 --- /dev/null +++ b/core/java/android/view/transition/Recolor.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.view.transition; + +import android.animation.Animator; +import android.animation.ArgbEvaluator; +import android.animation.ObjectAnimator; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import java.util.HashMap; + +/** + * This transition tracks changes during scene changes to the + * {@link View#setBackground(android.graphics.drawable.Drawable) background} + * property of its target views (when the background is a + * {@link ColorDrawable}, as well as the + * {@link TextView#setTextColor(android.content.res.ColorStateList) + * color} of the text for target TextViews. If the color changes between + * scenes, the color change is animated. + */ +public class Recolor extends Transition { + + private static final String PROPNAME_BACKGROUND = "android:recolor:background"; + private static final String PROPNAME_TEXT_COLOR = "android:recolor:textColor"; + + @Override + protected void captureValues(TransitionValues values, boolean start) { + values.values.put(PROPNAME_BACKGROUND, values.view.getBackground()); + if (values.view instanceof TextView) { + values.values.put(PROPNAME_TEXT_COLOR, ((TextView)values.view).getCurrentTextColor()); + } + } + + @Override + protected boolean prePlay(ViewGroup sceneRoot, TransitionValues startValues, + TransitionValues endValues) { + if (startValues == null || endValues == null) { + return false; + } + final View view = endValues.view; + Drawable startBackground = (Drawable) startValues.values.get(PROPNAME_BACKGROUND); + Drawable endBackground = (Drawable) endValues.values.get(PROPNAME_BACKGROUND); + boolean changed = false; + if (startBackground instanceof ColorDrawable && endBackground instanceof ColorDrawable) { + ColorDrawable startColor = (ColorDrawable) startBackground; + ColorDrawable endColor = (ColorDrawable) endBackground; + if (startColor.getColor() != endColor.getColor()) { + endColor.setColor(startColor.getColor()); + changed = true; + } + } + if (view instanceof TextView) { + TextView textView = (TextView) view; + int start = (Integer) startValues.values.get(PROPNAME_TEXT_COLOR); + int end = (Integer) endValues.values.get(PROPNAME_TEXT_COLOR); + if (start != end) { + textView.setTextColor(end); + changed = true; + } + } + return changed; + } + + @Override + protected Animator play(ViewGroup sceneRoot, TransitionValues startValues, + TransitionValues endValues) { + if (startValues == null || endValues == null) { + return null; + } + ObjectAnimator anim = null; + final View view = endValues.view; + HashMap<String, Object> startVals = startValues.values; + HashMap<String, Object> endVals = endValues.values; + Drawable startBackground = (Drawable) startVals.get(PROPNAME_BACKGROUND); + Drawable endBackground = (Drawable) endVals.get(PROPNAME_BACKGROUND); + if (startBackground instanceof ColorDrawable && endBackground instanceof ColorDrawable) { + ColorDrawable startColor = (ColorDrawable) startBackground; + ColorDrawable endColor = (ColorDrawable) endBackground; + if (startColor.getColor() != endColor.getColor()) { + anim = ObjectAnimator.ofObject(endBackground, "color", + new ArgbEvaluator(), startColor.getColor(), endColor.getColor()); + if (getStartDelay() > 0) { + endColor.setColor(startColor.getColor()); + } + } + } + if (view instanceof TextView) { + TextView textView = (TextView) view; + int start = (Integer) startValues.values.get(PROPNAME_TEXT_COLOR); + int end = (Integer) endValues.values.get(PROPNAME_TEXT_COLOR); + if (start != end) { + anim = ObjectAnimator.ofObject(textView, "textColor", + new ArgbEvaluator(), start, end); + if (getStartDelay() > 0) { + textView.setTextColor(end); + } + } + } + return anim; + } +} diff --git a/core/java/android/view/transition/Rotate.java b/core/java/android/view/transition/Rotate.java new file mode 100644 index 0000000..b42fbe5 --- /dev/null +++ b/core/java/android/view/transition/Rotate.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.view.transition; + +import android.animation.Animator; +import android.animation.ObjectAnimator; +import android.view.View; +import android.view.ViewGroup; + +/** + * This transition captures the rotation property of targets before and after + * the scene change and animates any changes. + */ +public class Rotate extends Transition { + + private static final String PROPNAME_ROTATION = "android:rotate:rotation"; + + @Override + protected void captureValues(TransitionValues values, boolean start) { + values.values.put(PROPNAME_ROTATION, values.view.getRotation()); + } + + @Override + protected boolean prePlay(ViewGroup sceneRoot, TransitionValues startValues, + TransitionValues endValues) { + if (startValues == null || endValues == null) { + return false; + } + final View view = endValues.view; + float startRotation = (Float) startValues.values.get(PROPNAME_ROTATION); + float endRotation = (Float) endValues.values.get(PROPNAME_ROTATION); + if (startRotation != endRotation) { + view.setRotation(startRotation); + return true; + } + return false; + } + + @Override + protected Animator play(ViewGroup sceneRoot, TransitionValues startValues, + TransitionValues endValues) { + if (startValues == null || endValues == null) { + return null; + } + final View view = endValues.view; + float startRotation = (Float) startValues.values.get(PROPNAME_ROTATION); + float endRotation = (Float) endValues.values.get(PROPNAME_ROTATION); + if (startRotation != endRotation) { + return ObjectAnimator.ofFloat(view, View.ROTATION, + startRotation, endRotation); + } + return null; + } +} diff --git a/core/java/android/view/transition/Scene.java b/core/java/android/view/transition/Scene.java new file mode 100644 index 0000000..62cb9d3 --- /dev/null +++ b/core/java/android/view/transition/Scene.java @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.view.transition; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.ViewGroup; + +/** + * A scene represents the collection of values that various properties in the + * View hierarchy will have when the scene is applied. A Scene can be + * configured to automatically run a Transition when it is applied, which will + * animate the various property changes that take place during the + * scene change. + */ +public final class Scene { + + private Context mContext; + private int mLayoutId = -1; + private ViewGroup mSceneRoot; + private ViewGroup mLayout; // alternative to layoutId + Runnable mEnterAction, mExitAction; + + /** + * Constructs a Scene with no information about how values will change + * when this scene is applied. This constructor might be used when + * a Scene is created with the intention of being dynamically configured, + * through setting {@link #setEnterAction(Runnable)} and possibly + * {@link #setExitAction(Runnable)}. + * + * @param sceneRoot The root of the hierarchy in which scene changes + * and transitions will take place. + */ + public Scene(ViewGroup sceneRoot) { + mSceneRoot = sceneRoot; + } + + /** + * Constructs a Scene which, when entered, will remove any + * children from the sceneRoot container and will inflate and add + * the hierarchy specified by the layoutId resource file. + * + * @param sceneRoot The root of the hierarchy in which scene changes + * and transitions will take place. + * @param layoutId The id of a resource file that defines the view + * hierarchy of this scene. + * @param context The context used in the process of inflating + * the layout resource. + */ + public Scene(ViewGroup sceneRoot, int layoutId, Context context) { + mContext = context; + mSceneRoot = sceneRoot; + mLayoutId = layoutId; + } + + /** + * Constructs a Scene which, when entered, will remove any + * children from the sceneRoot container and add the layout + * object as a new child of that container. + * + * @param sceneRoot The root of the hierarchy in which scene changes + * and transitions will take place. + * @param layout The view hiearrchy of this scene, added as a child + * of sceneRoot when this scene is entered. + */ + public Scene(ViewGroup sceneRoot, ViewGroup layout) { + mSceneRoot = sceneRoot; + mLayout = layout; + } + + /** + * Gets the root of the scene, which is the root of the view hierarchy + * affected by changes due to this scene, and which will be animated + * when this scene is entered. + * + * @return The root of the view hierarchy affected by this scene. + */ + public ViewGroup getSceneRoot() { + return mSceneRoot; + } + + /** + * Exits this scene, if it is the {@link ViewGroup#getCurrentScene() + * currentScene} on the scene's {@link #getSceneRoot() scene root}. + * Exiting a scene involves removing the layout added if the scene + * has either a layoutId or layout view group (set at construction + * time) and running the {@link #setExitAction(Runnable) exit action} + * if there is one. + */ + public void exit() { + if (mSceneRoot.getCurrentScene() == this) { + if (mLayoutId >= 0 || mLayout != null) { + // Undo layout change caused by entering this scene + getSceneRoot().removeAllViews(); + } + if (mExitAction != null) { + mExitAction.run(); + } + } + } + + /** + * Enters this scene, which entails changing all values that + * are specified by this scene. These may be values associated + * with a layout view group or layout resource file which will + * now be added to the scene root, or it may be values changed by + * an {@link #setEnterAction(Runnable)} enter action}, or a + * combination of the these. No transition will be run when the + * scene is entered. To get transition behavior in scene changes, + * use one of the methods in {@link TransitionManager} instead. + */ + public void enter() { + + // Apply layout change, if any + if (mLayoutId >= 0 || mLayout != null) { + // redundant with exit() action of previous scene, but must + // empty out that parent container before adding to it + getSceneRoot().removeAllViews(); + + if (mLayoutId >= 0) { + LayoutInflater.from(mContext).inflate(mLayoutId, mSceneRoot); + } else { + mSceneRoot.addView(mLayout); + } + } + + // Notify next scene that it is entering. Subclasses may override to configure scene. + if (mEnterAction != null) { + mEnterAction.run(); + } + + mSceneRoot.setCurrentScene(this ); + } + + /** + * Scenes that are not defined with layout resources or + * hierarchies, or which need to perform additional steps + * after those hierarchies are changed to, should set an enter + * action, and possibly an exit action as well. An enter action + * will cause Scene to call back into application code to do + * anything else the application needs after transitions have + * captured pre-change values and after any other scene changes + * have been applied, such as the layout (if any) being added to + * the view hierarchy. After this method is called, Transitions will + * be played. + * + * @param action The runnable whose {@link Runnable#run() run()} method will + * be called when this scene is entered + * @see #setExitAction(Runnable) + * @see Scene#Scene(ViewGroup, int, Context) + * @see Scene#Scene(ViewGroup, ViewGroup) + */ + public void setEnterAction(Runnable action) { + mEnterAction = action; + } + + /** + * Scenes that are not defined with layout resources or + * hierarchies, or which need to perform additional steps + * after those hierarchies are changed to, should set an enter + * action, and possibly an exit action as well. An exit action + * will cause Scene to call back into application code to do + * anything the application needs to do after applicable transitions have + * captured pre-change values, but before any other scene changes + * have been applied, such as the new layout (if any) being added to + * the view hierarchy. After this method is called, the next scene + * will be entered, including a call to {@link #setEnterAction(Runnable)} + * if an enter action is set. + * + * @see #setEnterAction(Runnable) + * @see Scene#Scene(ViewGroup, int, Context) + * @see Scene#Scene(ViewGroup, ViewGroup) + */ + public void setExitAction(Runnable action) { + mExitAction = action; + } + +}
\ No newline at end of file diff --git a/core/java/android/view/transition/Slide.java b/core/java/android/view/transition/Slide.java new file mode 100644 index 0000000..8630ee2 --- /dev/null +++ b/core/java/android/view/transition/Slide.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.view.transition; + +import android.animation.Animator; +import android.animation.ObjectAnimator; +import android.animation.TimeInterpolator; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.DecelerateInterpolator; + +/** + * This transition captures the visibility of target objects before and + * after a scene change and animates any changes by sliding the target + * objects into or out of place. + */ +public class Slide extends Visibility { + + // TODO: Add parameter for sliding factor - it's hard-coded below + + private static final TimeInterpolator sAccelerator = new AccelerateInterpolator(); + private static final TimeInterpolator sDecelerator = new DecelerateInterpolator(); + + @Override + protected Animator appear(ViewGroup sceneRoot, View startView, int startVisibility, + View endView, int endVisibility) { + ObjectAnimator anim = ObjectAnimator.ofFloat(endView, View.TRANSLATION_Y, + -2 * endView.getHeight(), 0); + anim.setInterpolator(sDecelerator); + return anim; + } + + @Override + protected boolean preAppear(ViewGroup sceneRoot, View startView, int startVisibility, + View endView, int endVisibility) { + endView.setTranslationY(-2 * endView.getHeight()); + return true; + } + + @Override + protected boolean preDisappear(ViewGroup sceneRoot, View startView, int startVisibility, + View endView, int endVisibility) { + startView.setTranslationY(0); + return true; + } + + @Override + protected Animator disappear(ViewGroup sceneRoot, View startView, int startVisibility, + View endView, int endVisibility) { + ObjectAnimator anim = ObjectAnimator.ofFloat(startView, View.TRANSLATION_Y, 0, + -2 * startView.getHeight()); + anim.setInterpolator(sAccelerator); + return anim; + } + +} diff --git a/core/java/android/view/transition/TextChange.java b/core/java/android/view/transition/TextChange.java new file mode 100644 index 0000000..0ba2412 --- /dev/null +++ b/core/java/android/view/transition/TextChange.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.view.transition; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ValueAnimator; +import android.view.ViewGroup; +import android.widget.TextView; + +import java.util.HashMap; + +/** + * This transition tracks changes to the text in TextView targets. If the text + * changes between the start and end scenes, the transition ensures that the + * starting text stays until the transition ends, at which point it changes + * to the end text. This is useful in situations where you want to resize a + * text view to its new size before displaying the text that goes there. + */ +public class TextChange extends Transition { + private static final String PROPNAME_TEXT = "android:textchange:text"; + + // TODO: think about other options we could have here, like cross-fading the text, or fading + // it out/in. These could be parameters to supply to the constructors (and xml attributes). + + @Override + protected void captureValues(TransitionValues values, boolean start) { + if (values.view instanceof TextView) { + TextView textview = (TextView) values.view; + values.values.put(PROPNAME_TEXT, textview.getText()); + } + } + + @Override + protected boolean prePlay(ViewGroup sceneRoot, TransitionValues startValues, + TransitionValues endValues) { + if (startValues == null || endValues == null || !(endValues.view instanceof TextView)) { + return false; + } + final TextView view = (TextView) endValues.view; + HashMap<String, Object> startVals = startValues.values; + HashMap<String, Object> endVals = endValues.values; + String startText = (String) startVals.get(PROPNAME_TEXT); + String endText = (String) endVals.get(PROPNAME_TEXT); + if (!startText.equals(endText)) { + view.setText(startText); + return true; + } + return false; + } + + @Override + protected Animator play(ViewGroup sceneRoot, TransitionValues startValues, + TransitionValues endValues) { + if (startValues == null || endValues == null || !(endValues.view instanceof TextView)) { + return null; + } + final TextView view = (TextView) endValues.view; + HashMap<String, Object> startVals = startValues.values; + HashMap<String, Object> endVals = endValues.values; + final String startText = (String) startVals.get(PROPNAME_TEXT); + final String endText = (String) endVals.get(PROPNAME_TEXT); + if (!startText.equals(endText)) { + // This noop animation is just used to keep the text in its start state + // until the transition ends + ValueAnimator anim = ValueAnimator.ofFloat(0, 1); + anim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + view.setText(endText); + } + }); + return anim; + } + return null; + } +} diff --git a/core/java/android/view/transition/Transition.java b/core/java/android/view/transition/Transition.java new file mode 100644 index 0000000..150c218 --- /dev/null +++ b/core/java/android/view/transition/Transition.java @@ -0,0 +1,911 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.view.transition; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.TimeInterpolator; +import android.util.LongSparseArray; +import android.util.SparseArray; +import android.view.SurfaceView; +import android.view.TextureView; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewOverlay; +import android.widget.ListView; + +import java.util.ArrayList; +import java.util.HashMap; + +/** + * A Transition holds information about animations that will be run on its + * targets during a scene change. Subclasses of this abstract class may + * choreograph several child transitions ({@link TransitionGroup} or they may + * perform custom animations themselves. Any Transition has two main jobs: + * (1) capture property values, and (2) play animations based on changes to + * captured property values. A custom transition knows what property values + * on View objects are of interest to it, and also knows how to animate + * changes to those values. For example, the {@link Fade} transition tracks + * changes to visibility-related properties and is able to construct and run + * animations that fade items in or out based on changes to those properties. + * + * <p>Note: Transitions may not work correctly with either {@link SurfaceView} + * or {@link TextureView}, due to the way that these views are displayed + * on the screen. For SurfaceView, the problem is that the view is updated from + * a non-UI thread, so changes to the view due to transitions (such as moving + * and resizing the view) may be out of sync with the display inside those bounds. + * TextureView is more compatible with transitions in general, but some + * specific transitions (such as {@link Crossfade}) may not be compatible + * with TextureView because they rely on {@link ViewOverlay} functionality, + * which does not currently work with TextureView.</p> + */ +public abstract class Transition { + + private static final String LOG_TAG = "Transition"; + static final boolean DBG = false; + + long mStartDelay = -1; + long mDuration = -1; + TimeInterpolator mInterpolator = null; + int[] mTargetIds; + View[] mTargets; + // TODO: sparse arrays instead of hashmaps? + private HashMap<View, TransitionValues> mStartValues = + new HashMap<View, TransitionValues>(); + private SparseArray<TransitionValues> mStartIdValues = new SparseArray<TransitionValues>(); + private LongSparseArray<TransitionValues> mStartItemIdValues = + new LongSparseArray<TransitionValues>(); + private HashMap<View, TransitionValues> mEndValues = + new HashMap<View, TransitionValues>(); + private SparseArray<TransitionValues> mEndIdValues = new SparseArray<TransitionValues>(); + private LongSparseArray<TransitionValues> mEndItemIdValues = + new LongSparseArray<TransitionValues>(); + + // Used to carry data between preplay() and play(), cleared before every scene transition + private ArrayList<TransitionValues> mPlayStartValuesList = new ArrayList<TransitionValues>(); + private ArrayList<TransitionValues> mPlayEndValuesList = new ArrayList<TransitionValues>(); + + // Number of per-target instances of this Transition currently running. This count is + // determined by calls to startTransition() and endTransition() + int mNumInstances = 0; + + + /** + * The set of listeners to be sent transition lifecycle events. + */ + ArrayList<TransitionListener> mListeners = null; + + /** + * Constructs a Transition object with no target objects. A transition with + * no targets defaults to running on all target objects in the scene hierarchy + * (if the transition is not contained in a TransitionGroup), or all target + * objects passed down from its parent (if it is in a TransitionGroup). + */ + public Transition() {} + + /** + * Sets the duration of this transition. By default, there is no duration + * (indicated by a negative number), which means that the Animator created by + * the transition will have its own specified duration. If the duration of a + * Transition is set, that duration will override the Animator duration. + * + * @param duration The length of the animation, in milliseconds. + * @return This transition object. + */ + public Transition setDuration(long duration) { + mDuration = duration; + return this; + } + + public long getDuration() { + return mDuration; + } + + /** + * Sets the startDelay of this transition. By default, there is no delay + * (indicated by a negative number), which means that the Animator created by + * the transition will have its own specified startDelay. If the delay of a + * Transition is set, that delay will override the Animator delay. + * + * @param startDelay The length of the delay, in milliseconds. + */ + public void setStartDelay(long startDelay) { + mStartDelay = startDelay; + } + + public long getStartDelay() { + return mStartDelay; + } + + /** + * Sets the interpolator of this transition. By default, the interpolator + * is null, which means that the Animator created by the transition + * will have its own specified interpolator. If the interpolator of a + * Transition is set, that interpolator will override the Animator interpolator. + * + * @param interpolator The time interpolator used by the transition + */ + public void setInterpolator(TimeInterpolator interpolator) { + mInterpolator = interpolator; + } + + public TimeInterpolator getInterpolator() { + return mInterpolator; + } + + /** + * This method is called by the transition's parent (all the way up to the + * topmost Transition in the hierarchy) with the sceneRoot and start/end + * values that the transition may need to run animations on its target + * views. The method is called for every applicable target object, which + * is stored in the {@link TransitionValues#view} field. When the method + * results in an animation needing to be run, the transition will construct + * the appropriate {@link Animator} object and return it. The transition + * mechanism will apply any applicable duration, startDelay, and interpolator + * to that animation and start it. Returning null from the method tells the + * transition engine that there is no animation to be played (TransitionGroup + * will return null because any applicable animations were started on its child + * transitions already and there is no animation to be run on the group itself). + * + * @param sceneRoot + * @param startValues + * @param endValues + * @return Animator The animation to run. + */ + protected abstract Animator play(ViewGroup sceneRoot, TransitionValues startValues, + TransitionValues endValues); + + /** + * This method is called by the transition's parent (all the way up to the + * topmost Transition in the hierarchy) with the sceneRoot and start/end + * values that the transition may need to set things up at the start of a + * Transition. For example, if an overall Transition consists of several + * child transitions in sequence, then some of the child transitions may + * want to set initial values on target views prior to the overall + * Transition commencing, to put them in an appropriate scene for the + * delay between that start and the child Transition start time. For + * example, a transition that fades an item in may wish to set the starting + * alpha value to 0, to avoid it blinking in prior to the transition + * actually starting the animation. This is necessary because the scene + * change that triggers the Transition will automatically set the end-scene + * on all target views, so a Transition that wants to animate from a + * different value should set that value in the preplay() method. + * + * <p>Additionally, a Transition can perform logic to determine whether + * the transition needs to run on the given target and start/end values. + * For example, a transition that resizes objects on the screen may wish + * to avoid running for views which are not present in either the start + * or end scenes. A return value of <code>false</code> indicates that + * the transition should not run, and there will be no ensuing call to the + * {@link #play(ViewGroup, TransitionValues, TransitionValues)} method during + * this scene change. The default implementation returns true.</p> + * + * <p>The method is called for every applicable target object, which is + * stored in the {@link TransitionValues#view} field.</p> + * + * @param sceneRoot + * @param startValues + * @param endValues + * @return True if the Transition's {@link #play(ViewGroup, + * TransitionValues, TransitionValues) play()} method should be called + * during this scene change, false otherwise. + */ + protected boolean prePlay(ViewGroup sceneRoot, TransitionValues startValues, + TransitionValues endValues) { + return true; + } + + /** + * This version of prePlay() is called with the entire set of start/end + * values. The implementation in Transition iterates through these lists + * and calls {@link #prePlay(ViewGroup, TransitionValues, TransitionValues)} + * with each set of start/end values on this transition. The + * TransitionGroup subclass overrides this method and delegates it to + * each of its children in succession. The intention in splitting + * preplay() out from play() is to allow all Transitions in the tree to + * set up the appropriate start scene for their target objects prior to + * any calls to play(), which is necessary when there is a sequential + * Transition, where a child transition which is not the first may want to + * set up a target's scene prior to the overall Transition start. + * + * @hide + */ + protected void prePlay(ViewGroup sceneRoot, HashMap<View, TransitionValues> startValues, + SparseArray<TransitionValues> startIdValues, + LongSparseArray<TransitionValues> startItemIdValues, + HashMap<View, TransitionValues> endValues, + SparseArray<TransitionValues> endIdValues, + LongSparseArray<TransitionValues> endItemIdValues) { + mPlayStartValuesList.clear(); + mPlayEndValuesList.clear(); + HashMap<View, TransitionValues> endCopy = new HashMap<View, TransitionValues>(endValues); + SparseArray<TransitionValues> endIdCopy = + new SparseArray<TransitionValues>(endIdValues.size()); + for (int i = 0; i < endIdValues.size(); ++i) { + int id = endIdValues.keyAt(i); + endIdCopy.put(id, endIdValues.valueAt(i)); + } + LongSparseArray<TransitionValues> endItemIdCopy = + new LongSparseArray<TransitionValues>(endItemIdValues.size()); + for (int i = 0; i < endItemIdValues.size(); ++i) { + long id = endItemIdValues.keyAt(i); + endItemIdCopy.put(id, endItemIdValues.valueAt(i)); + } + // Walk through the start values, playing everything we find + // Remove from the end set as we go + ArrayList<TransitionValues> startValuesList = new ArrayList<TransitionValues>(); + ArrayList<TransitionValues> endValuesList = new ArrayList<TransitionValues>(); + for (View view : startValues.keySet()) { + TransitionValues start = null; + TransitionValues end = null; + boolean isInListView = false; + if (view.getParent() instanceof ListView) { + isInListView = true; + } + if (!isInListView) { + int id = view.getId(); + start = startValues.get(view) != null ? + startValues.get(view) : startIdValues.get(id); + if (endValues.get(view) != null) { + end = endValues.get(view); + endCopy.remove(view); + } else { + end = endIdValues.get(id); + View removeView = null; + for (View viewToRemove : endCopy.keySet()) { + if (viewToRemove.getId() == id) { + removeView = viewToRemove; + } + } + if (removeView != null) { + endCopy.remove(removeView); + } + } + endIdCopy.remove(id); + if (isValidTarget(view, id)) { + startValuesList.add(start); + endValuesList.add(end); + } + } else { + ListView parent = (ListView) view.getParent(); + if (parent.getAdapter().hasStableIds()) { + int position = parent.getPositionForView(view); + long itemId = parent.getItemIdAtPosition(position); + start = startItemIdValues.get(itemId); + endItemIdCopy.remove(itemId); + // TODO: deal with targetIDs for itemIDs for ListView items + startValuesList.add(start); + endValuesList.add(end); + } + } + } + int startItemIdCopySize = startItemIdValues.size(); + for (int i = 0; i < startItemIdCopySize; ++i) { + long id = startItemIdValues.keyAt(i); + if (isValidTarget(null, id)) { + TransitionValues start = startItemIdValues.get(id); + TransitionValues end = endItemIdValues.get(id); + endItemIdCopy.remove(id); + startValuesList.add(start); + endValuesList.add(end); + } + } + // Now walk through the remains of the end set + for (View view : endCopy.keySet()) { + int id = view.getId(); + if (isValidTarget(view, id)) { + TransitionValues start = startValues.get(view) != null ? + startValues.get(view) : startIdValues.get(id); + TransitionValues end = endCopy.get(view); + endIdCopy.remove(id); + startValuesList.add(start); + endValuesList.add(end); + } + } + int endIdCopySize = endIdCopy.size(); + for (int i = 0; i < endIdCopySize; ++i) { + int id = endIdCopy.keyAt(i); + if (isValidTarget(null, id)) { + TransitionValues start = startIdValues.get(id); + TransitionValues end = endIdCopy.get(id); + startValuesList.add(start); + endValuesList.add(end); + } + } + int endItemIdCopySize = endItemIdCopy.size(); + for (int i = 0; i < endItemIdCopySize; ++i) { + long id = endItemIdCopy.keyAt(i); + // TODO: Deal with targetIDs and itemIDs + TransitionValues start = startItemIdValues.get(id); + TransitionValues end = endItemIdCopy.get(id); + startValuesList.add(start); + endValuesList.add(end); + } + for (int i = 0; i < startValuesList.size(); ++i) { + TransitionValues start = startValuesList.get(i); + TransitionValues end = endValuesList.get(i); + // TODO: what to do about targetIds and itemIds? + if (prePlay(sceneRoot, start, end)) { + // Note: we've already done the check against targetIDs in these lists + mPlayStartValuesList.add(start); + mPlayEndValuesList.add(end); + } + } + } + + /** + * Internal utility method for checking whether a given view/id + * is valid for this transition, where "valid" means that either + * the Transition has no target/targetId list (the default, in which + * cause the transition should act on all views in the hiearchy), or + * the given view is in the target list or the view id is in the + * targetId list. If the target parameter is null, then the target list + * is not checked (this is in the case of ListView items, where the + * views are ignored and only the ids are used). + */ + boolean isValidTarget(View target, long targetId) { + if (mTargetIds == null && mTargets == null) { + return true; + } + if (mTargetIds != null) { + for (int i = 0; i < mTargetIds.length; ++i) { + if (mTargetIds[i] == targetId) { + return true; + } + } + } + if (target != null && mTargets != null) { + for (int i = 0; i < mTargets.length; ++i) { + if (mTargets[i] == target) { + return true; + } + } + } + return false; + } + + /** + * This version of play() is called with the entire set of start/end + * values. The implementation in Transition iterates through these lists + * and calls {@link #play(ViewGroup, TransitionValues, TransitionValues)} + * with each set of start/end values on this transition. The + * TransitionGroup subclass overrides this method and delegates it to + * each of its children in succession. + * + * @hide + */ + protected void play(ViewGroup sceneRoot, + final HashMap<View, TransitionValues> startValues, + final SparseArray<TransitionValues> startIdValues, + final LongSparseArray<TransitionValues> startItemIdValues, + final HashMap<View, TransitionValues> endValues, + final SparseArray<TransitionValues> endIdValues, + final LongSparseArray<TransitionValues> endItemIdValues) { + + startTransition(); + // Now walk the list of TransitionValues, calling play for each pair + for (int i = 0; i < mPlayStartValuesList.size(); ++i) { + TransitionValues start = mPlayStartValuesList.get(i); + TransitionValues end = mPlayEndValuesList.get(i); + startTransition(); + animate(play(sceneRoot, start, end)); + } + mPlayStartValuesList.clear(); + mPlayEndValuesList.clear(); + endTransition(); + } + + /** + * Captures the current scene of values for the properties that this + * transition monitors. These values can be either the start or end + * values used in a subsequent call to + * {@link #play(ViewGroup, TransitionValues, TransitionValues)}, as indicated by + * <code>start</code>. The main concern for an implementation is what the + * properties are that the transition cares about and what the values are + * for all of those properties. The start and end values will be compared + * later during the preplay and play() methods to determine what, if any, + * animations, should be run. + * + * @param transitionValues The holder any values that the Transition + * wishes to store. Values are stored in the fields of this + * TransitionValues object, according to their type, and are keyed from + * a String value. For example, to start a view's rotation value, + * a Transition might call + * <code>transitionValues.floatValues.put("rotation", view.getRotation()) + * </code>. The target <code>View</code> will already be stored in + * the transitionValues structure when this method is called. The other + * fields in TransitionValues, e.g. <code>floatValues</code>, + * may need to be instantiated if they have not yet been created. + */ + protected abstract void captureValues(TransitionValues transitionValues, boolean start); + + /** + * Sets the ids of target views that this Transition is interested in + * animating. By default, there are no targetIds, and a Transition will + * listen for changes on every view in the hierarchy below the sceneRoot + * of the Scene being transitioned into. Setting targetIDs constrains + * the Transition to only listen for, and act on, views with these IDs. + * Views with different IDs, or no IDs whatsoever, will be ignored. + * + * @see View#getId() + * @param targetIds A list of IDs which specify the set of Views on which + * the Transition will act. + * @return Transition The Transition on which the targetIds have been set. + * Returning the same object makes it easier to chain calls during + * construction, such as + * <code>transitionGroup.addTransitions(new Fade()).setTargetIds(someId);</code> + */ + public Transition setTargetIds(int... targetIds) { + int numTargets = targetIds.length; + mTargetIds = new int[numTargets]; + System.arraycopy(targetIds, 0, mTargetIds, 0, numTargets); + return this; + } + + /** + * Sets the target view instances that this Transition is interested in + * animating. By default, there are no targets, and a Transition will + * listen for changes on every view in the hierarchy below the sceneRoot + * of the Scene being transitioned into. Setting targets constrains + * the Transition to only listen for, and act on, these views. + * All other views will be ignored. + * + * <p>The target list is like the {@link #setTargetIds(int...) targetId} + * list except this list specifies the actual View instances, not the ids + * of the views. This is an important distinction when scene changes involve + * view hierarchies which have been inflated separately; different views may + * share the same id but not actually be the same instance. If the transition + * should treat those views as the same, then seTargetIds() should be used + * instead of setTargets(). If, on the other hand, scene changes involve + * changes all within the same view hierarchy, among views which do not + * necessary have ids set on them, then the target list may be more + * convenient.</p> + * + * @see #setTargetIds(int...) + * @param targets A list of Views on which the Transition will act. + * @return Transition The Transition on which the targets have been set. + * Returning the same object makes it easier to chain calls during + * construction, such as + * <code>transitionGroup.addTransitions(new Fade()).setTargets(someView);</code> + */ + public Transition setTargets(View... targets) { + int numTargets = targets.length; + mTargets = new View[numTargets]; + System.arraycopy(targets, 0, mTargets, 0, numTargets); + return this; + } + + /** + * Returns the array of target IDs that this transition limits itself to + * tracking and animating. If the array is null for both this method and + * {@link #getTargets()}, then this transition is + * not limited to specific views, and will handle changes to any views + * in the hierarchy of a scene change. + * + * @return the list of target IDs + */ + public int[] getTargetIds() { + return mTargetIds; + } + + /** + * Returns the array of target views that this transition limits itself to + * tracking and animating. If the array is null for both this method and + * {@link #getTargetIds()}, then this transition is + * not limited to specific views, and will handle changes to any views + * in the hierarchy of a scene change. + * + * @return the list of target views + */ + public View[] getTargets() { + return mTargets; + } + + /** + * Recursive method that captures values for the given view and the + * hierarchy underneath it. + * @param sceneRoot The root of the view hierarchy being captured + * @param start true if this capture is happening before the scene change, + * false otherwise + */ + void captureValues(ViewGroup sceneRoot, boolean start) { + if (mTargetIds != null && mTargetIds.length > 0 || + mTargets != null && mTargets.length > 0) { + if (mTargetIds != null) { + for (int i = 0; i < mTargetIds.length; ++i) { + int id = mTargetIds[i]; + View view = sceneRoot.findViewById(id); + if (view != null) { + TransitionValues values = new TransitionValues(); + values.view = view; + captureValues(values, start); + if (start) { + mStartValues.put(view, values); + mStartIdValues.put(id, values); + } else { + mEndValues.put(view, values); + mEndIdValues.put(id, values); + } + } + } + } + if (mTargets != null) { + for (int i = 0; i < mTargets.length; ++i) { + View view = mTargets[i]; + if (view != null) { + TransitionValues values = new TransitionValues(); + values.view = view; + captureValues(values, start); + if (start) { + mStartValues.put(view, values); + } else { + mEndValues.put(view, values); + } + } + } + } + } else { + captureHierarchy(sceneRoot, start); + } + } + + /** + * Recursive method which captures values for an entire view hierarchy, + * starting at some root view. Transitions without targetIDs will use this + * method to capture values for all possible views. + * + * @param view The view for which to capture values. Children of this View + * will also be captured, recursively down to the leaf nodes. + * @param start true if values are being captured in the start scene, false + * otherwise. + */ + private void captureHierarchy(View view, boolean start) { + if (view == null) { + return; + } + boolean isListViewItem = false; + if (view.getParent() instanceof ListView) { + isListViewItem = true; + } + if (isListViewItem && !((ListView) view.getParent()).getAdapter().hasStableIds()) { + // ignore listview children unless we can track them with stable IDs + return; + } + long id; + if (!isListViewItem) { + id = view.getId(); + } else { + ListView listview = (ListView) view.getParent(); + int position = listview.getPositionForView(view); + id = listview.getItemIdAtPosition(position); + view.setHasTransientState(true); + } + TransitionValues values = new TransitionValues(); + values.view = view; + captureValues(values, start); + if (start) { + if (!isListViewItem) { + mStartValues.put(view, values); + mStartIdValues.put((int) id, values); + } else { + mStartItemIdValues.put(id, values); + } + } else { + if (!isListViewItem) { + mEndValues.put(view, values); + mEndIdValues.put((int) id, values); + } else { + mEndItemIdValues.put(id, values); + } + } + if (view instanceof ViewGroup) { + ViewGroup parent = (ViewGroup) view; + for (int i = 0; i < parent.getChildCount(); ++i) { + captureHierarchy(parent.getChildAt(i), start); + } + } + } + + /** + * Called by TransitionManager to play the transition. This calls + * prePlay() and then play() with the full set of per-view + * transitionValues objects + */ + void play(ViewGroup sceneRoot) { + // prePlay() must be called on entire transition hierarchy and set of views + // before calling play() on anything; every transition needs a chance to set up + // target views appropriately before transitions begin running + prePlay(sceneRoot, mStartValues, mStartIdValues, mStartItemIdValues, + mEndValues, mEndIdValues, mEndItemIdValues); + play(sceneRoot, mStartValues, mStartIdValues, mStartItemIdValues, + mEndValues, mEndIdValues, mEndItemIdValues); + } + + /** + * This is a utility method used by subclasses to handle standard parts of + * setting up and running an Animator: it sets the {@link #getDuration() + * duration} and the {@link #getStartDelay() startDelay}, starts the + * animation, and, when the animator ends, calls {@link #endTransition()}. + * + * @param animator The Animator to be run during this transition. + * + * @hide + */ + protected void animate(Animator animator) { + // TODO: maybe pass auto-end as a boolean parameter? + if (animator == null) { + endTransition(); + } else { + if (getDuration() >= 0) { + animator.setDuration(getDuration()); + } + if (getStartDelay() >= 0) { + animator.setStartDelay(getStartDelay()); + } + if (getInterpolator() != null) { + animator.setInterpolator(getInterpolator()); + } + animator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationCancel(Animator animation) { + cancelTransition(); + } + + @Override + public void onAnimationEnd(Animator animation) { + endTransition(); + animation.removeListener(this); + } + }); + animator.start(); + } + } + + /** + * Subclasses may override to receive notice of when the transition starts. + * This is equivalent to listening for the + * {@link TransitionListener#onTransitionStart(Transition)} callback. + */ + protected void onTransitionStart() { + } + + /** + * Subclasses may override to receive notice of when the transition is + * canceled. This is equivalent to listening for the + * {@link TransitionListener#onTransitionCancel(Transition)} callback. + */ + protected void onTransitionCancel() { + } + + /** + * Subclasses may override to receive notice of when the transition ends. + * This is equivalent to listening for the + * {@link TransitionListener#onTransitionEnd(Transition)} callback. + */ + protected void onTransitionEnd() { + } + + /** + * This method is called automatically by the transition and + * TransitionGroup classes prior to a Transition subclass starting; + * subclasses should not need to call it directly. + * + * @hide + */ + protected void startTransition() { + if (mNumInstances == 0) { + onTransitionStart(); + if (mListeners != null && mListeners.size() > 0) { + ArrayList<TransitionListener> tmpListeners = + (ArrayList<TransitionListener>) mListeners.clone(); + int numListeners = tmpListeners.size(); + for (int i = 0; i < numListeners; ++i) { + tmpListeners.get(i).onTransitionStart(this); + } + } + } + mNumInstances++; + } + + /** + * This method is called automatically by the Transition and + * TransitionGroup classes when a transition finishes, either because + * a transition did nothing (returned a null Animator from + * {@link Transition#play(ViewGroup, TransitionValues, + * TransitionValues)}) or because the transition returned a valid + * Animator and endTransition() was called in the onAnimationEnd() + * callback of the AnimatorListener. + * + * @hide + */ + protected void endTransition() { + --mNumInstances; + if (mNumInstances == 0) { + onTransitionEnd(); + if (mListeners != null && mListeners.size() > 0) { + ArrayList<TransitionListener> tmpListeners = + (ArrayList<TransitionListener>) mListeners.clone(); + int numListeners = tmpListeners.size(); + for (int i = 0; i < numListeners; ++i) { + tmpListeners.get(i).onTransitionEnd(this); + } + } + for (int i = 0; i < mStartItemIdValues.size(); ++i) { + TransitionValues tv = mStartItemIdValues.valueAt(i); + View v = tv.view; + if (v.hasTransientState()) { + v.setHasTransientState(false); + } + } + for (int i = 0; i < mEndItemIdValues.size(); ++i) { + TransitionValues tv = mEndItemIdValues.valueAt(i); + View v = tv.view; + if (v.hasTransientState()) { + v.setHasTransientState(false); + } + } + mStartValues.clear(); + mStartIdValues.clear(); + mStartItemIdValues.clear(); + mEndValues.clear(); + mEndIdValues.clear(); + mEndItemIdValues.clear(); + } + } + + /** + * This method cancels a transition that is currently running. + * Implementation TBD. + */ + protected void cancelTransition() { + // TODO: how does this work with instances? + // TODO: this doesn't actually do *anything* yet + onTransitionCancel(); + if (mListeners != null && mListeners.size() > 0) { + ArrayList<TransitionListener> tmpListeners = + (ArrayList<TransitionListener>) mListeners.clone(); + int numListeners = tmpListeners.size(); + for (int i = 0; i < numListeners; ++i) { + tmpListeners.get(i).onTransitionCancel(this); + } + } + } + + /** + * Adds a listener to the set of listeners that are sent events through the + * life of an animation, such as start, repeat, and end. + * + * @param listener the listener to be added to the current set of listeners + * for this animation. + */ + public void addListener(TransitionListener listener) { + if (mListeners == null) { + mListeners = new ArrayList<TransitionListener>(); + } + mListeners.add(listener); + } + + /** + * Removes a listener from the set listening to this animation. + * + * @param listener the listener to be removed from the current set of + * listeners for this transition. + */ + public void removeListener(TransitionListener listener) { + if (mListeners == null) { + return; + } + mListeners.remove(listener); + if (mListeners.size() == 0) { + mListeners = null; + } + } + + /** + * Gets the set of {@link TransitionListener} objects that are currently + * listening for events on this <code>Transition</code> object. + * + * @return ArrayList<TransitionListener> The set of listeners. + */ + public ArrayList<TransitionListener> getListeners() { + return mListeners; + } + + @Override + public String toString() { + return toString(""); + } + + String toString(String indent) { + String result = indent + getClass().getSimpleName() + "@" + + Integer.toHexString(hashCode()) + ": "; + result += "dur(" + mDuration + ") "; + result += "dly(" + mStartDelay + ") "; + result += "interp(" + mInterpolator + ") "; + result += "tgts("; + if (mTargetIds != null) { + for (int i = 0; i < mTargetIds.length; ++i) { + if (i > 0) { + result += ", "; + } + result += mTargetIds[i]; + } + } + if (mTargets != null) { + for (int i = 0; i < mTargets.length; ++i) { + if (i > 0) { + result += ", "; + } + result += mTargets[i]; + } + } + result += ")"; + return result; + } + + /** + * A transition listener receives notifications from a transition. + * Notifications indicate transition lifecycle events: when the transition + * begins, ends, or is canceled. + */ + public static interface TransitionListener { + /** + * Notification about the start of the transition. + * + * @param transition The started transition. + */ + void onTransitionStart(Transition transition); + + /** + * Notification about the end of the transition. Canceled transitions + * will always notify listeners of both the cancellation and end + * events. That is, {@link #onTransitionEnd()} is always called, + * regardless of whether the transition was canceled or played + * through to completion. + * + * @param transition The transition which reached its end. + */ + void onTransitionEnd(Transition transition); + + /** + * Notification about the cancellation of the transition. + * + * @param transition The transition which was canceled. + */ + void onTransitionCancel(Transition transition); + } + + /** + * Utility adapter class to avoid having to override all three methods + * whenever someone just wants to listen for a single event. + * + * @hide + * */ + public static class TransitionListenerAdapter implements TransitionListener { + @Override + public void onTransitionStart(Transition transition) { + } + + @Override + public void onTransitionEnd(Transition transition) { + } + + @Override + public void onTransitionCancel(Transition transition) { + } + } + +} diff --git a/core/java/android/view/transition/TransitionGroup.java b/core/java/android/view/transition/TransitionGroup.java new file mode 100644 index 0000000..363872a --- /dev/null +++ b/core/java/android/view/transition/TransitionGroup.java @@ -0,0 +1,292 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.view.transition; + +import android.animation.Animator; +import android.util.AndroidRuntimeException; +import android.util.LongSparseArray; +import android.util.SparseArray; +import android.view.View; +import android.view.ViewGroup; + +import java.util.ArrayList; +import java.util.HashMap; + +/** + * A TransitionGroup is a parent of child transitions (including other + * TransitionGroups). Using TransitionGroups enables more complex + * choreography of transitions, where some groups play {@link #TOGETHER} and + * others play {@link #SEQUENTIALLY}. For example, {@link AutoTransition} + * uses a TransitionGroup to sequentially play a Fade(Fade.OUT), followed by + * a {@link Move}, followed by a Fade(Fade.OUT) transition. + */ +public class TransitionGroup extends Transition { + + ArrayList<Transition> mTransitions = new ArrayList<Transition>(); + private boolean mPlayTogether = true; + int mCurrentListeners; + boolean mStarted = false; + + /** + * A flag used to indicate that the child transitions of this group + * should all start at the same time. + */ + public static final int TOGETHER = 0; + /** + * A flag used to indicate that the child transitions of this group should + * play in sequence; when one child transition ends, the next child + * transition begins. Note that a transition does not end until all + * instances of it (which are playing on all applicable targets of the + * transition) end. + */ + public static final int SEQUENTIALLY = 1; + + /** + * Constructs an empty transition group. Add child transitions to the + * group by calling to {@link #addTransitions(Transition...)} )}. By default, + * child transitions will play {@link #TOGETHER}. + */ + public TransitionGroup() { + } + + /** + * Constructs an empty transition group with the specified ordering. + * + * @param ordering {@link #TOGETHER} to start this group's child + * transitions together, {@link #SEQUENTIALLY} to play the child + * transitions in sequence. + * @see #setOrdering(int) + */ + public TransitionGroup(int ordering) { + setOrdering(ordering); + } + + /** + * Sets the play order of this group's child transitions. + * + * @param ordering {@link #TOGETHER} to start this group's child + * transitions together, {@link #SEQUENTIALLY} to play the child + * transitions in sequence. + */ + public void setOrdering(int ordering) { + switch (ordering) { + case SEQUENTIALLY: + mPlayTogether = false; + break; + case TOGETHER: + mPlayTogether = true; + break; + default: + throw new AndroidRuntimeException("Invalid parameter for TransitionGroup " + + "ordering: " + ordering); + } + } + + /** + * Adds child transitions to this group. The order of the child transitions + * passed in determines the order in which they are started. + * + * @param transitions A list of child transition to be added to this group. + */ + public void addTransitions(Transition... transitions) { + if (transitions != null) { + int numTransitions = transitions.length; + for (int i = 0; i < numTransitions; ++i) { + mTransitions.add(transitions[i]); + } + } + } + + /** + * Removes the specified child transition from this group. + * + * @param transition The transition to be removed. + */ + public void removeTransition(Transition transition) { + mTransitions.remove(transition); + } + + /** + * Sets up listeners for each of the child transitions. This is used to + * determine when this transition group is finished (all child transitions + * must finish first). + */ + private void setupStartEndListeners() { + for (Transition childTransition : mTransitions) { + childTransition.addListener(mListener); + } + mCurrentListeners = mTransitions.size(); + } + + /** + * This listener is used to detect when all child transitions are done, at + * which point this transition group is also done. + */ + private TransitionListener mListener = new TransitionListenerAdapter() { + @Override + public void onTransitionStart(Transition transition) { + if (!mStarted) { + startTransition(); + mStarted = true; + } + } + + @Override + public void onTransitionEnd(Transition transition) { + --mCurrentListeners; + if (mCurrentListeners == 0) { + // All child trans + mStarted = false; + endTransition(); + } + transition.removeListener(this); + } + }; + + /** + * @hide + */ + @Override + protected void prePlay(ViewGroup sceneRoot, + HashMap<View, TransitionValues> startValues, + SparseArray<TransitionValues> startIdValues, + LongSparseArray<TransitionValues> startItemIdValues, + HashMap<View, TransitionValues> endValues, + SparseArray<TransitionValues> endIdValues, + LongSparseArray<TransitionValues> endItemIdValues) { + for (Transition childTransition : mTransitions) { + childTransition.prePlay(sceneRoot, startValues, startIdValues, startItemIdValues, + endValues, endIdValues, endItemIdValues); + } + } + + /** + * @hide + */ + @Override + protected void play(ViewGroup sceneRoot, + final HashMap<View, TransitionValues> startValues, + final SparseArray<TransitionValues> startIdValues, + final LongSparseArray<TransitionValues> startItemIdValues, + final HashMap<View, TransitionValues> endValues, + final SparseArray<TransitionValues> endIdValues, + final LongSparseArray<TransitionValues> endItemIdValues) { + setupStartEndListeners(); + final ViewGroup finalSceneRoot = sceneRoot; + if (!mPlayTogether) { + // Setup sequence with listeners + // TODO: Need to add listeners in such a way that we can remove them later if canceled + for (int i = 1; i < mTransitions.size(); ++i) { + Transition previousTransition = mTransitions.get(i - 1); + final Transition nextTransition = mTransitions.get(i); + previousTransition.addListener(new TransitionListenerAdapter() { + @Override + public void onTransitionEnd(Transition transition) { + nextTransition.play(finalSceneRoot, + startValues, startIdValues, startItemIdValues, + endValues, endIdValues, endItemIdValues); + transition.removeListener(this); + } + }); + } + Transition firstTransition = mTransitions.get(0); + if (firstTransition != null) { + firstTransition.play(finalSceneRoot, startValues, startIdValues, startItemIdValues, + endValues, endIdValues, endItemIdValues); + } + } else { + for (Transition childTransition : mTransitions) { + childTransition.play(finalSceneRoot, startValues, startIdValues, startItemIdValues, + endValues, endIdValues, endItemIdValues); + } + } + } + + @Override + protected Animator play(ViewGroup sceneRoot, + TransitionValues startValues, TransitionValues endValues) { + final View view = (endValues != null) ? endValues.view : + (startValues != null) ? startValues.view : null; + final int targetId = (view != null) ? view.getId() : -1; + // TODO: not sure this is a valid check - what about auto-targets? No need for ids. + if (targetId < 0) { + return null; + } + setupStartEndListeners(); + if (!mPlayTogether) { + final ViewGroup finalSceneRoot = sceneRoot; + final TransitionValues finalStartValues = startValues; + final TransitionValues finalEndValues = endValues; + // Setup sequence with listeners + // TODO: Need to add listeners in such a way that we can remove them later if canceled + for (int i = 1; i < mTransitions.size(); ++i) { + Transition previousTransition = mTransitions.get(i - 1); + final Transition nextTransition = mTransitions.get(i); + previousTransition.addListener(new TransitionListenerAdapter() { + @Override + public void onTransitionEnd(Transition transition) { + nextTransition.startTransition(); + if (nextTransition.isValidTarget(view, targetId)) { + animate(nextTransition.play(finalSceneRoot, finalStartValues, + finalEndValues)); + } else { + nextTransition.endTransition(); + } + } + }); + } + Transition firstTransition = mTransitions.get(0); + if (firstTransition != null) { + firstTransition.startTransition(); + if (firstTransition.isValidTarget(view, targetId)) { + animate(firstTransition.play(finalSceneRoot, finalStartValues, finalEndValues)); + } else { + firstTransition.endTransition(); + } + } + } else { + for (Transition childTransition : mTransitions) { + childTransition.startTransition(); + if (childTransition.isValidTarget(view, targetId)) { + animate(childTransition.play(sceneRoot, startValues, endValues)); + } else { + childTransition.endTransition(); + } + } + } + return null; + } + + @Override + protected void captureValues(TransitionValues transitionValues, boolean start) { + int targetId = transitionValues.view.getId(); + for (Transition childTransition : mTransitions) { + if (childTransition.isValidTarget(transitionValues.view, targetId)) { + childTransition.captureValues(transitionValues, start); + } + } + } + + @Override + String toString(String indent) { + String result = super.toString(indent); + for (int i = 0; i < mTransitions.size(); ++i) { + result += "\n" + mTransitions.get(i).toString(indent + " "); + } + return result; + } + +} diff --git a/core/java/android/view/transition/TransitionInflater.java b/core/java/android/view/transition/TransitionInflater.java new file mode 100644 index 0000000..a5f5836 --- /dev/null +++ b/core/java/android/view/transition/TransitionInflater.java @@ -0,0 +1,392 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.view.transition; + +import android.content.Context; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.content.res.XmlResourceParser; +import android.util.AttributeSet; +import android.util.SparseArray; +import android.util.Xml; +import android.view.InflateException; +import android.view.ViewGroup; +import android.view.animation.AnimationUtils; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; + +/** + * This class inflates scenes and transitions from resource files. + */ +public class TransitionInflater { + + // We only need one inflater for any given context. Also, this allows us to associate + // ids with unique instances per-Context, used to avoid re-inflating + // already-inflated resources into new/different instances + private static final HashMap<Context, TransitionInflater> sInflaterMap = + new HashMap<Context, TransitionInflater>(); + + private Context mContext; + // TODO: do we need id maps for transitions and transitionMgrs as well? + SparseArray<Scene> mScenes = new SparseArray<Scene>(); + + private TransitionInflater(Context context) { + mContext = context; + } + + /** + * Obtains the TransitionInflater from the given context. + */ + public static TransitionInflater from(Context context) { + TransitionInflater inflater = sInflaterMap.get(context); + if (inflater != null) { + return inflater; + } + inflater = new TransitionInflater(context); + sInflaterMap.put(context, inflater); + return inflater; + } + + /** + * Loads a {@link Transition} object from a resource + * + * @param resource The resource id of the transition to load + * @return The loaded Transition object + * @throws android.content.res.Resources.NotFoundException when the + * transition cannot be loaded + */ + public Transition inflateTransition(int resource) { + XmlResourceParser parser = mContext.getResources().getXml(resource); + try { + return createTransitionFromXml(parser, Xml.asAttributeSet(parser), null); + } catch (XmlPullParserException e) { + InflateException ex = new InflateException(e.getMessage()); + ex.initCause(e); + throw ex; + } catch (IOException e) { + InflateException ex = new InflateException( + parser.getPositionDescription() + + ": " + e.getMessage()); + ex.initCause(e); + throw ex; + } finally { + parser.close(); + } + } + + /** + * Loads a {@link TransitionManager} object from a resource + * + * + * + * @param resource The resource id of the transition manager to load + * @return The loaded TransitionManager object + * @throws android.content.res.Resources.NotFoundException when the + * transition manager cannot be loaded + */ + public TransitionManager inflateTransitionManager(int resource, ViewGroup sceneRoot) { + XmlResourceParser parser = mContext.getResources().getXml(resource); + try { + return createTransitionManagerFromXml(parser, Xml.asAttributeSet(parser), sceneRoot); + } catch (XmlPullParserException e) { + InflateException ex = new InflateException(e.getMessage()); + ex.initCause(e); + throw ex; + } catch (IOException e) { + InflateException ex = new InflateException( + parser.getPositionDescription() + + ": " + e.getMessage()); + ex.initCause(e); + throw ex; + } finally { + parser.close(); + } + } + + /** + * Loads a {@link Scene} object from a resource + * + * @param resource The resource id of the scene to load + * @return The loaded Scene object + * @throws android.content.res.Resources.NotFoundException when the scene + * cannot be loaded + */ + public Scene inflateScene(int resource, ViewGroup parent) { + Scene scene = mScenes.get(resource); + if (scene != null) { + return scene; + } + XmlResourceParser parser = mContext.getResources().getXml(resource); + try { + scene = createSceneFromXml(parser, Xml.asAttributeSet(parser), parent); + mScenes.put(resource, scene); + return scene; + } catch (XmlPullParserException e) { + InflateException ex = new InflateException(e.getMessage()); + ex.initCause(e); + throw ex; + } catch (IOException e) { + InflateException ex = new InflateException( + parser.getPositionDescription() + + ": " + e.getMessage()); + ex.initCause(e); + throw ex; + } finally { + parser.close(); + } + } + + + // + // Transition loading + // + + private Transition createTransitionFromXml(XmlPullParser parser, + AttributeSet attrs, TransitionGroup transitionGroup) + throws XmlPullParserException, IOException { + + Transition transition = null; + + // Make sure we are on a start tag. + int type; + int depth = parser.getDepth(); + + while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) + && type != XmlPullParser.END_DOCUMENT) { + + boolean newTransition = false; + + if (type != XmlPullParser.START_TAG) { + continue; + } + + String name = parser.getName(); + if ("fade".equals(name)) { + transition = new Fade(); + newTransition = true; + } else if ("move".equals(name)) { + transition = new Move(); + newTransition = true; + } else if ("slide".equals(name)) { + transition = new Slide(); + newTransition = true; + } else if ("autoTransition".equals(name)) { + transition = new AutoTransition(); + newTransition = true; + } else if ("recolor".equals(name)) { + transition = new Recolor(); + newTransition = true; + } else if ("transitionGroup".equals(name)) { + transition = new TransitionGroup(); + createTransitionFromXml(parser, attrs, ((TransitionGroup) transition)); + newTransition = true; + } else if ("targets".equals(name)) { + if (parser.getDepth() - 1 > depth && transition != null) { + // We're inside the child tag - add targets to the child + getTargetIDs(parser, attrs, transition); + } else if (parser.getDepth() - 1 == depth && transitionGroup != null) { + // add targets to the group + getTargetIDs(parser, attrs, transitionGroup); + } + } + if (transition != null || "targets".equals(name)) { + if (newTransition) { + loadTransition(transition, attrs); + if (transitionGroup != null) { + transitionGroup.addTransitions(transition); + } + } + } else { + throw new RuntimeException("Unknown scene name: " + parser.getName()); + } + } + + return transition; + } + + private void getTargetIDs(XmlPullParser parser, + AttributeSet attrs, Transition transition) throws XmlPullParserException, IOException { + + // Make sure we are on a start tag. + int type; + int depth = parser.getDepth(); + + ArrayList<Integer> targetIds = new ArrayList<Integer>(); + while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) + && type != XmlPullParser.END_DOCUMENT) { + + if (type != XmlPullParser.START_TAG) { + continue; + } + + String name = parser.getName(); + if (name.equals("target")) { + TypedArray a = mContext.obtainStyledAttributes(attrs, + com.android.internal.R.styleable.Transition); + int id = a.getResourceId(com.android.internal.R.styleable.Transition_targetID, -1); + if (id >= 0) { + targetIds.add(id); + } + } else { + throw new RuntimeException("Unknown scene name: " + parser.getName()); + } + } + int numTargets = targetIds.size(); + if (numTargets > 0) { + int[] targetsArray = new int[numTargets]; + for (int i = 0; i < targetIds.size(); ++i) { + targetsArray[i] = targetIds.get(i); + } + transition.setTargetIds(targetsArray); + } + } + + private Transition loadTransition(Transition transition, AttributeSet attrs) + throws Resources.NotFoundException { + + TypedArray a = + mContext.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Transition); + long duration = a.getInt(com.android.internal.R.styleable.Transition_duration, -1); + if (duration >= 0) { + transition.setDuration(duration); + } + long startOffset = a.getInt(com.android.internal.R.styleable.Transition_startOffset, -1); + if (startOffset > 0) { + transition.setStartDelay(startOffset); + } + final int resID = + a.getResourceId(com.android.internal.R.styleable.Animator_interpolator, 0); + if (resID > 0) { + transition.setInterpolator(AnimationUtils.loadInterpolator(mContext, resID)); + } + a.recycle(); + return transition; + } + + // + // TransitionManager loading + // + + private TransitionManager createTransitionManagerFromXml(XmlPullParser parser, + AttributeSet attrs, ViewGroup sceneRoot) throws XmlPullParserException, IOException { + + // Make sure we are on a start tag. + int type; + int depth = parser.getDepth(); + TransitionManager transitionManager = null; + + while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) + && type != XmlPullParser.END_DOCUMENT) { + + if (type != XmlPullParser.START_TAG) { + continue; + } + + String name = parser.getName(); + if (name.equals("transitionManager")) { + transitionManager = new TransitionManager(); + } else if (name.equals("transition") && (transitionManager != null)) { + loadTransition(attrs, sceneRoot, transitionManager); + } else { + throw new RuntimeException("Unknown scene name: " + parser.getName()); + } + } + return transitionManager; + } + + private void loadTransition(AttributeSet attrs, ViewGroup sceneRoot, + TransitionManager transitionManager) + throws Resources.NotFoundException { + + TypedArray a = mContext.obtainStyledAttributes(attrs, + com.android.internal.R.styleable.TransitionManager); + int transitionId = attrs.getAttributeResourceValue( + com.android.internal.R.styleable.TransitionManager_transition, -1); + Scene fromScene = null, toScene = null; + int fromId = attrs.getAttributeResourceValue( + com.android.internal.R.styleable.TransitionManager_fromScene, -1); + if (fromId >= 0) fromScene = inflateScene(fromId, sceneRoot); + int toId = attrs.getAttributeResourceValue( + com.android.internal.R.styleable.TransitionManager_toScene, -1); + if (toId >= 0) toScene = inflateScene(toId, sceneRoot); + if (transitionId >= 0) { + Transition transition = inflateTransition(transitionId); + if (transition != null) { + if (fromScene != null) { + if (toScene == null){ + throw new RuntimeException("No matching toScene for given fromScene " + + "for transition ID " + transitionId); + } else { + transitionManager.setTransition(fromScene, toScene, transition); + } + } else if (toId >= 0) { + transitionManager.setTransition(toScene, transition); + } + } + } + a.recycle(); + } + + // + // Scene loading + // + + private Scene createSceneFromXml(XmlPullParser parser, AttributeSet attrs, ViewGroup parent) + throws XmlPullParserException, IOException { + Scene scene = null; + + // Make sure we are on a start tag. + int type; + int depth = parser.getDepth(); + + while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) + && type != XmlPullParser.END_DOCUMENT) { + + if (type != XmlPullParser.START_TAG) { + continue; + } + + String name = parser.getName(); + if (name.equals("scene")) { + scene = loadScene(attrs, parent); + } else { + throw new RuntimeException("Unknown scene name: " + parser.getName()); + } + } + + return scene; + } + + private Scene loadScene(AttributeSet attrs, ViewGroup parent) + throws Resources.NotFoundException { + + Scene scene; + TypedArray a = mContext.obtainStyledAttributes(attrs, + com.android.internal.R.styleable.Scene); + int layoutId = a.getResourceId(com.android.internal.R.styleable.Scene_layout, -1); + if (layoutId >= 0) { + scene = new Scene(parent, layoutId, mContext); + } else { + scene = new Scene(parent); + } + a.recycle(); + return scene; + } +} diff --git a/core/java/android/view/transition/TransitionManager.java b/core/java/android/view/transition/TransitionManager.java new file mode 100644 index 0000000..5a1991c --- /dev/null +++ b/core/java/android/view/transition/TransitionManager.java @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.view.transition; + +import android.view.ViewGroup; +import android.view.ViewTreeObserver; + +import java.util.HashMap; + +/** + * This class manages the set of transitions that fire when there is a + * change of {@link Scene}. To use the manager, add scenes along with + * transition objects with calls to {@link #setTransition(Scene, Transition)} + * or {@link #setTransition(Scene, Scene, Transition)}. Setting specific + * transitions for scene changes is not required; by default, a Scene change + * will use {@link AutoTransition} to do something reasonable for most + * situations. Specifying other transitions for particular scene changes is + * only necessary if the application wants different transition behavior + * in these situations. + */ +public class TransitionManager { + // TODO: how to handle enter/exit? + + private static final Transition sDefaultTransition = new AutoTransition(); + private Transition mDefaultTransition = new AutoTransition(); + + HashMap<Scene, Transition> mSceneTransitions = new HashMap<Scene, Transition>(); + HashMap<Scene, HashMap<Scene, Transition>> mScenePairTransitions = + new HashMap<Scene, HashMap<Scene, Transition>>(); + + /** + * Sets the transition to be used for any scene change for which no + * other transition is explicitly set. The initial value is + * an {@link AutoTransition} instance. + * + * @param transition The default transition to be used for scene changes. + */ + public void setDefaultTransition(Transition transition) { + mDefaultTransition = transition; + } + + /** + * Gets the current default transition. The initial value is an {@link + * AutoTransition} instance. + * + * @return The current default transition. + * @see #setDefaultTransition(Transition) + */ + public Transition getDefaultTransition() { + return mDefaultTransition; + } + + /** + * Sets a specific transition to occur when the given scene is entered. + * + * @param scene The scene which, when applied, will cause the given + * transition to run. + * @param transition The transition that will play when the given scene is + * entered. A value of null will result in the default behavior of + * using {@link AutoTransition}. + */ + public void setTransition(Scene scene, Transition transition) { + mSceneTransitions.put(scene, transition); + } + + /** + * Sets a specific transition to occur when the given pair of scenes is + * exited/entered. + * + * @param fromScene The scene being exited when the given transition will + * be run + * @param toScene The scene being entered when the given transition will + * be run + * @param transition The transition that will play when the given scene is + * entered. A value of null will result in the default behavior of + * using {@link AutoTransition}. + */ + public void setTransition(Scene fromScene, Scene toScene, Transition transition) { + HashMap<Scene, Transition> sceneTransitionMap = mScenePairTransitions.get(toScene); + if (sceneTransitionMap == null) { + sceneTransitionMap = new HashMap<Scene, Transition>(); + mScenePairTransitions.put(toScene, sceneTransitionMap); + } + sceneTransitionMap.put(fromScene, transition); + } + + /** + * Returns the Transition for the given scene being entered. The result + * depends not only on the given scene, but also the scene which the + * {@link Scene#getSceneRoot() sceneRoot} of the Scene is currently in. + * + * @param scene The scene being entered + * @return The Transition to be used for the given scene change. If no + * Transition was specified for this scene change, {@link AutoTransition} + * will be used instead. + */ + private Transition getTransition(Scene scene) { + Transition transition = null; + ViewGroup sceneRoot = scene.getSceneRoot(); + if (sceneRoot != null) { + // TODO: cached in Scene instead? long-term, cache in View itself + Scene currScene = sceneRoot.getCurrentScene(); + if (currScene != null) { + HashMap<Scene, Transition> sceneTransitionMap = mScenePairTransitions.get(scene); + if (sceneTransitionMap != null) { + transition = sceneTransitionMap.get(currScene); + if (transition != null) { + return transition; + } + } + } + } + transition = mSceneTransitions.get(scene); + return (transition != null) ? transition : new AutoTransition(); + } + + /** + * This is where all of the work of a transition/scene-change is + * orchestrated. This method captures the start values for the given + * transition, exits the current Scene, enters the new scene, captures + * the end values for the transition, and finally plays the + * resulting values-populated transition. + * + * @param scene The scene being entered + * @param transition The transition to play for this scene change + */ + private static void changeScene(Scene scene, final Transition transition) { + + final ViewGroup sceneRoot = scene.getSceneRoot(); + + // Capture current values + if (transition != null) { + transition.captureValues(sceneRoot, true); + } + + // Notify previous scene that it is being exited + Scene previousScene = sceneRoot.getCurrentScene(); + if (previousScene != null) { + previousScene.exit(); + } + + scene.enter(); + + if (transition != null) { + final ViewTreeObserver observer = sceneRoot.getViewTreeObserver(); + observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { + public boolean onPreDraw() { + sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this); + transition.captureValues(sceneRoot, false); + transition.play(sceneRoot); + return true; + } + }); + } + } + + /** + * Change to the given scene, using the + * appropriate transition for this particular scene change + * (as specified to the TransitionManager, or the default + * if no such transition exists). + * + * @param scene The Scene to change to + */ + public void transitionTo(Scene scene) { + // Auto transition if there is no transition declared for the Scene, but there is + // a root or parent view + changeScene(scene, getTransition(scene)); + + } + + /** + * Static utility method to simply change to the given scene using + * the default transition for TransitionManager. + * + * @param scene The Scene to change to + */ + public static void go(Scene scene) { + changeScene(scene, sDefaultTransition); + } + + /** + * Static utility method to simply change to the given scene using + * the given transition. + * + * <p>Passing in <code>null</code> for the transition parameter will + * result in the scene changing without any transition running, and is + * equivalent to calling {@link Scene#exit()} on the scene root's + * {@link ViewGroup#getCurrentScene() current scene}, followed by + * {@link Scene#enter()} on the scene specified by the <code>scene</code> + * parameter.</p> + * + * @param scene The Scene to change to + * @param transition The transition to use for this scene change. A + * value of null causes the scene change to happen with no transition. + */ + public static void go(Scene scene, Transition transition) { + changeScene(scene, transition); + } + + /** + * Static utility method to simply change to a scene defined by the + * code in the given runnable, which will be executed after + * the current values have been captured for the transition. + * This is equivalent to creating a Scene and calling {@link + * Scene#setEnterAction(Runnable)} with the runnable, then calling + * {@link #go(Scene, Transition)}. The transition used will be the + * default provided by TransitionManager. + * + * @param sceneRoot The root of the View hierarchy used when this scene + * runs a transition automatically. + * @param action The runnable whose {@link Runnable#run() run()} method will + * be called. + */ + public static void go(ViewGroup sceneRoot, Runnable action) { + Scene scene = new Scene(sceneRoot); + scene.setEnterAction(action); + changeScene(scene, sDefaultTransition); + } + + /** + * Static utility method to simply change to a scene defined by the + * code in the given runnable, which will be executed after + * the current values have been captured for the transition. + * This is equivalent to creating a Scene and calling {@link + * Scene#setEnterAction(Runnable)} with the runnable, then calling + * {@link #go(Scene, Transition)}. The given transition will be + * used to animate the changes. + * + * <p>Passing in <code>null</code> for the transition parameter will + * result in the scene changing without any transition running, and is + * equivalent to calling {@link Scene#exit()} on the scene root's + * {@link ViewGroup#getCurrentScene() current scene}, followed by + * {@link Scene#enter()} on a new scene specified by the + * <code>action</code> parameter.</p> + * + * @param sceneRoot The root of the View hierarchy to run the transition on. + * @param action The runnable whose {@link Runnable#run() run()} method will + * be called. + * @param transition The transition to use for this change. A + * value of null causes the change to happen with no transition. + */ + public static void go(ViewGroup sceneRoot, Runnable action, Transition transition) { + Scene scene = new Scene(sceneRoot); + scene.setEnterAction(action); + changeScene(scene, transition); + } +} diff --git a/core/java/android/view/transition/TransitionValues.java b/core/java/android/view/transition/TransitionValues.java new file mode 100644 index 0000000..120ace8 --- /dev/null +++ b/core/java/android/view/transition/TransitionValues.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.view.transition; + +import android.view.View; +import android.view.ViewGroup; + +import java.util.HashMap; + +/** + * Data structure which holds cached values for the transition. + * The view field is the target which all of the values pertain to. + * The values field is a hashmap which holds information for fields + * according to names selected by the transitions. These names should + * be unique to avoid clobbering values stored by other transitions, + * such as the convention project:transition_name:property_name. For + * example, the platform might store a property "alpha" in a transition + * "Fader" as "android:fader:alpha". + * + * <p>These values are cached during the + * {@link Transition#captureValues(TransitionValues, boolean)} + * capture} phases of a scene change, once when the start values are captured + * and again when the end values are captured. These start/end values are then + * passed into the transitions during the play phase of the scene change, + * for {@link Transition#prePlay(ViewGroup, TransitionValues, TransitionValues)} and + * for {@link Transition#play(ViewGroup, TransitionValues, TransitionValues)}.</p> + */ +public class TransitionValues { + + /** + * The View with these values + */ + public View view; + + /** + * The set of values tracked by transitions for this scene + */ + public final HashMap<String, Object> values = new HashMap<String, Object>(); + + @Override + public String toString() { + String returnValue = "TransitionValues@" + Integer.toHexString(hashCode()) + ":\n"; + returnValue += " view = " + view + "\n"; + returnValue += " values = " + values + "\n"; + return returnValue; + } +}
\ No newline at end of file diff --git a/core/java/android/view/transition/Visibility.java b/core/java/android/view/transition/Visibility.java new file mode 100644 index 0000000..a3e6e77 --- /dev/null +++ b/core/java/android/view/transition/Visibility.java @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.view.transition; + +import android.animation.Animator; +import android.view.View; +import android.view.ViewGroup; + +/** + * This transition tracks changes to the visibility of target views in the + * start and end scenes. Visibility is determined not just by the + * {@link View#setVisibility(int)} state of views, but also whether + * views exist in the current view hierarchy. The class is intended to be a + * utility for subclasses such as {@link Fade}, which use this visibility + * information to determine the specific animations to run when visibility + * changes occur. Subclasses should implement one or more of the methods + * {@link #preAppear(ViewGroup, View, int, View, int)}, + * {@link #preDisappear(ViewGroup, View, int, View, int)}, + * {@link #appear(ViewGroup, View, int, View, int)}, and + * {@link #disappear(ViewGroup, View, int, View, int)}. + */ +public abstract class Visibility extends Transition { + + private static final String PROPNAME_VISIBILITY = "android:visibility:visibility"; + private static final String PROPNAME_PARENT = "android:visibility:parent"; + + @Override + protected void captureValues(TransitionValues values, boolean start) { + int visibility = values.view.getVisibility(); + values.values.put(PROPNAME_VISIBILITY, visibility); + values.values.put(PROPNAME_PARENT, values.view.getParent()); + } + + @Override + protected boolean prePlay(ViewGroup sceneRoot, TransitionValues startValues, + TransitionValues endValues) { + boolean visibilityChange = false; + boolean fadeIn = false; + int startVisibility, endVisibility; + View startParent, endParent; + if (startValues != null) { + startVisibility = (Integer) startValues.values.get(PROPNAME_VISIBILITY); + startParent = (View) startValues.values.get(PROPNAME_PARENT); + } else { + startVisibility = -1; + startParent = null; + } + if (endValues != null) { + endVisibility = (Integer) endValues.values.get(PROPNAME_VISIBILITY); + endParent = (View) endValues.values.get(PROPNAME_PARENT); + } else { + endVisibility = -1; + endParent = null; + } + boolean existenceChange = false; + if (startValues != null && endValues != null) { + if (startVisibility == endVisibility && startParent == endParent) { + return false; + } else { + if (startVisibility != endVisibility) { + if (startVisibility == View.VISIBLE) { + fadeIn = false; + visibilityChange = true; + } else if (endVisibility == View.VISIBLE) { + fadeIn = true; + visibilityChange = true; + } + // no visibilityChange if going between INVISIBLE and GONE + } else if (startParent != endParent) { + existenceChange = true; + if (endParent == null) { + fadeIn = false; + visibilityChange = true; + } else if (startParent == null) { + fadeIn = true; + visibilityChange = true; + } + } + } + } + if (startValues == null) { + existenceChange = true; + fadeIn = true; + visibilityChange = true; + } else if (endValues == null) { + existenceChange = true; + fadeIn = false; + visibilityChange = true; + } + if (visibilityChange) { + if (fadeIn) { + return preAppear(sceneRoot, existenceChange ? null : startValues.view, + startVisibility, endValues.view, endVisibility); + } else { + return preDisappear(sceneRoot, startValues.view, startVisibility, + existenceChange ? null : endValues.view, endVisibility); + } + } else { + return false; + } + } + + @Override + protected Animator play(ViewGroup sceneRoot, TransitionValues startValues, + TransitionValues endValues) { + boolean visibilityChange = false; + boolean fadeIn = false; + int startVisibility, endVisibility; + View startParent, endParent; + if (startValues != null) { + startVisibility = (Integer) startValues.values.get(PROPNAME_VISIBILITY); + startParent = (View) startValues.values.get(PROPNAME_PARENT); + } else { + startVisibility = -1; + startParent = null; + } + if (endValues != null) { + endVisibility = (Integer) endValues.values.get(PROPNAME_VISIBILITY); + endParent = (View) endValues.values.get(PROPNAME_PARENT); + } else { + endVisibility = -1; + endParent = null; + } + boolean existenceChange = false; + if (startValues != null && endValues != null) { + if (startVisibility == endVisibility && startParent == endParent) { + return null; + } else { + if (startVisibility != endVisibility) { + if (startVisibility == View.VISIBLE) { + fadeIn = false; + visibilityChange = true; + } else if (endVisibility == View.VISIBLE) { + fadeIn = true; + visibilityChange = true; + } + // no visibilityChange if going between INVISIBLE and GONE + } else if (startParent != endParent) { + existenceChange = true; + if (endParent == null) { + fadeIn = false; + visibilityChange = true; + } else if (startParent == null) { + fadeIn = true; + visibilityChange = true; + } + } + } + } + if (startValues == null) { + existenceChange = true; + fadeIn = true; + visibilityChange = true; + } else if (endValues == null) { + existenceChange = true; + fadeIn = false; + visibilityChange = true; + } + if (visibilityChange) { + if (fadeIn) { + return appear(sceneRoot, existenceChange ? null : startValues.view, startVisibility, + endValues.view, endVisibility); + } else { + return disappear(sceneRoot, startValues.view, startVisibility, + existenceChange ? null : endValues.view, endVisibility); + } + } + return null; + } + + /** + * The default implementation of this method does nothing. Subclasses + * should override if they need to set up anything prior to the + * transition starting. + * + * @param sceneRoot + * @param startView + * @param startVisibility + * @param endView + * @param endVisibility + * @return + */ + protected boolean preAppear(ViewGroup sceneRoot, View startView, int startVisibility, + View endView, int endVisibility) { + return true; + } + + /** + * The default implementation of this method does nothing. Subclasses + * should override if they need to set up anything prior to the + * transition starting. + * @param sceneRoot + * @param startView + * @param startVisibility + * @param endView + * @param endVisibility + * @return + */ + protected boolean preDisappear(ViewGroup sceneRoot, View startView, int startVisibility, + View endView, int endVisibility) { + return true; + } + + /** + * The default implementation of this method does nothing. Subclasses + * should override if they need to do anything when target objects + * appear during the scene change. + * @param sceneRoot + * @param startView + * @param startVisibility + * @param endView + * @param endVisibility + */ + protected Animator appear(ViewGroup sceneRoot, View startView, int startVisibility, + View endView, int endVisibility) { return null; } + + /** + * The default implementation of this method does nothing. Subclasses + * should override if they need to do anything when target objects + * disappear during the scene change. + * @param sceneRoot + * @param startView + * @param startVisibility + * @param endView + * @param endVisibility + */ + protected Animator disappear(ViewGroup sceneRoot, View startView, int startVisibility, + View endView, int endVisibility) { return null; } + +} diff --git a/core/java/android/view/transition/package.html b/core/java/android/view/transition/package.html new file mode 100644 index 0000000..37dc0ec --- /dev/null +++ b/core/java/android/view/transition/package.html @@ -0,0 +1,25 @@ +<html> +<body> +<p>The classes in this package enable "scenes & transitions" functionality for +view hiearchies.</p> + +<p>A <b>Scene</b> is an encapsulation of the state of a view hiearchy, +including the views in that hierarchy and the various values (layout-related +and otherwise) that those views have. A scene be defined by a layout hierarchy +directly or some code which sets up the scene dynamically as it is entered.</p> + +<p>A <b>Transition</b> is a mechanism to automatically animate changes that occur +when a new scene is entered. Some transition capabilities are automatic. That +is, entering a scene may cause animations to run which fade out views that +go away, move and resize existing views that change, and fade in views that +become visible. There are additional transitions that can animate other +attributes, such as color changes, and which can optionally be specified +to take place during particular scene changes. Finally, developers can +define their own Transition subclasses which monitor particular property +changes and which run custom animations when those properties change values.</p> + +<p><b>TransitionManager</b> is used to specify custom transitions for particular +scene changes, and to cause scene changes with transitions to take place.</p> + +</body> +</html> diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index bf66292..ba85c1a 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -1151,10 +1151,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } if (mChoiceMode != CHOICE_MODE_NONE) { if (mCheckStates == null) { - mCheckStates = new SparseBooleanArray(); + mCheckStates = new SparseBooleanArray(0); } if (mCheckedIdStates == null && mAdapter != null && mAdapter.hasStableIds()) { - mCheckedIdStates = new LongSparseArray<Integer>(); + mCheckedIdStates = new LongSparseArray<Integer>(0); } // Modal multi-choice mode only has choices when the mode is active. Clear them. if (mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL) { @@ -1615,10 +1615,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() { + @Override public SavedState createFromParcel(Parcel in) { return new SavedState(in); } + @Override public SavedState[] newArray(int size) { return new SavedState[size]; } @@ -1943,8 +1945,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } final int top = getChildAt(0).getTop(); - final float fadeLength = (float) getVerticalFadingEdgeLength(); - return top < mPaddingTop ? (float) -(top - mPaddingTop) / fadeLength : fadeEdge; + final float fadeLength = getVerticalFadingEdgeLength(); + return top < mPaddingTop ? -(top - mPaddingTop) / fadeLength : fadeEdge; } } @@ -1961,9 +1963,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te final int bottom = getChildAt(count - 1).getBottom(); final int height = getHeight(); - final float fadeLength = (float) getVerticalFadingEdgeLength(); + final float fadeLength = getVerticalFadingEdgeLength(); return bottom > height - mPaddingBottom ? - (float) (bottom - height + mPaddingBottom) / fadeLength : fadeEdge; + (bottom - height + mPaddingBottom) / fadeLength : fadeEdge; } } @@ -2426,7 +2428,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * @return True if the selector should be shown */ boolean shouldShowSelector() { - return (hasFocus() && !isInTouchMode()) || touchModeDrawsInPressedState(); + return (!isInTouchMode()) || touchModeDrawsInPressedState(); } private void drawSelector(Canvas canvas) { @@ -2764,13 +2766,14 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } public boolean sameWindow() { - return hasWindowFocus() && getWindowAttachCount() == mOriginalAttachCount; + return getWindowAttachCount() == mOriginalAttachCount; } } private class PerformClick extends WindowRunnnable implements Runnable { int mClickMotionPosition; + @Override public void run() { // The data has changed since we posted this action in the event queue, // bail out before bad things happen @@ -2792,6 +2795,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } private class CheckForLongPress extends WindowRunnnable implements Runnable { + @Override public void run() { final int motionPosition = mMotionPosition; final View child = getChildAt(motionPosition - mFirstPosition); @@ -2815,6 +2819,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } private class CheckForKeyLongPress extends WindowRunnnable implements Runnable { + @Override public void run() { if (isPressed() && mSelectedPosition >= 0) { int index = mSelectedPosition - mFirstPosition; @@ -2989,6 +2994,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } final class CheckForTap implements Runnable { + @Override public void run() { if (mTouchMode == TOUCH_MODE_DOWN) { mTouchMode = TOUCH_MODE_TAP; @@ -3239,6 +3245,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } + @Override public void onTouchModeChanged(boolean isInTouchMode) { if (isInTouchMode) { // Get rid of the selection when we enter touch mode @@ -3299,95 +3306,153 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } - final int action = ev.getAction(); - - View v; - initVelocityTrackerIfNotExists(); mVelocityTracker.addMovement(ev); - switch (action & MotionEvent.ACTION_MASK) { - case MotionEvent.ACTION_DOWN: { - switch (mTouchMode) { - case TOUCH_MODE_OVERFLING: { - mFlingRunnable.endFling(); - if (mPositionScroller != null) { - mPositionScroller.stop(); - } - mTouchMode = TOUCH_MODE_OVERSCROLL; - mMotionX = (int) ev.getX(); - mMotionY = mLastY = (int) ev.getY(); - mMotionCorrection = 0; - mActivePointerId = ev.getPointerId(0); - mDirection = 0; + final int actionMasked = ev.getActionMasked(); + switch (actionMasked) { + case MotionEvent.ACTION_DOWN: { + onTouchDown(ev); break; } - default: { - mActivePointerId = ev.getPointerId(0); - final int x = (int) ev.getX(); - final int y = (int) ev.getY(); - int motionPosition = pointToPosition(x, y); - if (!mDataChanged) { - if ((mTouchMode != TOUCH_MODE_FLING) && (motionPosition >= 0) - && (getAdapter().isEnabled(motionPosition))) { - // User clicked on an actual view (and was not stopping a fling). - // It might be a click or a scroll. Assume it is a click until - // proven otherwise - mTouchMode = TOUCH_MODE_DOWN; - // FIXME Debounce - if (mPendingCheckForTap == null) { - mPendingCheckForTap = new CheckForTap(); - } - postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout()); - } else { - if (mTouchMode == TOUCH_MODE_FLING) { - // Stopped a fling. It is a scroll. - createScrollingCache(); - mTouchMode = TOUCH_MODE_SCROLL; - mMotionCorrection = 0; - motionPosition = findMotionRow(y); - mFlingRunnable.flywheelTouch(); - } - } - } + case MotionEvent.ACTION_MOVE: { + onTouchMove(ev); + break; + } + + case MotionEvent.ACTION_UP: { + onTouchUp(ev); + break; + } + + case MotionEvent.ACTION_CANCEL: { + onTouchCancel(); + break; + } + case MotionEvent.ACTION_POINTER_UP: { + onSecondaryPointerUp(ev); + final int x = mMotionX; + final int y = mMotionY; + final int motionPosition = pointToPosition(x, y); if (motionPosition >= 0) { // Remember where the motion event started - v = getChildAt(motionPosition - mFirstPosition); - mMotionViewOriginalTop = v.getTop(); + final View child = getChildAt(motionPosition - mFirstPosition); + mMotionViewOriginalTop = child.getTop(); + mMotionPosition = motionPosition; } + mLastY = y; + break; + } + + case MotionEvent.ACTION_POINTER_DOWN: { + // New pointers take over dragging duties + final int index = ev.getActionIndex(); + final int id = ev.getPointerId(index); + final int x = (int) ev.getX(index); + final int y = (int) ev.getY(index); + mMotionCorrection = 0; + mActivePointerId = id; mMotionX = x; mMotionY = y; - mMotionPosition = motionPosition; - mLastY = Integer.MIN_VALUE; + final int motionPosition = pointToPosition(x, y); + if (motionPosition >= 0) { + // Remember where the motion event started + final View child = getChildAt(motionPosition - mFirstPosition); + mMotionViewOriginalTop = child.getTop(); + mMotionPosition = motionPosition; + } + mLastY = y; break; } + } + + return true; + } + + private void onTouchDown(MotionEvent ev) { + View v; + switch (mTouchMode) { + case TOUCH_MODE_OVERFLING: { + mFlingRunnable.endFling(); + if (mPositionScroller != null) { + mPositionScroller.stop(); } + mTouchMode = TOUCH_MODE_OVERSCROLL; + mMotionX = (int) ev.getX(); + mMotionY = mLastY = (int) ev.getY(); + mMotionCorrection = 0; + mActivePointerId = ev.getPointerId(0); + mDirection = 0; + break; + } - if (performButtonActionOnTouchDown(ev)) { - if (mTouchMode == TOUCH_MODE_DOWN) { - removeCallbacks(mPendingCheckForTap); + default: { + mActivePointerId = ev.getPointerId(0); + final int x = (int) ev.getX(); + final int y = (int) ev.getY(); + int motionPosition = pointToPosition(x, y); + if (!mDataChanged) { + if ((mTouchMode != TOUCH_MODE_FLING) && (motionPosition >= 0) + && (getAdapter().isEnabled(motionPosition))) { + // User clicked on an actual view (and was not stopping a fling). + // It might be a click or a scroll. Assume it is a click until + // proven otherwise + mTouchMode = TOUCH_MODE_DOWN; + // FIXME Debounce + if (mPendingCheckForTap == null) { + mPendingCheckForTap = new CheckForTap(); + } + postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout()); + } else { + if (mTouchMode == TOUCH_MODE_FLING) { + // Stopped a fling. It is a scroll. + createScrollingCache(); + mTouchMode = TOUCH_MODE_SCROLL; + mMotionCorrection = 0; + motionPosition = findMotionRow(y); + mFlingRunnable.flywheelTouch(); + } } } + + if (motionPosition >= 0) { + // Remember where the motion event started + v = getChildAt(motionPosition - mFirstPosition); + mMotionViewOriginalTop = v.getTop(); + } + mMotionX = x; + mMotionY = y; + mMotionPosition = motionPosition; + mLastY = Integer.MIN_VALUE; break; } + } - case MotionEvent.ACTION_MOVE: { - int pointerIndex = ev.findPointerIndex(mActivePointerId); - if (pointerIndex == -1) { - pointerIndex = 0; - mActivePointerId = ev.getPointerId(pointerIndex); + if (performButtonActionOnTouchDown(ev)) { + if (mTouchMode == TOUCH_MODE_DOWN) { + removeCallbacks(mPendingCheckForTap); } - final int y = (int) ev.getY(pointerIndex); + } + } - if (mDataChanged) { - // Re-sync everything if data has been changed - // since the scroll operation can query the adapter. - layoutChildren(); - } + private void onTouchMove(MotionEvent ev) { + int pointerIndex = ev.findPointerIndex(mActivePointerId); + if (pointerIndex == -1) { + pointerIndex = 0; + mActivePointerId = ev.getPointerId(pointerIndex); + } - switch (mTouchMode) { + if (mDataChanged) { + // Re-sync everything if data has been changed + // since the scroll operation can query the adapter. + layoutChildren(); + } + + final int y = (int) ev.getY(pointerIndex); + + switch (mTouchMode) { case TOUCH_MODE_DOWN: case TOUCH_MODE_TAP: case TOUCH_MODE_DONE_WAITING: @@ -3399,262 +3464,219 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te case TOUCH_MODE_OVERSCROLL: scrollIfNeeded(y); break; - } - break; } + } - case MotionEvent.ACTION_UP: { - switch (mTouchMode) { - case TOUCH_MODE_DOWN: - case TOUCH_MODE_TAP: - case TOUCH_MODE_DONE_WAITING: - final int motionPosition = mMotionPosition; - final View child = getChildAt(motionPosition - mFirstPosition); + private void onTouchUp(MotionEvent ev) { + switch (mTouchMode) { + case TOUCH_MODE_DOWN: + case TOUCH_MODE_TAP: + case TOUCH_MODE_DONE_WAITING: + final int motionPosition = mMotionPosition; + final View child = getChildAt(motionPosition - mFirstPosition); - final float x = ev.getX(); - final boolean inList = x > mListPadding.left && x < getWidth() - mListPadding.right; + final float x = ev.getX(); + final boolean inList = x > mListPadding.left && x < getWidth() - mListPadding.right; - if (child != null && !child.hasFocusable() && inList) { - if (mTouchMode != TOUCH_MODE_DOWN) { - child.setPressed(false); - } + if (child != null && !child.hasFocusable() && inList) { + if (mTouchMode != TOUCH_MODE_DOWN) { + child.setPressed(false); + } - if (mPerformClick == null) { - mPerformClick = new PerformClick(); - } + if (mPerformClick == null) { + mPerformClick = new PerformClick(); + } - final AbsListView.PerformClick performClick = mPerformClick; - performClick.mClickMotionPosition = motionPosition; - performClick.rememberWindowAttachCount(); + final AbsListView.PerformClick performClick = mPerformClick; + performClick.mClickMotionPosition = motionPosition; + performClick.rememberWindowAttachCount(); - mResurrectToPosition = motionPosition; + mResurrectToPosition = motionPosition; - if (mTouchMode == TOUCH_MODE_DOWN || mTouchMode == TOUCH_MODE_TAP) { - final Handler handler = getHandler(); - if (handler != null) { - handler.removeCallbacks(mTouchMode == TOUCH_MODE_DOWN ? - mPendingCheckForTap : mPendingCheckForLongPress); + if (mTouchMode == TOUCH_MODE_DOWN || mTouchMode == TOUCH_MODE_TAP) { + final Handler handler = getHandler(); + if (handler != null) { + handler.removeCallbacks(mTouchMode == TOUCH_MODE_DOWN ? + mPendingCheckForTap : mPendingCheckForLongPress); + } + mLayoutMode = LAYOUT_NORMAL; + if (!mDataChanged && mAdapter.isEnabled(motionPosition)) { + mTouchMode = TOUCH_MODE_TAP; + setSelectedPositionInt(mMotionPosition); + layoutChildren(); + child.setPressed(true); + positionSelector(mMotionPosition, child); + setPressed(true); + if (mSelector != null) { + Drawable d = mSelector.getCurrent(); + if (d != null && d instanceof TransitionDrawable) { + ((TransitionDrawable) d).resetTransition(); + } } - mLayoutMode = LAYOUT_NORMAL; - if (!mDataChanged && mAdapter.isEnabled(motionPosition)) { - mTouchMode = TOUCH_MODE_TAP; - setSelectedPositionInt(mMotionPosition); - layoutChildren(); - child.setPressed(true); - positionSelector(mMotionPosition, child); - setPressed(true); - if (mSelector != null) { - Drawable d = mSelector.getCurrent(); - if (d != null && d instanceof TransitionDrawable) { - ((TransitionDrawable) d).resetTransition(); + if (mTouchModeReset != null) { + removeCallbacks(mTouchModeReset); + } + mTouchModeReset = new Runnable() { + @Override + public void run() { + mTouchModeReset = null; + mTouchMode = TOUCH_MODE_REST; + child.setPressed(false); + setPressed(false); + if (!mDataChanged) { + performClick.run(); } } - if (mTouchModeReset != null) { - removeCallbacks(mTouchModeReset); - } - mTouchModeReset = new Runnable() { - @Override - public void run() { - mTouchModeReset = null; - mTouchMode = TOUCH_MODE_REST; - child.setPressed(false); - setPressed(false); - if (!mDataChanged) { - performClick.run(); - } - } - }; - postDelayed(mTouchModeReset, - ViewConfiguration.getPressedStateDuration()); - } else { - mTouchMode = TOUCH_MODE_REST; - updateSelectorState(); - } - return true; - } else if (!mDataChanged && mAdapter.isEnabled(motionPosition)) { - performClick.run(); + }; + postDelayed(mTouchModeReset, + ViewConfiguration.getPressedStateDuration()); + } else { + mTouchMode = TOUCH_MODE_REST; + updateSelectorState(); } + return; + } else if (!mDataChanged && mAdapter.isEnabled(motionPosition)) { + performClick.run(); } - mTouchMode = TOUCH_MODE_REST; - updateSelectorState(); - break; - case TOUCH_MODE_SCROLL: - final int childCount = getChildCount(); - if (childCount > 0) { - final int firstChildTop = getChildAt(0).getTop(); - final int lastChildBottom = getChildAt(childCount - 1).getBottom(); - final int contentTop = mListPadding.top; - final int contentBottom = getHeight() - mListPadding.bottom; - if (mFirstPosition == 0 && firstChildTop >= contentTop && - mFirstPosition + childCount < mItemCount && - lastChildBottom <= getHeight() - contentBottom) { + } + mTouchMode = TOUCH_MODE_REST; + updateSelectorState(); + break; + case TOUCH_MODE_SCROLL: + final int childCount = getChildCount(); + if (childCount > 0) { + final int firstChildTop = getChildAt(0).getTop(); + final int lastChildBottom = getChildAt(childCount - 1).getBottom(); + final int contentTop = mListPadding.top; + final int contentBottom = getHeight() - mListPadding.bottom; + if (mFirstPosition == 0 && firstChildTop >= contentTop && + mFirstPosition + childCount < mItemCount && + lastChildBottom <= getHeight() - contentBottom) { + mTouchMode = TOUCH_MODE_REST; + reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); + } else { + final VelocityTracker velocityTracker = mVelocityTracker; + velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); + + final int initialVelocity = (int) + (velocityTracker.getYVelocity(mActivePointerId) * mVelocityScale); + // Fling if we have enough velocity and we aren't at a boundary. + // Since we can potentially overfling more than we can overscroll, don't + // allow the weird behavior where you can scroll to a boundary then + // fling further. + if (Math.abs(initialVelocity) > mMinimumVelocity && + !((mFirstPosition == 0 && + firstChildTop == contentTop - mOverscrollDistance) || + (mFirstPosition + childCount == mItemCount && + lastChildBottom == contentBottom + mOverscrollDistance))) { + if (mFlingRunnable == null) { + mFlingRunnable = new FlingRunnable(); + } + reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING); + + mFlingRunnable.start(-initialVelocity); + } else { mTouchMode = TOUCH_MODE_REST; reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); - } else { - final VelocityTracker velocityTracker = mVelocityTracker; - velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); - - final int initialVelocity = (int) - (velocityTracker.getYVelocity(mActivePointerId) * mVelocityScale); - // Fling if we have enough velocity and we aren't at a boundary. - // Since we can potentially overfling more than we can overscroll, don't - // allow the weird behavior where you can scroll to a boundary then - // fling further. - if (Math.abs(initialVelocity) > mMinimumVelocity && - !((mFirstPosition == 0 && - firstChildTop == contentTop - mOverscrollDistance) || - (mFirstPosition + childCount == mItemCount && - lastChildBottom == contentBottom + mOverscrollDistance))) { - if (mFlingRunnable == null) { - mFlingRunnable = new FlingRunnable(); - } - reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING); - - mFlingRunnable.start(-initialVelocity); - } else { - mTouchMode = TOUCH_MODE_REST; - reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); - if (mFlingRunnable != null) { - mFlingRunnable.endFling(); - } - if (mPositionScroller != null) { - mPositionScroller.stop(); - } + if (mFlingRunnable != null) { + mFlingRunnable.endFling(); + } + if (mPositionScroller != null) { + mPositionScroller.stop(); } } - } else { - mTouchMode = TOUCH_MODE_REST; - reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); - } - break; - - case TOUCH_MODE_OVERSCROLL: - if (mFlingRunnable == null) { - mFlingRunnable = new FlingRunnable(); - } - final VelocityTracker velocityTracker = mVelocityTracker; - velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); - final int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId); - - reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING); - if (Math.abs(initialVelocity) > mMinimumVelocity) { - mFlingRunnable.startOverfling(-initialVelocity); - } else { - mFlingRunnable.startSpringback(); } - - break; + } else { + mTouchMode = TOUCH_MODE_REST; + reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); } + break; - setPressed(false); - - if (mEdgeGlowTop != null) { - mEdgeGlowTop.onRelease(); - mEdgeGlowBottom.onRelease(); + case TOUCH_MODE_OVERSCROLL: + if (mFlingRunnable == null) { + mFlingRunnable = new FlingRunnable(); } + final VelocityTracker velocityTracker = mVelocityTracker; + velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); + final int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId); - // Need to redraw since we probably aren't drawing the selector anymore - invalidate(); - - final Handler handler = getHandler(); - if (handler != null) { - handler.removeCallbacks(mPendingCheckForLongPress); + reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING); + if (Math.abs(initialVelocity) > mMinimumVelocity) { + mFlingRunnable.startOverfling(-initialVelocity); + } else { + mFlingRunnable.startSpringback(); } - recycleVelocityTracker(); + break; + } - mActivePointerId = INVALID_POINTER; + setPressed(false); - if (PROFILE_SCROLLING) { - if (mScrollProfilingStarted) { - Debug.stopMethodTracing(); - mScrollProfilingStarted = false; - } - } - - if (mScrollStrictSpan != null) { - mScrollStrictSpan.finish(); - mScrollStrictSpan = null; - } - break; + if (mEdgeGlowTop != null) { + mEdgeGlowTop.onRelease(); + mEdgeGlowBottom.onRelease(); } - case MotionEvent.ACTION_CANCEL: { - switch (mTouchMode) { - case TOUCH_MODE_OVERSCROLL: - if (mFlingRunnable == null) { - mFlingRunnable = new FlingRunnable(); - } - mFlingRunnable.startSpringback(); - break; + // Need to redraw since we probably aren't drawing the selector anymore + invalidate(); - case TOUCH_MODE_OVERFLING: - // Do nothing - let it play out. - break; + final Handler handler = getHandler(); + if (handler != null) { + handler.removeCallbacks(mPendingCheckForLongPress); + } - default: - mTouchMode = TOUCH_MODE_REST; - setPressed(false); - View motionView = this.getChildAt(mMotionPosition - mFirstPosition); - if (motionView != null) { - motionView.setPressed(false); - } - clearScrollingCache(); + recycleVelocityTracker(); - final Handler handler = getHandler(); - if (handler != null) { - handler.removeCallbacks(mPendingCheckForLongPress); - } + mActivePointerId = INVALID_POINTER; - recycleVelocityTracker(); + if (PROFILE_SCROLLING) { + if (mScrollProfilingStarted) { + Debug.stopMethodTracing(); + mScrollProfilingStarted = false; } + } - if (mEdgeGlowTop != null) { - mEdgeGlowTop.onRelease(); - mEdgeGlowBottom.onRelease(); - } - mActivePointerId = INVALID_POINTER; - break; + if (mScrollStrictSpan != null) { + mScrollStrictSpan.finish(); + mScrollStrictSpan = null; } + } - case MotionEvent.ACTION_POINTER_UP: { - onSecondaryPointerUp(ev); - final int x = mMotionX; - final int y = mMotionY; - final int motionPosition = pointToPosition(x, y); - if (motionPosition >= 0) { - // Remember where the motion event started - v = getChildAt(motionPosition - mFirstPosition); - mMotionViewOriginalTop = v.getTop(); - mMotionPosition = motionPosition; + private void onTouchCancel() { + switch (mTouchMode) { + case TOUCH_MODE_OVERSCROLL: + if (mFlingRunnable == null) { + mFlingRunnable = new FlingRunnable(); } - mLastY = y; + mFlingRunnable.startSpringback(); break; - } - case MotionEvent.ACTION_POINTER_DOWN: { - // New pointers take over dragging duties - final int index = ev.getActionIndex(); - final int id = ev.getPointerId(index); - final int x = (int) ev.getX(index); - final int y = (int) ev.getY(index); - mMotionCorrection = 0; - mActivePointerId = id; - mMotionX = x; - mMotionY = y; - final int motionPosition = pointToPosition(x, y); - if (motionPosition >= 0) { - // Remember where the motion event started - v = getChildAt(motionPosition - mFirstPosition); - mMotionViewOriginalTop = v.getTop(); - mMotionPosition = motionPosition; - } - mLastY = y; + case TOUCH_MODE_OVERFLING: + // Do nothing - let it play out. break; - } + + default: + mTouchMode = TOUCH_MODE_REST; + setPressed(false); + View motionView = this.getChildAt(mMotionPosition - mFirstPosition); + if (motionView != null) { + motionView.setPressed(false); + } + clearScrollingCache(); + + final Handler handler = getHandler(); + if (handler != null) { + handler.removeCallbacks(mPendingCheckForLongPress); + } + + recycleVelocityTracker(); } - return true; + if (mEdgeGlowTop != null) { + mEdgeGlowTop.onRelease(); + mEdgeGlowBottom.onRelease(); + } + mActivePointerId = INVALID_POINTER; } @Override @@ -3733,7 +3755,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (scrollY != 0) { // Pin to the top/bottom during overscroll int restoreCount = canvas.save(); - canvas.translate(0, (float) scrollY); + canvas.translate(0, scrollY); mFastScroller.draw(canvas); canvas.restoreToCount(restoreCount); } else { @@ -3945,6 +3967,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te private int mLastFlingY; private final Runnable mCheckFlywheel = new Runnable() { + @Override public void run() { final int activeId = mActivePointerId; final VelocityTracker vt = mVelocityTracker; @@ -4066,6 +4089,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te postDelayed(mCheckFlywheel, FLYWHEEL_TIMEOUT); } + @Override public void run() { switch (mTouchMode) { default: @@ -4455,6 +4479,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te removeCallbacks(this); } + @Override public void run() { final int listHeight = getHeight(); final int firstPos = mFirstPosition; @@ -4637,9 +4662,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te /** * The amount of friction applied to flings. The default value * is {@link ViewConfiguration#getScrollFriction}. - * - * @return A scalar dimensionless value representing the coefficient of - * friction. */ public void setFriction(float friction) { if (mFlingRunnable == null) { @@ -4806,6 +4828,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (!isHardwareAccelerated()) { if (mClearScrollingCache == null) { mClearScrollingCache = new Runnable() { + @Override public void run() { if (mCachingStarted) { mCachingStarted = mCachingActive = false; @@ -5083,7 +5106,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te requestLayout(); invalidate(); } - + /** * If there is a selection returns false. * Otherwise resurrects the selection and returns true if resurrected. @@ -5706,6 +5729,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te return mFiltered; } + @Override public void onGlobalLayout() { if (isShown()) { // Show the popup if we are filtered @@ -5725,6 +5749,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * For our text watcher that is associated with the text filter. Does * nothing. */ + @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @@ -5733,6 +5758,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * the actual filtering as the text changes, and takes care of hiding and * showing the popup displaying the currently entered filter text. */ + @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if (mPopup != null && isTextFilterEnabled()) { int length = s.length(); @@ -5763,9 +5789,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * For our text watcher that is associated with the text filter. Does * nothing. */ + @Override public void afterTextChanged(Editable s) { } + @Override public void onFilterComplete(int count) { if (mSelectedPosition < 0 && count > 0) { mResurrectToPosition = INVALID_POSITION; @@ -5934,6 +5962,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * This defers a notifyDataSetChanged on the pending RemoteViewsAdapter if it has not * connected yet. */ + @Override public void deferNotifyDataSetChanged() { mDeferNotifyDataSetChanged = true; } @@ -5941,6 +5970,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te /** * Called back when the adapter connects to the RemoteViewsService. */ + @Override public boolean onRemoteAdapterConnected() { if (mRemoteAdapter != mAdapter) { setAdapter(mRemoteAdapter); @@ -5959,6 +5989,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te /** * Called back when the adapter disconnects from the RemoteViewsService. */ + @Override public void onRemoteAdapterDisconnected() { // If the remote adapter disconnects, we keep it around // since the currently displayed items are still cached. @@ -6041,6 +6072,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te return mWrapped != null; } + @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { if (mWrapped.onCreateActionMode(mode, menu)) { // Initialize checked graphic state? @@ -6050,14 +6082,17 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te return false; } + @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return mWrapped.onPrepareActionMode(mode, menu); } + @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { return mWrapped.onActionItemClicked(mode, item); } + @Override public void onDestroyActionMode(ActionMode mode) { mWrapped.onDestroyActionMode(mode); mChoiceActionMode = null; @@ -6072,6 +6107,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te setLongClickable(true); } + @Override public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { mWrapped.onItemCheckedStateChanged(mode, position, id, checked); diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index f57f333..91c989d 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -16,6 +16,13 @@ package android.widget; +import android.content.UndoManager; +import android.content.UndoOperation; +import android.content.UndoOwner; +import android.os.Parcel; +import android.os.Parcelable; +import android.text.InputFilter; +import android.text.SpannableString; import com.android.internal.util.ArrayUtils; import com.android.internal.widget.EditableInputConnection; @@ -107,11 +114,16 @@ import java.util.HashMap; */ public class Editor { private static final String TAG = "Editor"; + static final boolean DEBUG_UNDO = false; static final int BLINK = 500; private static final float[] TEMP_POSITION = new float[2]; private static int DRAG_SHADOW_MAX_TEXT_LENGTH = 20; + UndoManager mUndoManager; + UndoOwner mUndoOwner; + InputFilter mUndoInputFilter; + // Cursor Controllers. InsertionPointCursorController mInsertionPointCursorController; SelectionModifierCursorController mSelectionModifierCursorController; @@ -181,7 +193,10 @@ public class Editor { // Set when this TextView gained focus with some text selected. Will start selection mode. boolean mCreatedWithASelection; - private EasyEditSpanController mEasyEditSpanController; + // The span controller helps monitoring the changes to which the Editor needs to react: + // - EasyEditSpans, for which we have some UI to display on attach and on hide + // - SelectionSpans, for which we need to call updateSelection if an IME is attached + private SpanController mSpanController; WordIterator mWordIterator; SpellChecker mSpellChecker; @@ -466,8 +481,8 @@ public class Editor { } private void hideSpanControllers() { - if (mEasyEditSpanController != null) { - mEasyEditSpanController.hide(); + if (mSpanController != null) { + mSpanController.hide(); } } @@ -1082,9 +1097,12 @@ public class Editor { mTextView.updateAfterEdit(); reportExtractedText(); } else if (ims.mCursorChanged) { - // Cheezy way to get us to report the current cursor location. + // Cheesy way to get us to report the current cursor location. mTextView.invalidateCursor(); } + // sendUpdateSelection knows to avoid sending if the selection did + // not actually change. + sendUpdateSelection(); } static final int EXTRACT_NOTHING = -2; @@ -1205,6 +1223,27 @@ public class Editor { return false; } + private void sendUpdateSelection() { + if (null != mInputMethodState && mInputMethodState.mBatchEditNesting <= 0) { + final InputMethodManager imm = InputMethodManager.peekInstance(); + if (null != imm) { + final int selectionStart = mTextView.getSelectionStart(); + final int selectionEnd = mTextView.getSelectionEnd(); + int candStart = -1; + int candEnd = -1; + if (mTextView.getText() instanceof Spannable) { + final Spannable sp = (Spannable) mTextView.getText(); + candStart = EditableInputConnection.getComposingSpanStart(sp); + candEnd = EditableInputConnection.getComposingSpanEnd(sp); + } + // InputMethodManager#updateSelection skips sending the message if + // none of the parameters have changed since the last time we called it. + imm.updateSelection(mTextView, + selectionStart, selectionEnd, candStart, candEnd); + } + } + } + void onDraw(Canvas canvas, Layout layout, Path highlight, Paint highlightPaint, int cursorOffsetVertical) { final int selectionStart = mTextView.getSelectionStart(); @@ -1222,17 +1261,6 @@ public class Editor { // input method. reported = reportExtractedText(); } - if (!reported && highlight != null) { - int candStart = -1; - int candEnd = -1; - if (mTextView.getText() instanceof Spannable) { - Spannable sp = (Spannable) mTextView.getText(); - candStart = EditableInputConnection.getComposingSpanStart(sp); - candEnd = EditableInputConnection.getComposingSpanEnd(sp); - } - imm.updateSelection(mTextView, - selectionStart, selectionEnd, candStart, candEnd); - } } if (imm.isWatchingCursor(mTextView) && highlight != null) { @@ -1859,17 +1887,18 @@ public class Editor { text.setSpan(mKeyListener, 0, textLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE); } - if (mEasyEditSpanController == null) { - mEasyEditSpanController = new EasyEditSpanController(); + if (mSpanController == null) { + mSpanController = new SpanController(); } - text.setSpan(mEasyEditSpanController, 0, textLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE); + text.setSpan(mSpanController, 0, textLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE); } /** * Controls the {@link EasyEditSpan} monitoring when it is added, and when the related * pop-up should be displayed. + * Also monitors {@link Selection} to call back to the attached input method. */ - class EasyEditSpanController implements SpanWatcher { + class SpanController implements SpanWatcher { private static final int DISPLAY_TIMEOUT_MS = 3000; // 3 secs @@ -1877,9 +1906,18 @@ public class Editor { private Runnable mHidePopup; + // This function is pure but inner classes can't have static functions + private boolean isNonIntermediateSelectionSpan(final Spannable text, + final Object span) { + return (Selection.SELECTION_START == span || Selection.SELECTION_END == span) + && (text.getSpanFlags(span) & Spanned.SPAN_INTERMEDIATE) == 0; + } + @Override public void onSpanAdded(Spannable text, Object span, int start, int end) { - if (span instanceof EasyEditSpan) { + if (isNonIntermediateSelectionSpan(text, span)) { + sendUpdateSelection(); + } else if (span instanceof EasyEditSpan) { if (mPopupWindow == null) { mPopupWindow = new EasyEditPopupWindow(); mHidePopup = new Runnable() { @@ -1903,7 +1941,7 @@ public class Editor { int start = editable.getSpanStart(span); int end = editable.getSpanEnd(span); if (start >= 0 && end >= 0) { - sendNotification(EasyEditSpan.TEXT_DELETED, span); + sendEasySpanNotification(EasyEditSpan.TEXT_DELETED, span); mTextView.deleteText_internal(start, end); } editable.removeSpan(span); @@ -1934,7 +1972,9 @@ public class Editor { @Override public void onSpanRemoved(Spannable text, Object span, int start, int end) { - if (mPopupWindow != null && span == mPopupWindow.mEasyEditSpan) { + if (isNonIntermediateSelectionSpan(text, span)) { + sendUpdateSelection(); + } else if (mPopupWindow != null && span == mPopupWindow.mEasyEditSpan) { hide(); } } @@ -1942,9 +1982,11 @@ public class Editor { @Override public void onSpanChanged(Spannable text, Object span, int previousStart, int previousEnd, int newStart, int newEnd) { - if (mPopupWindow != null && span instanceof EasyEditSpan) { + if (isNonIntermediateSelectionSpan(text, span)) { + sendUpdateSelection(); + } else if (mPopupWindow != null && span instanceof EasyEditSpan) { EasyEditSpan easyEditSpan = (EasyEditSpan) span; - sendNotification(EasyEditSpan.TEXT_MODIFIED, easyEditSpan); + sendEasySpanNotification(EasyEditSpan.TEXT_MODIFIED, easyEditSpan); text.removeSpan(easyEditSpan); } } @@ -1956,7 +1998,7 @@ public class Editor { } } - private void sendNotification(int textChangedType, EasyEditSpan span) { + private void sendEasySpanNotification(int textChangedType, EasyEditSpan span) { try { PendingIntent pendingIntent = span.getPendingIntent(); if (pendingIntent != null) { @@ -1984,7 +2026,7 @@ public class Editor { /** * Displays the actions associated to an {@link EasyEditSpan}. The pop-up is controlled - * by {@link EasyEditSpanController}. + * by {@link SpanController}. */ private class EasyEditPopupWindow extends PinnedPopupWindow implements OnClickListener { @@ -3929,4 +3971,166 @@ public class Editor { mTextView.setCursorPosition_internal(newCursorPosition, newCursorPosition); } } + + public static class UndoInputFilter implements InputFilter { + final Editor mEditor; + + public UndoInputFilter(Editor editor) { + mEditor = editor; + } + + @Override + public CharSequence filter(CharSequence source, int start, int end, + Spanned dest, int dstart, int dend) { + if (DEBUG_UNDO) { + Log.d(TAG, "filter: source=" + source + " (" + start + "-" + end + ")"); + Log.d(TAG, "filter: dest=" + dest + " (" + dstart + "-" + dend + ")"); + } + final UndoManager um = mEditor.mUndoManager; + if (um.isInUndo()) { + if (DEBUG_UNDO) Log.d(TAG, "*** skipping, currently performing undo/redo"); + return null; + } + + um.beginUpdate("Edit text"); + TextModifyOperation op = um.getLastOperation( + TextModifyOperation.class, mEditor.mUndoOwner, UndoManager.MERGE_MODE_UNIQUE); + if (op != null) { + if (DEBUG_UNDO) Log.d(TAG, "Last op: range=(" + op.mRangeStart + "-" + op.mRangeEnd + + "), oldText=" + op.mOldText); + // See if we can continue modifying this operation. + if (op.mOldText == null) { + // The current operation is an add... are we adding more? We are adding + // more if we are either appending new text to the end of the last edit or + // completely replacing some or all of the last edit. + if (start < end && ((dstart >= op.mRangeStart && dend <= op.mRangeEnd) + || (dstart == op.mRangeEnd && dend == op.mRangeEnd))) { + op.mRangeEnd = dstart + (end-start); + um.endUpdate(); + if (DEBUG_UNDO) Log.d(TAG, "*** merging with last op, mRangeEnd=" + + op.mRangeEnd); + return null; + } + } else { + // The current operation is a delete... can we delete more? + if (start == end && dend == op.mRangeStart-1) { + SpannableStringBuilder str; + if (op.mOldText instanceof SpannableString) { + str = (SpannableStringBuilder)op.mOldText; + } else { + str = new SpannableStringBuilder(op.mOldText); + } + str.insert(0, dest, dstart, dend); + op.mRangeStart = dstart; + op.mOldText = str; + um.endUpdate(); + if (DEBUG_UNDO) Log.d(TAG, "*** merging with last op, range=(" + + op.mRangeStart + "-" + op.mRangeEnd + + "), oldText=" + op.mOldText); + return null; + } + } + + // Couldn't add to the current undo operation, need to start a new + // undo state for a new undo operation. + um.commitState(null); + um.setUndoLabel("Edit text"); + } + + // Create a new undo state reflecting the operation being performed. + op = new TextModifyOperation(mEditor.mUndoOwner); + op.mRangeStart = dstart; + if (start < end) { + op.mRangeEnd = dstart + (end-start); + } else { + op.mRangeEnd = dstart; + } + if (dstart < dend) { + op.mOldText = dest.subSequence(dstart, dend); + } + if (DEBUG_UNDO) Log.d(TAG, "*** adding new op, range=(" + op.mRangeStart + + "-" + op.mRangeEnd + "), oldText=" + op.mOldText); + um.addOperation(op, UndoManager.MERGE_MODE_NONE); + um.endUpdate(); + return null; + } + } + + public static class TextModifyOperation extends UndoOperation<TextView> { + int mRangeStart, mRangeEnd; + CharSequence mOldText; + + public TextModifyOperation(UndoOwner owner) { + super(owner); + } + + public TextModifyOperation(Parcel src, ClassLoader loader) { + super(src, loader); + mRangeStart = src.readInt(); + mRangeEnd = src.readInt(); + mOldText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(src); + } + + @Override + public void commit() { + } + + @Override + public void undo() { + swapText(); + } + + @Override + public void redo() { + swapText(); + } + + private void swapText() { + // Both undo and redo involves swapping the contents of the range + // in the text view with our local text. + TextView tv = getOwnerData(); + Editable editable = (Editable)tv.getText(); + CharSequence curText; + if (mRangeStart >= mRangeEnd) { + curText = null; + } else { + curText = editable.subSequence(mRangeStart, mRangeEnd); + } + if (DEBUG_UNDO) { + Log.d(TAG, "Swap: range=(" + mRangeStart + "-" + mRangeEnd + + "), oldText=" + mOldText); + Log.d(TAG, "Swap: curText=" + curText); + } + if (mOldText == null) { + editable.delete(mRangeStart, mRangeEnd); + mRangeEnd = mRangeStart; + } else { + editable.replace(mRangeStart, mRangeEnd, mOldText); + mRangeEnd = mRangeStart + mOldText.length(); + } + mOldText = curText; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(mRangeStart); + dest.writeInt(mRangeEnd); + TextUtils.writeToParcel(mOldText, dest, flags); + } + + public static final Parcelable.ClassLoaderCreator<TextModifyOperation> CREATOR + = new Parcelable.ClassLoaderCreator<TextModifyOperation>() { + public TextModifyOperation createFromParcel(Parcel in) { + return new TextModifyOperation(in, null); + } + + public TextModifyOperation createFromParcel(Parcel in, ClassLoader loader) { + return new TextModifyOperation(in, loader); + } + + public TextModifyOperation[] newArray(int size) { + return new TextModifyOperation[size]; + } + }; + } } diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java index 2309001..b0ab70d 100644 --- a/core/java/android/widget/GridLayout.java +++ b/core/java/android/widget/GridLayout.java @@ -24,7 +24,9 @@ import android.graphics.Insets; import android.graphics.Paint; import android.util.AttributeSet; import android.util.Log; +import android.util.LogPrinter; import android.util.Pair; +import android.util.Printer; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; @@ -124,6 +126,17 @@ import static java.lang.Math.min; * GridLayout's algorithms favour rows and columns that are closer to its <em>right</em> * and <em>bottom</em> edges. * + * <h4>Interpretation of GONE</h4> + * + * For layout purposes, GridLayout treats views whose visibility status is + * {@link View#GONE GONE}, as having zero width and height. This is subtly different from + * the policy of ignoring views that are marked as GONE outright. If, for example, a gone-marked + * view was alone in a column, that column would itself collapse to zero width if and only if + * no gravity was defined on the view. If gravity was defined, then the gone-marked + * view has no effect on the layout and the container should be laid out as if the view + * had never been added to it. + * These statements apply equally to rows as well as columns, and to groups of rows or columns. + * * <h5>Limitations</h5> * * GridLayout does not provide support for the principle of <em>weight</em>, as defined in @@ -208,10 +221,15 @@ public class GridLayout extends ViewGroup { // Misc constants - static final String TAG = GridLayout.class.getName(); static final int MAX_SIZE = 100000; static final int DEFAULT_CONTAINER_MARGIN = 0; static final int UNINITIALIZED_HASH = 0; + static final Printer LOG_PRINTER = new LogPrinter(Log.DEBUG, GridLayout.class.getName()); + static final Printer NO_PRINTER = new Printer() { + @Override + public void println(String x) { + } + }; // Defaults @@ -240,6 +258,7 @@ public class GridLayout extends ViewGroup { int alignmentMode = DEFAULT_ALIGNMENT_MODE; int defaultGap; int lastLayoutParamsHashCode = UNINITIALIZED_HASH; + Printer printer = LOG_PRINTER; // Constructors @@ -556,6 +575,29 @@ public class GridLayout extends ViewGroup { requestLayout(); } + /** + * Return the printer that will log diagnostics from this layout. + * + * @see #setPrinter(android.util.Printer) + * + * @return the printer associated with this view + */ + public Printer getPrinter() { + return printer; + } + + /** + * Set the printer that will log diagnostics from this layout. + * The default value is created by {@link android.util.LogPrinter}. + * + * @param printer the printer associated with this layout + * + * @see #getPrinter() + */ + public void setPrinter(Printer printer) { + this.printer = (printer == null) ? NO_PRINTER : printer; + } + // Static utility methods static int max2(int[] a, int valueIfEmpty) { @@ -915,7 +957,7 @@ public class GridLayout extends ViewGroup { protected void onChildVisibilityChanged(View child, int oldVisibility, int newVisibility) { super.onChildVisibilityChanged(child, oldVisibility, newVisibility); if (oldVisibility == GONE || newVisibility == GONE) { - invalidateStructure(); + invalidateStructure(); } } @@ -935,8 +977,8 @@ public class GridLayout extends ViewGroup { validateLayoutParams(); lastLayoutParamsHashCode = computeLayoutParamsHashCode(); } else if (lastLayoutParamsHashCode != computeLayoutParamsHashCode()) { - Log.w(TAG, "The fields of some layout parameters were modified in between layout " + - "operations. Check the javadoc for GridLayout.LayoutParams#rowSpec."); + printer.println("The fields of some layout parameters were modified in between " + + "layout operations. Check the javadoc for GridLayout.LayoutParams#rowSpec."); invalidateStructure(); consistencyCheck(); } @@ -1246,6 +1288,7 @@ public class GridLayout extends ViewGroup { Assoc<Spec, Bounds> assoc = Assoc.of(Spec.class, Bounds.class); for (int i = 0, N = getChildCount(); i < N; i++) { View c = getChildAt(i); + // we must include views that are GONE here, see introductory javadoc LayoutParams lp = getLayoutParams(c); Spec spec = horizontal ? lp.columnSpec : lp.rowSpec; Bounds bounds = getAlignment(spec.alignment, horizontal).getBounds(); @@ -1261,6 +1304,7 @@ public class GridLayout extends ViewGroup { } for (int i = 0, N = getChildCount(); i < N; i++) { View c = getChildAt(i); + // we must include views that are GONE here, see introductory javadoc LayoutParams lp = getLayoutParams(c); Spec spec = horizontal ? lp.columnSpec : lp.rowSpec; groupBounds.getValue(i).include(GridLayout.this, c, spec, this); @@ -1527,8 +1571,8 @@ public class GridLayout extends ViewGroup { removed.add(arc); } } - Log.d(TAG, axisName + " constraints: " + arcsToString(culprits) + " are inconsistent; " - + "permanently removing: " + arcsToString(removed) + ". "); + printer.println(axisName + " constraints: " + arcsToString(culprits) + + " are inconsistent; permanently removing: " + arcsToString(removed) + ". "); } /* @@ -2666,6 +2710,9 @@ public class GridLayout extends ViewGroup { @Override public int getAlignmentValue(View view, int viewSize, int mode) { + if (view.getVisibility() == GONE) { + return 0; + } int baseline = view.getBaseline(); return baseline == -1 ? UNDEFINED : baseline; } diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java index f42999d..a82bebd 100644 --- a/core/java/android/widget/ListView.java +++ b/core/java/android/widget/ListView.java @@ -2425,24 +2425,37 @@ public class ListView extends AbsListView { /** * Used by {@link #arrowScrollImpl(int)} to help determine the next selected position - * to move to. This can return a position currently not represented by a view on screen - * but only in the direction given. + * to move to. This return a position in the direction given if the selected item + * is fully visible. * + * @param selectedView Current selected view to move from * @param selectedPos Current selected position to move from * @param direction Direction to move in * @return Desired selected position after moving in the given direction */ - private final int nextSelectedPositionForDirection(int selectedPos, int direction) { + private final int nextSelectedPositionForDirection( + View selectedView, int selectedPos, int direction) { int nextSelected; + if (direction == View.FOCUS_DOWN) { - nextSelected = selectedPos != INVALID_POSITION && selectedPos >= mFirstPosition ? - selectedPos + 1 : - mFirstPosition; + final int listBottom = getHeight() - mListPadding.bottom; + if (selectedView != null && selectedView.getBottom() <= listBottom) { + nextSelected = selectedPos != INVALID_POSITION && selectedPos >= mFirstPosition ? + selectedPos + 1 : + mFirstPosition; + } else { + return INVALID_POSITION; + } } else { - final int lastPos = mFirstPosition + getChildCount() - 1; - nextSelected = selectedPos != INVALID_POSITION && selectedPos <= lastPos ? - selectedPos - 1 : - lastPos; + final int listTop = mListPadding.top; + if (selectedView != null && selectedView.getTop() >= listTop) { + final int lastPos = mFirstPosition + getChildCount() - 1; + nextSelected = selectedPos != INVALID_POSITION && selectedPos <= lastPos ? + selectedPos - 1 : + lastPos; + } else { + return INVALID_POSITION; + } } if (nextSelected < 0 || nextSelected >= mAdapter.getCount()) { @@ -2466,7 +2479,7 @@ public class ListView extends AbsListView { View selectedView = getSelectedView(); int selectedPos = mSelectedPosition; - int nextSelectedPosition = nextSelectedPositionForDirection(selectedPos, direction); + int nextSelectedPosition = nextSelectedPositionForDirection(selectedView, selectedPos, direction); int amountToScroll = amountToScroll(direction, nextSelectedPosition); // if we are moving focus, we may OVERRIDE the default behavior diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java index aeee111..3ff0cee 100644 --- a/core/java/android/widget/RemoteViewsAdapter.java +++ b/core/java/android/widget/RemoteViewsAdapter.java @@ -22,9 +22,11 @@ import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; +import android.Manifest; import android.appwidget.AppWidgetManager; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; @@ -34,6 +36,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.util.Log; +import android.util.Slog; import android.view.LayoutInflater; import android.view.View; import android.view.View.MeasureSpec; @@ -50,9 +53,11 @@ import com.android.internal.widget.LockPatternUtils; */ /** @hide */ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback { + private static final String MULTI_USER_PERM = Manifest.permission.INTERACT_ACROSS_USERS_FULL; + private static final String TAG = "RemoteViewsAdapter"; - // The max number of items in the cache + // The max number of items in the cache private static final int sDefaultCacheSize = 40; // The delay (in millis) to wait until attempting to unbind from a service after a request. // This ensures that we don't stay continually bound to the service and that it can be destroyed @@ -63,7 +68,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback private static final int sDefaultLoadingViewHeight = 50; // Type defs for controlling different messages across the main and worker message queues - private static final int sDefaultMessageType = 0; + private static final int sDefaultMessageType = 0; private static final int sUnbindServiceMessageType = 1; private final Context mContext; @@ -90,7 +95,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback private Handler mMainQueue; // We cache the FixedSizeRemoteViewsCaches across orientation. These are the related data - // structures; + // structures; private static final HashMap<RemoteViewsCacheKey, FixedSizeRemoteViewsCache> sCachedRemoteViewsCaches = new HashMap<RemoteViewsCacheKey, @@ -155,13 +160,12 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback try { RemoteViewsAdapter adapter; final AppWidgetManager mgr = AppWidgetManager.getInstance(context); - if (Process.myUid() == Process.SYSTEM_UID - && (adapter = mAdapter.get()) != null) { + if ((adapter = mAdapter.get()) != null) { + checkInteractAcrossUsersPermission(context, adapter.mUserId); mgr.bindRemoteViewsService(appWidgetId, intent, asBinder(), new UserHandle(adapter.mUserId)); } else { - mgr.bindRemoteViewsService(appWidgetId, intent, asBinder(), - Process.myUserHandle()); + Slog.w(TAG, "bind: adapter was null"); } mIsConnecting = true; } catch (Exception e) { @@ -176,12 +180,12 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback try { RemoteViewsAdapter adapter; final AppWidgetManager mgr = AppWidgetManager.getInstance(context); - if (Process.myUid() == Process.SYSTEM_UID - && (adapter = mAdapter.get()) != null) { + if ((adapter = mAdapter.get()) != null) { + checkInteractAcrossUsersPermission(context, adapter.mUserId); mgr.unbindRemoteViewsService(appWidgetId, intent, new UserHandle(adapter.mUserId)); } else { - mgr.unbindRemoteViewsService(appWidgetId, intent, Process.myUserHandle()); + Slog.w(TAG, "unbind: adapter was null"); } mIsConnecting = false; } catch (Exception e) { @@ -263,7 +267,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback // Clear the main/worker queues final RemoteViewsAdapter adapter = mAdapter.get(); if (adapter == null) return; - + adapter.mMainQueue.post(new Runnable() { @Override public void run() { @@ -828,11 +832,9 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback } mRequestedViews = new RemoteViewsFrameLayoutRefSet(); - if (Process.myUid() == Process.SYSTEM_UID) { - mUserId = new LockPatternUtils(context).getCurrentUser(); - } else { - mUserId = UserHandle.myUserId(); - } + checkInteractAcrossUsersPermission(context, UserHandle.myUserId()); + mUserId = context.getUserId(); + // Strip the previously injected app widget id from service intent if (intent.hasExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID)) { intent.removeExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID); @@ -876,6 +878,15 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback } } + private static void checkInteractAcrossUsersPermission(Context context, int userId) { + if (context.getUserId() != userId + && context.checkCallingOrSelfPermission(MULTI_USER_PERM) + != PackageManager.PERMISSION_GRANTED) { + throw new SecurityException("Must have permission " + MULTI_USER_PERM + + " to inflate another user's widget"); + } + } + @Override protected void finalize() throws Throwable { try { diff --git a/core/java/android/widget/ScrollBarDrawable.java b/core/java/android/widget/ScrollBarDrawable.java index 93a1179..9886bc3 100644 --- a/core/java/android/widget/ScrollBarDrawable.java +++ b/core/java/android/widget/ScrollBarDrawable.java @@ -226,6 +226,12 @@ public class ScrollBarDrawable extends Drawable { } @Override + public int getAlpha() { + // All elements should have same alpha, just return one of them + return mVerticalThumb.getAlpha(); + } + + @Override public void setColorFilter(ColorFilter cf) { if (mVerticalTrack != null) { mVerticalTrack.setColorFilter(cf); diff --git a/core/java/android/widget/TextClock.java b/core/java/android/widget/TextClock.java index a564c96..b3b95d9 100644 --- a/core/java/android/widget/TextClock.java +++ b/core/java/android/widget/TextClock.java @@ -95,6 +95,7 @@ public class TextClock extends TextView { * * @see #setFormat12Hour(CharSequence) * @see #getFormat12Hour() + * * @deprecated Let the system use locale-appropriate defaults instead. */ public static final CharSequence DEFAULT_FORMAT_12_HOUR = "h:mm a"; @@ -108,6 +109,7 @@ public class TextClock extends TextView { * * @see #setFormat24Hour(CharSequence) * @see #getFormat24Hour() + * * @deprecated Let the system use locale-appropriate defaults instead. */ public static final CharSequence DEFAULT_FORMAT_24_HOUR = "H:mm"; @@ -162,9 +164,7 @@ public class TextClock extends TextView { }; /** - * Creates a new clock using the default patterns - * {@link #DEFAULT_FORMAT_24_HOUR} and {@link #DEFAULT_FORMAT_12_HOUR} - * respectively for the 24-hour and 12-hour modes. + * Creates a new clock using the default patterns for the current locale. * * @param context The Context the view is running in, through which it can * access the current theme, resources, etc. @@ -258,20 +258,26 @@ public class TextClock extends TextView { } /** - * Specifies the formatting pattern used to display the date and/or time + * <p>Specifies the formatting pattern used to display the date and/or time * in 12-hour mode. The formatting pattern syntax is described in - * {@link DateFormat}. + * {@link DateFormat}.</p> * - * If this pattern is set to null, {@link #getFormat24Hour()} will be used + * <p>If this pattern is set to null, {@link #getFormat24Hour()} will be used * even in 12-hour mode. If both 24-hour and 12-hour formatting patterns - * are set to null, {@link #DEFAULT_FORMAT_24_HOUR} and - * {@link #DEFAULT_FORMAT_12_HOUR} will be used instead. + * are set to null, the default pattern for the current locale will be used + * instead.</p> + * + * <p><strong>Note:</strong> if styling is not needed, it is highly recommended + * you supply a format string generated by + * {@link DateFormat#getBestDateTimePattern(java.util.Locale, String)}. This method + * takes care of generating a format string adapted to the desired locale.</p> + * * * @param format A date/time formatting pattern as described in {@link DateFormat} * * @see #getFormat12Hour() * @see #is24HourModeEnabled() - * @see #DEFAULT_FORMAT_12_HOUR + * @see DateFormat#getBestDateTimePattern(java.util.Locale, String) * @see DateFormat * * @attr ref android.R.styleable#TextClock_format12Hour @@ -300,20 +306,25 @@ public class TextClock extends TextView { } /** - * Specifies the formatting pattern used to display the date and/or time + * <p>Specifies the formatting pattern used to display the date and/or time * in 24-hour mode. The formatting pattern syntax is described in - * {@link DateFormat}. + * {@link DateFormat}.</p> + * + * <p>If this pattern is set to null, {@link #getFormat24Hour()} will be used + * even in 12-hour mode. If both 24-hour and 12-hour formatting patterns + * are set to null, the default pattern for the current locale will be used + * instead.</p> * - * If this pattern is set to null, {@link #getFormat12Hour()} will be used - * even in 24-hour mode. If both 24-hour and 12-hour formatting patterns - * are set to null, {@link #DEFAULT_FORMAT_24_HOUR} and - * {@link #DEFAULT_FORMAT_12_HOUR} will be used instead. + * <p><strong>Note:</strong> if styling is not needed, it is highly recommended + * you supply a format string generated by + * {@link DateFormat#getBestDateTimePattern(java.util.Locale, String)}. This method + * takes care of generating a format string adapted to the desired locale.</p> * * @param format A date/time formatting pattern as described in {@link DateFormat} * * @see #getFormat24Hour() * @see #is24HourModeEnabled() - * @see #DEFAULT_FORMAT_24_HOUR + * @see DateFormat#getBestDateTimePattern(java.util.Locale, String) * @see DateFormat * * @attr ref android.R.styleable#TextClock_format24Hour @@ -334,8 +345,7 @@ public class TextClock extends TextView { * returned by {@link #getFormat12Hour()} is used instead. * * If either one of the formats is null, the other format is used. If - * both formats are null, the default values {@link #DEFAULT_FORMAT_12_HOUR} - * and {@link #DEFAULT_FORMAT_24_HOUR} are used instead. + * both formats are null, the default formats for the current locale are used. * * @return true if time should be displayed in 24-hour format, false if it * should be displayed in 12-hour format. diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 53cf82d..b1692d7 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -20,6 +20,7 @@ import android.R; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; +import android.content.UndoManager; import android.content.res.ColorStateList; import android.content.res.CompatibilityInfo; import android.content.res.Resources; @@ -284,6 +285,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private boolean mPreDrawRegistered; + // A flag to prevent repeated movements from escaping the enclosing text view. The idea here is + // that if a user is holding down a movement key to traverse text, we shouldn't also traverse + // the view hierarchy. On the other hand, if the user is using the movement key to traverse views + // (i.e. the first movement was to traverse out of this view, or this view was traversed into by + // the user holding the movement key down) then we shouldn't prevent the focus from changing. + private boolean mPreventDefaultMovement; + private TextUtils.TruncateAt mEllipsize; static class Drawables { @@ -1503,6 +1511,47 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } /** + * Retrieve the {@link android.content.UndoManager} that is currently associated + * with this TextView. By default there is no associated UndoManager, so null + * is returned. One can be associated with the TextView through + * {@link #setUndoManager(android.content.UndoManager, String)} + */ + public final UndoManager getUndoManager() { + return mEditor == null ? null : mEditor.mUndoManager; + } + + /** + * Associate an {@link android.content.UndoManager} with this TextView. Once + * done, all edit operations on the TextView will result in appropriate + * {@link android.content.UndoOperation} objects pushed on the given UndoManager's + * stack. + * + * @param undoManager The {@link android.content.UndoManager} to associate with + * this TextView, or null to clear any existing association. + * @param tag String tag identifying this particular TextView owner in the + * UndoManager. This is used to keep the correct association with the + * {@link android.content.UndoOwner} of any operations inside of the UndoManager. + */ + public final void setUndoManager(UndoManager undoManager, String tag) { + if (undoManager != null) { + createEditorIfNeeded(); + mEditor.mUndoManager = undoManager; + mEditor.mUndoOwner = undoManager.getOwner(tag, this); + mEditor.mUndoInputFilter = new Editor.UndoInputFilter(mEditor); + if (!(mText instanceof Editable)) { + setText(mText, BufferType.EDITABLE); + } + + setFilters((Editable) mText, mFilters); + } else if (mEditor != null) { + // XXX need to destroy all associated state. + mEditor.mUndoManager = null; + mEditor.mUndoOwner = null; + mEditor.mUndoInputFilter = null; + } + } + + /** * @return the current key listener for this TextView. * This will frequently be null for non-EditText TextViews. * @@ -4394,16 +4443,30 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * and includes mInput in the list if it is an InputFilter. */ private void setFilters(Editable e, InputFilter[] filters) { - if (mEditor != null && mEditor.mKeyListener instanceof InputFilter) { - InputFilter[] nf = new InputFilter[filters.length + 1]; - - System.arraycopy(filters, 0, nf, 0, filters.length); - nf[filters.length] = (InputFilter) mEditor.mKeyListener; + if (mEditor != null) { + final boolean undoFilter = mEditor.mUndoInputFilter != null; + final boolean keyFilter = mEditor.mKeyListener instanceof InputFilter; + int num = 0; + if (undoFilter) num++; + if (keyFilter) num++; + if (num > 0) { + InputFilter[] nf = new InputFilter[filters.length + num]; + + System.arraycopy(filters, 0, nf, 0, filters.length); + num = 0; + if (undoFilter) { + nf[filters.length] = mEditor.mUndoInputFilter; + num++; + } + if (keyFilter) { + nf[filters.length + num] = (InputFilter) mEditor.mKeyListener; + } - e.setFilters(nf); - } else { - e.setFilters(filters); + e.setFilters(nf); + return; + } } + e.setFilters(filters); } /** @@ -5268,7 +5331,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener public boolean onKeyDown(int keyCode, KeyEvent event) { int which = doKeyDown(keyCode, event, null); if (which == 0) { - // Go through default dispatching. return super.onKeyDown(keyCode, event); } @@ -5366,6 +5428,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return 0; } + // If this is the initial keydown, we don't want to prevent a movement away from this view. + // While this shouldn't be necessary because any time we're preventing default movement we + // should be restricting the focus to remain within this view, thus we'll also receive + // the key up event, occasionally key up events will get dropped and we don't want to + // prevent the user from traversing out of this on the next key down. + if (event.getRepeatCount() == 0 && !KeyEvent.isModifierKey(keyCode)) { + mPreventDefaultMovement = false; + } + switch (keyCode) { case KeyEvent.KEYCODE_ENTER: if (event.hasNoModifiers()) { @@ -5474,12 +5545,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } if (doDown) { - if (mMovement.onKeyDown(this, (Spannable)mText, keyCode, event)) + if (mMovement.onKeyDown(this, (Spannable)mText, keyCode, event)) { + if (event.getRepeatCount() == 0 && !KeyEvent.isModifierKey(keyCode)) { + mPreventDefaultMovement = true; + } return 2; + } } } - return 0; + return mPreventDefaultMovement && !KeyEvent.isModifierKey(keyCode) ? -1 : 0; } /** @@ -5512,6 +5587,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return super.onKeyUp(keyCode, event); } + if (!KeyEvent.isModifierKey(keyCode)) { + mPreventDefaultMovement = false; + } + switch (keyCode) { case KeyEvent.KEYCODE_DPAD_CENTER: if (event.hasNoModifiers()) { diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java index 1d85126..aaa1adaa 100644 --- a/core/java/android/widget/Toast.java +++ b/core/java/android/widget/Toast.java @@ -29,6 +29,7 @@ import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; +import android.view.View.OnClickListener; import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; @@ -74,6 +75,9 @@ public class Toast { */ public static final int LENGTH_LONG = 1; + /** @hide */ + public static final int LENGTH_INFINITE = 2; + final Context mContext; final TN mTN; int mDuration; @@ -288,6 +292,61 @@ public class Toast { tv.setText(s); } + /** @hide */ + public static Toast makeBar(Context context, int resId, int duration) { + return makeBar(context, context.getResources().getText(resId), duration); + } + + /** @hide */ + public static Toast makeBar(Context context, CharSequence text, int duration) { + Toast result = new Toast(context); + + LayoutInflater inflate = (LayoutInflater) + context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View v = inflate.inflate(com.android.internal.R.layout.toast_bar, null); + ((TextView)v.findViewById(android.R.id.message)).setText(text); + v.findViewById(android.R.id.button1).setVisibility(View.GONE); + + result.mNextView = v; + result.mDuration = duration; + result.mTN.mParams.alpha = 0.9f; + result.mTN.mParams.windowAnimations = com.android.internal.R.style.Animation_ToastBar; + + return result; + } + + /** @hide */ + public Toast setAction(int resId, Runnable action) { + return setAction(mContext.getResources().getText(resId), action); + } + + /** @hide */ + public Toast setAction(CharSequence actionText, final Runnable action) { + if (mNextView != null) { + TextView text1 = (TextView)mNextView.findViewById(android.R.id.text1); + View button1 = mNextView.findViewById(android.R.id.button1); + if (text1 != null && button1 != null) { + text1.setText(actionText); + button1.setVisibility(View.VISIBLE); + button1.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (action != null) { + action.run(); + } + }}); + return setInteractive(true); + } + } + throw new RuntimeException("This Toast was not created with Toast.makeBar()"); + } + + /** @hide */ + public Toast setInteractive(boolean interactive) { + mTN.setInteractive(interactive); + return this; + } + // ======================================================================================= // All the gunk below is the interaction with the Notification Service, which handles // the proper ordering of these system-wide. @@ -340,13 +399,20 @@ public class Toast { final WindowManager.LayoutParams params = mParams; params.height = WindowManager.LayoutParams.WRAP_CONTENT; params.width = WindowManager.LayoutParams.WRAP_CONTENT; - params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE - | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE - | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; params.format = PixelFormat.TRANSLUCENT; params.windowAnimations = com.android.internal.R.style.Animation_Toast; params.type = WindowManager.LayoutParams.TYPE_TOAST; params.setTitle("Toast"); + setInteractive(false); + } + + private void setInteractive(boolean interactive) { + mParams.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON + | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | (interactive + ? (WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL + | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH) + : WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); } /** diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java index acbb2b1..e092fff 100644 --- a/core/java/com/android/internal/app/ActionBarImpl.java +++ b/core/java/com/android/internal/app/ActionBarImpl.java @@ -1210,6 +1210,10 @@ public class ActionBarImpl extends ActionBar { mActionView.setIcon(icon); } + public boolean hasIcon() { + return mActionView.hasIcon(); + } + @Override public void setLogo(int resId) { mActionView.setLogo(resId); @@ -1220,6 +1224,10 @@ public class ActionBarImpl extends ActionBar { mActionView.setLogo(logo); } + public boolean hasLogo() { + return mActionView.hasLogo(); + } + public void setDefaultDisplayHomeAsUpEnabled(boolean enable) { if (!mDisplayHomeAsUpSet) { setDisplayHomeAsUpEnabled(enable); diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index c22cd26..a674776 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -16,6 +16,7 @@ package com.android.internal.app; +import android.os.AsyncTask; import com.android.internal.R; import com.android.internal.content.PackageMonitor; @@ -621,9 +622,11 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte view = mInflater.inflate( com.android.internal.R.layout.resolve_list_item, parent, false); + final ViewHolder holder = new ViewHolder(view); + view.setTag(holder); + // Fix the icon size even if we have different sized resources - ImageView icon = (ImageView)view.findViewById(R.id.icon); - ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) icon.getLayoutParams(); + ViewGroup.LayoutParams lp = holder.icon.getLayoutParams(); lp.width = lp.height = mIconSize; } else { view = convertView; @@ -633,20 +636,30 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte } private final void bindView(View view, DisplayResolveInfo info) { - TextView text = (TextView)view.findViewById(com.android.internal.R.id.text1); - TextView text2 = (TextView)view.findViewById(com.android.internal.R.id.text2); - ImageView icon = (ImageView)view.findViewById(R.id.icon); - text.setText(info.displayLabel); + final ViewHolder holder = (ViewHolder) view.getTag(); + holder.text.setText(info.displayLabel); if (mShowExtended) { - text2.setVisibility(View.VISIBLE); - text2.setText(info.extendedInfo); + holder.text2.setVisibility(View.VISIBLE); + holder.text2.setText(info.extendedInfo); } else { - text2.setVisibility(View.GONE); + holder.text2.setVisibility(View.GONE); } if (info.displayIcon == null) { - info.displayIcon = loadIconForResolveInfo(info.ri); + new LoadIconTask().execute(info); } - icon.setImageDrawable(info.displayIcon); + holder.icon.setImageDrawable(info.displayIcon); + } + } + + static class ViewHolder { + public TextView text; + public TextView text2; + public ImageView icon; + + public ViewHolder(View view) { + text = (TextView) view.findViewById(com.android.internal.R.id.text1); + text2 = (TextView) view.findViewById(com.android.internal.R.id.text2); + icon = (ImageView) view.findViewById(R.id.icon); } } @@ -660,5 +673,21 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte } } + + class LoadIconTask extends AsyncTask<DisplayResolveInfo, Void, DisplayResolveInfo> { + @Override + protected DisplayResolveInfo doInBackground(DisplayResolveInfo... params) { + final DisplayResolveInfo info = params[0]; + if (info.displayIcon == null) { + info.displayIcon = loadIconForResolveInfo(info.ri); + } + return info; + } + + @Override + protected void onPostExecute(DisplayResolveInfo info) { + mAdapter.notifyDataSetChanged(); + } + } } diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java index 424c19b..ab871fb 100644 --- a/core/java/com/android/internal/content/PackageMonitor.java +++ b/core/java/com/android/internal/content/PackageMonitor.java @@ -25,6 +25,7 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.UserHandle; +import com.android.internal.os.BackgroundThread; import java.util.HashSet; @@ -37,10 +38,6 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver { static final IntentFilter sNonDataFilt = new IntentFilter(); static final IntentFilter sExternalFilt = new IntentFilter(); - static final Object sLock = new Object(); - static HandlerThread sBackgroundThread; - static Handler sBackgroundHandler; - static { sPackageFilt.addAction(Intent.ACTION_PACKAGE_ADDED); sPackageFilt.addAction(Intent.ACTION_PACKAGE_REMOVED); @@ -79,15 +76,7 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver { } mRegisteredContext = context; if (thread == null) { - synchronized (sLock) { - if (sBackgroundThread == null) { - sBackgroundThread = new HandlerThread("PackageMonitor", - android.os.Process.THREAD_PRIORITY_BACKGROUND); - sBackgroundThread.start(); - sBackgroundHandler = new Handler(sBackgroundThread.getLooper()); - } - mRegisteredHandler = sBackgroundHandler; - } + mRegisteredHandler = BackgroundThread.getHandler(); } else { mRegisteredHandler = new Handler(thread); } diff --git a/core/java/com/android/internal/os/BackgroundThread.java b/core/java/com/android/internal/os/BackgroundThread.java new file mode 100644 index 0000000..d6f7b20 --- /dev/null +++ b/core/java/com/android/internal/os/BackgroundThread.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.os; + +import android.os.Handler; +import android.os.HandlerThread; + +/** + * Shared singleton background thread for each process. + */ +public final class BackgroundThread extends HandlerThread { + private static BackgroundThread sInstance; + private static Handler sHandler; + + private BackgroundThread() { + super("android.bg", android.os.Process.THREAD_PRIORITY_BACKGROUND); + } + + private static void ensureThreadLocked() { + if (sInstance == null) { + sInstance = new BackgroundThread(); + sInstance.start(); + sHandler = new Handler(sInstance.getLooper()); + } + } + + public static BackgroundThread get() { + synchronized (BackgroundThread.class) { + ensureThreadLocked(); + return sInstance; + } + } + + public static Handler getHandler() { + synchronized (BackgroundThread.class) { + ensureThreadLocked(); + return sHandler; + } + } +} diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index a2e8d49..38391df 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -83,7 +83,7 @@ public final class BatteryStatsImpl extends BatteryStats { private static final int MAGIC = 0xBA757475; // 'BATSTATS' // Current on-disk Parcel version - private static final int VERSION = 64 + (USE_OLD_HISTORY ? 1000 : 0); + private static final int VERSION = 65 + (USE_OLD_HISTORY ? 1000 : 0); // Maximum number of items we will record in the history. private static final int MAX_HISTORY_ITEMS = 2000; @@ -659,7 +659,7 @@ public final class BatteryStatsImpl extends BatteryStats { } public void logState(Printer pw, String prefix) { - pw.println(prefix + " mCount=" + mCount + pw.println(prefix + "mCount=" + mCount + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount + " mUnpluggedCount=" + mUnpluggedCount); pw.println(prefix + "mTotalTime=" + mTotalTime @@ -1044,7 +1044,7 @@ public final class BatteryStatsImpl extends BatteryStats { public void logState(Printer pw, String prefix) { super.logState(pw, prefix); - pw.println(prefix + "mNesting=" + mNesting + "mUpdateTime=" + mUpdateTime + pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime + " mAcquireTime=" + mAcquireTime); } @@ -2236,6 +2236,14 @@ public final class BatteryStatsImpl extends BatteryStats { getUidStatsLocked(uid).noteVideoTurnedOffLocked(); } + public void noteActivityResumedLocked(int uid) { + getUidStatsLocked(uid).noteActivityResumedLocked(); + } + + public void noteActivityPausedLocked(int uid) { + getUidStatsLocked(uid).noteActivityPausedLocked(); + } + public void noteVibratorOnLocked(int uid, long durationMillis) { getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis); } @@ -2537,6 +2545,8 @@ public final class BatteryStatsImpl extends BatteryStats { boolean mVideoTurnedOn; StopwatchTimer mVideoTurnedOnTimer; + StopwatchTimer mForegroundActivityTimer; + BatchTimer mVibratorOnTimer; Counter[] mUserActivityCounters; @@ -2772,6 +2782,27 @@ public final class BatteryStatsImpl extends BatteryStats { } } + public StopwatchTimer createForegroundActivityTimerLocked() { + if (mForegroundActivityTimer == null) { + mForegroundActivityTimer = new StopwatchTimer( + Uid.this, FOREGROUND_ACTIVITY, null, mUnpluggables); + } + return mForegroundActivityTimer; + } + + @Override + public void noteActivityResumedLocked() { + // We always start, since we want multiple foreground PIDs to nest + createForegroundActivityTimerLocked().startRunningLocked(BatteryStatsImpl.this); + } + + @Override + public void noteActivityPausedLocked() { + if (mForegroundActivityTimer != null) { + mForegroundActivityTimer.stopRunningLocked(BatteryStatsImpl.this); + } + } + public BatchTimer createVibratorOnTimerLocked() { if (mVibratorOnTimer == null) { mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, @@ -2840,6 +2871,11 @@ public final class BatteryStatsImpl extends BatteryStats { } @Override + public Timer getForegroundActivityTimer() { + return mForegroundActivityTimer; + } + + @Override public Timer getVibratorOnTimer() { return mVibratorOnTimer; } @@ -2915,6 +2951,9 @@ public final class BatteryStatsImpl extends BatteryStats { active |= !mVideoTurnedOnTimer.reset(BatteryStatsImpl.this, false); active |= mVideoTurnedOn; } + if (mForegroundActivityTimer != null) { + active |= !mForegroundActivityTimer.reset(BatteryStatsImpl.this, false); + } if (mVibratorOnTimer != null) { if (mVibratorOnTimer.reset(BatteryStatsImpl.this, false)) { mVibratorOnTimer.detach(); @@ -3014,6 +3053,10 @@ public final class BatteryStatsImpl extends BatteryStats { mVideoTurnedOnTimer.detach(); mVideoTurnedOnTimer = null; } + if (mForegroundActivityTimer != null) { + mForegroundActivityTimer.detach(); + mForegroundActivityTimer = null; + } if (mUserActivityCounters != null) { for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { mUserActivityCounters[i].detach(); @@ -3095,6 +3138,12 @@ public final class BatteryStatsImpl extends BatteryStats { } else { out.writeInt(0); } + if (mForegroundActivityTimer != null) { + out.writeInt(1); + mForegroundActivityTimer.writeToParcel(out, batteryRealtime); + } else { + out.writeInt(0); + } if (mVibratorOnTimer != null) { out.writeInt(1); mVibratorOnTimer.writeToParcel(out, batteryRealtime); @@ -3200,6 +3249,12 @@ public final class BatteryStatsImpl extends BatteryStats { mVideoTurnedOnTimer = null; } if (in.readInt() != 0) { + mForegroundActivityTimer = new StopwatchTimer( + Uid.this, FOREGROUND_ACTIVITY, null, mUnpluggables, in); + } else { + mForegroundActivityTimer = null; + } + if (in.readInt() != 0) { mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, mUnpluggables, BatteryStatsImpl.this.mOnBatteryInternal, in); } else { @@ -3368,14 +3423,14 @@ public final class BatteryStatsImpl extends BatteryStats { long mSystemTime; /** - * Number of times the process has been started. + * Amount of time the process was running in the foreground. */ - int mStarts; + long mForegroundTime; /** - * Amount of time the process was running in the foreground. + * Number of times the process has been started. */ - long mForegroundTime; + int mStarts; /** * The amount of user time loaded from a previous save. @@ -3388,14 +3443,14 @@ public final class BatteryStatsImpl extends BatteryStats { long mLoadedSystemTime; /** - * The number of times the process has started from a previous save. + * The amount of foreground time loaded from a previous save. */ - int mLoadedStarts; + long mLoadedForegroundTime; /** - * The amount of foreground time loaded from a previous save. + * The number of times the process has started from a previous save. */ - long mLoadedForegroundTime; + int mLoadedStarts; /** * The amount of user time loaded from the previous run. @@ -3408,14 +3463,14 @@ public final class BatteryStatsImpl extends BatteryStats { long mLastSystemTime; /** - * The number of times the process has started from the previous run. + * The amount of foreground time loaded from the previous run */ - int mLastStarts; + long mLastForegroundTime; /** - * The amount of foreground time loaded from the previous run + * The number of times the process has started from the previous run. */ - long mLastForegroundTime; + int mLastStarts; /** * The amount of user time when last unplugged. @@ -3428,14 +3483,14 @@ public final class BatteryStatsImpl extends BatteryStats { long mUnpluggedSystemTime; /** - * The number of times the process has started before unplugged. + * The amount of foreground time since unplugged. */ - int mUnpluggedStarts; + long mUnpluggedForegroundTime; /** - * The amount of foreground time since unplugged. + * The number of times the process has started before unplugged. */ - long mUnpluggedForegroundTime; + int mUnpluggedStarts; SamplingCounter[] mSpeedBins; @@ -3449,8 +3504,8 @@ public final class BatteryStatsImpl extends BatteryStats { public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) { mUnpluggedUserTime = mUserTime; mUnpluggedSystemTime = mSystemTime; - mUnpluggedStarts = mStarts; mUnpluggedForegroundTime = mForegroundTime; + mUnpluggedStarts = mStarts; } public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) { @@ -5357,6 +5412,9 @@ public final class BatteryStatsImpl extends BatteryStats { u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in); } if (in.readInt() != 0) { + u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in); + } + if (in.readInt() != 0) { u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in); } @@ -5410,6 +5468,7 @@ public final class BatteryStatsImpl extends BatteryStats { Uid.Proc p = u.getProcessStatsLocked(procName); p.mUserTime = p.mLoadedUserTime = in.readLong(); p.mSystemTime = p.mLoadedSystemTime = in.readLong(); + p.mForegroundTime = p.mLoadedForegroundTime = in.readLong(); p.mStarts = p.mLoadedStarts = in.readInt(); int NSB = in.readInt(); if (NSB > 100) { @@ -5559,6 +5618,12 @@ public final class BatteryStatsImpl extends BatteryStats { } else { out.writeInt(0); } + if (u.mForegroundActivityTimer != null) { + out.writeInt(1); + u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL); + } else { + out.writeInt(0); + } if (u.mVibratorOnTimer != null) { out.writeInt(1); u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); @@ -5628,6 +5693,7 @@ public final class BatteryStatsImpl extends BatteryStats { Uid.Proc ps = ent.getValue(); out.writeLong(ps.mUserTime); out.writeLong(ps.mSystemTime); + out.writeLong(ps.mForegroundTime); out.writeInt(ps.mStarts); final int N = ps.mSpeedBins.length; out.writeInt(N); @@ -5903,7 +5969,7 @@ public final class BatteryStatsImpl extends BatteryStats { updateKernelWakelocksLocked(); } - public void dumpLocked(PrintWriter pw) { + public void dumpLocked(PrintWriter pw, boolean isUnpluggedOnly) { if (DEBUG) { Printer pr = new PrintWriterPrinter(pw); pr.println("*** Screen timer:"); @@ -5935,7 +6001,7 @@ public final class BatteryStatsImpl extends BatteryStats { pr.println("*** Mobile ifaces:"); pr.println(mMobileIfaces.toString()); } - super.dumpLocked(pw); + super.dumpLocked(pw, isUnpluggedOnly); } private NetworkStats mNetworkSummaryCache; diff --git a/core/java/com/android/internal/os/ProcessStats.java b/core/java/com/android/internal/os/ProcessStats.java index b1bb8c1..bd0914d 100644 --- a/core/java/com/android/internal/os/ProcessStats.java +++ b/core/java/com/android/internal/os/ProcessStats.java @@ -518,6 +518,10 @@ public class ProcessStats { return pids; } + /** + * Returns the total time (in clock ticks, or 1/100 sec) spent executing in + * both user and system code. + */ public long getCpuTimeForPid(int pid) { final String statFile = "/proc/" + pid + "/stat"; final long[] statsData = mSinglePidStatsData; @@ -531,9 +535,9 @@ public class ProcessStats { } /** - * Returns the times spent at each CPU speed, since the last call to this method. If this - * is the first time, it will return 1 for each value. - * @return relative times spent at different speed steps. + * Returns the delta time (in clock ticks, or 1/100 sec) spent at each CPU + * speed, since the last call to this method. If this is the first call, it + * will return 1 for each value. */ public long[] getLastCpuSpeedTimes() { if (mCpuSpeedTimes == null) { diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index fb22df7..ccc0089 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -22,9 +22,11 @@ import static libcore.io.OsConstants.S_IRWXO; import android.content.res.Resources; import android.content.res.TypedArray; import android.net.LocalServerSocket; +import android.opengl.EGL14; import android.os.Debug; import android.os.Process; import android.os.SystemClock; +import android.os.SystemProperties; import android.os.Trace; import android.util.EventLog; import android.util.Log; @@ -59,9 +61,10 @@ import java.util.ArrayList; * @hide */ public class ZygoteInit { - private static final String TAG = "Zygote"; + private static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload"; + private static final String ANDROID_SOCKET_ENV = "ANDROID_SOCKET_zygote"; private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020; @@ -227,6 +230,13 @@ public class ZygoteInit { static void preload() { preloadClasses(); preloadResources(); + preloadOpenGL(); + } + + private static void preloadOpenGL() { + if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false)) { + EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); + } } /** @@ -479,7 +489,6 @@ public class ZygoteInit { OsConstants.CAP_NET_BIND_SERVICE, OsConstants.CAP_NET_BROADCAST, OsConstants.CAP_NET_RAW, - OsConstants.CAP_SYS_BOOT, OsConstants.CAP_SYS_MODULE, OsConstants.CAP_SYS_NICE, OsConstants.CAP_SYS_RESOURCE, diff --git a/core/java/com/android/internal/policy/IKeyguardExitCallback.aidl b/core/java/com/android/internal/policy/IKeyguardExitCallback.aidl new file mode 100644 index 0000000..3702712 --- /dev/null +++ b/core/java/com/android/internal/policy/IKeyguardExitCallback.aidl @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.policy; + +oneway interface IKeyguardExitCallback { + void onKeyguardExitResult(boolean success); +} diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl new file mode 100644 index 0000000..880464d --- /dev/null +++ b/core/java/com/android/internal/policy/IKeyguardService.aidl @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.policy; + +import com.android.internal.policy.IKeyguardShowCallback; +import com.android.internal.policy.IKeyguardExitCallback; + +import android.os.Bundle; + +interface IKeyguardService { + boolean isShowing(); + boolean isSecure(); + boolean isShowingAndNotHidden(); + boolean isInputRestricted(); + boolean isDismissable(); + oneway void verifyUnlock(IKeyguardExitCallback callback); + oneway void keyguardDone(boolean authenticated, boolean wakeup); + oneway void setHidden(boolean isHidden); + oneway void dismiss(); + oneway void onWakeKeyWhenKeyguardShowing(int keyCode); + oneway void onWakeMotionWhenKeyguardShowing(); + oneway void onDreamingStarted(); + oneway void onDreamingStopped(); + oneway void onScreenTurnedOff(int reason); + oneway void onScreenTurnedOn(IKeyguardShowCallback callback); + oneway void setKeyguardEnabled(boolean enabled); + oneway void onSystemReady(); + oneway void doKeyguardTimeout(in Bundle options); + oneway void setCurrentUser(int userId); + oneway void showAssistant(); +} diff --git a/core/java/com/android/internal/policy/IKeyguardShowCallback.aidl b/core/java/com/android/internal/policy/IKeyguardShowCallback.aidl new file mode 100644 index 0000000..a2784d9 --- /dev/null +++ b/core/java/com/android/internal/policy/IKeyguardShowCallback.aidl @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.policy; + +oneway interface IKeyguardShowCallback { + void onShown(IBinder windowToken); +} diff --git a/core/java/com/android/internal/util/IndentingPrintWriter.java b/core/java/com/android/internal/util/IndentingPrintWriter.java index d01a817..6fddd09 100644 --- a/core/java/com/android/internal/util/IndentingPrintWriter.java +++ b/core/java/com/android/internal/util/IndentingPrintWriter.java @@ -68,6 +68,10 @@ public class IndentingPrintWriter extends PrintWriter { print(key + "=" + String.valueOf(value) + " "); } + public void printHexPair(String key, int value) { + print(key + "=0x" + Integer.toHexString(value) + " "); + } + @Override public void write(char[] buf, int offset, int count) { final int indentLength = mIndentBuilder.length(); diff --git a/core/java/com/android/internal/view/RotationPolicy.java b/core/java/com/android/internal/view/RotationPolicy.java index 95130c8..70e2bfc 100644 --- a/core/java/com/android/internal/view/RotationPolicy.java +++ b/core/java/com/android/internal/view/RotationPolicy.java @@ -17,12 +17,13 @@ package com.android.internal.view; import android.content.Context; +import android.content.pm.PackageManager; import android.database.ContentObserver; import android.net.Uri; import android.os.AsyncTask; +import android.os.Build; import android.os.Handler; import android.os.RemoteException; -import android.os.ServiceManager; import android.os.UserHandle; import android.provider.Settings; import android.util.Log; @@ -40,6 +41,21 @@ public final class RotationPolicy { } /** + * Gets whether the device supports rotation. In general such a + * device has an accelerometer and has the portrait and landscape + * features. + * + * @param context Context for accessing system resources. + * @return Whether the device supports rotation. + */ + public static boolean isRotationSupported(Context context) { + PackageManager pm = context.getPackageManager(); + return pm.hasSystemFeature(PackageManager.FEATURE_SENSOR_ACCELEROMETER) + && pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_PORTRAIT) + && pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_LANDSCAPE); + } + + /** * Returns true if the device supports the rotation-lock toggle feature * in the system UI or system bar. * @@ -48,7 +64,8 @@ public final class RotationPolicy { * settings. */ public static boolean isRotationLockToggleSupported(Context context) { - return context.getResources().getConfiguration().smallestScreenWidthDp >= 600; + return isRotationSupported(context) + && context.getResources().getConfiguration().smallestScreenWidthDp >= 600; } /** diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java index dda1a10..f2bd522 100644 --- a/core/java/com/android/internal/widget/ActionBarView.java +++ b/core/java/com/android/internal/widget/ActionBarView.java @@ -16,24 +16,12 @@ package com.android.internal.widget; -import com.android.internal.R; -import com.android.internal.view.menu.ActionMenuItem; -import com.android.internal.view.menu.ActionMenuPresenter; -import com.android.internal.view.menu.ActionMenuView; -import com.android.internal.view.menu.MenuBuilder; -import com.android.internal.view.menu.MenuItemImpl; -import com.android.internal.view.menu.MenuPresenter; -import com.android.internal.view.menu.MenuView; -import com.android.internal.view.menu.SubMenuBuilder; - import android.animation.LayoutTransition; import android.app.ActionBar; import android.app.ActionBar.OnNavigationListener; -import android.app.Activity; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Configuration; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; @@ -42,7 +30,6 @@ import android.os.Parcelable; import android.text.Layout; import android.text.TextUtils; import android.util.AttributeSet; -import android.util.Log; import android.view.CollapsibleActionView; import android.view.Gravity; import android.view.LayoutInflater; @@ -62,6 +49,15 @@ import android.widget.ProgressBar; import android.widget.Spinner; import android.widget.SpinnerAdapter; import android.widget.TextView; +import com.android.internal.R; +import com.android.internal.view.menu.ActionMenuItem; +import com.android.internal.view.menu.ActionMenuPresenter; +import com.android.internal.view.menu.ActionMenuView; +import com.android.internal.view.menu.MenuBuilder; +import com.android.internal.view.menu.MenuItemImpl; +import com.android.internal.view.menu.MenuPresenter; +import com.android.internal.view.menu.MenuView; +import com.android.internal.view.menu.SubMenuBuilder; /** * @hide @@ -188,34 +184,8 @@ public class ActionBarView extends AbsActionBarView { ActionBar.NAVIGATION_MODE_STANDARD); mTitle = a.getText(R.styleable.ActionBar_title); mSubtitle = a.getText(R.styleable.ActionBar_subtitle); - mLogo = a.getDrawable(R.styleable.ActionBar_logo); - if (mLogo == null) { - if (context instanceof Activity) { - try { - mLogo = pm.getActivityLogo(((Activity) context).getComponentName()); - } catch (NameNotFoundException e) { - Log.e(TAG, "Activity component name not found!", e); - } - } - if (mLogo == null) { - mLogo = appInfo.loadLogo(pm); - } - } - mIcon = a.getDrawable(R.styleable.ActionBar_icon); - if (mIcon == null) { - if (context instanceof Activity) { - try { - mIcon = pm.getActivityIcon(((Activity) context).getComponentName()); - } catch (NameNotFoundException e) { - Log.e(TAG, "Activity component name not found!", e); - } - } - if (mIcon == null) { - mIcon = appInfo.loadIcon(pm); - } - } final LayoutInflater inflater = LayoutInflater.from(context); @@ -729,7 +699,11 @@ public class ActionBarView extends AbsActionBarView { } public void setIcon(int resId) { - setIcon(mContext.getResources().getDrawable(resId)); + setIcon(resId != 0 ? mContext.getResources().getDrawable(resId) : null); + } + + public boolean hasIcon() { + return mIcon != null; } public void setLogo(Drawable logo) { @@ -740,7 +714,11 @@ public class ActionBarView extends AbsActionBarView { } public void setLogo(int resId) { - setLogo(mContext.getResources().getDrawable(resId)); + setLogo(resId != 0 ? mContext.getResources().getDrawable(resId) : null); + } + + public boolean hasLogo() { + return mLogo != null; } public void setNavigationMode(int mode) { diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index d3ead26..521ba81 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -16,6 +16,7 @@ package com.android.internal.widget; +import android.Manifest; import android.app.ActivityManagerNative; import android.app.admin.DevicePolicyManager; import android.appwidget.AppWidgetManager; @@ -149,6 +150,8 @@ public class LockPatternUtils { private DevicePolicyManager mDevicePolicyManager; private ILockSettings mLockSettingsService; + private final boolean mMultiUserMode; + // The current user is set by KeyguardViewMediator and shared by all LockPatternUtils. private static volatile int sCurrentUserId = UserHandle.USER_NULL; @@ -170,6 +173,12 @@ public class LockPatternUtils { public LockPatternUtils(Context context) { mContext = context; mContentResolver = context.getContentResolver(); + + // If this is being called by the system or by an application like keyguard that + // has permision INTERACT_ACROSS_USERS, then LockPatternUtils will operate in multi-user + // mode where calls are for the current user rather than the user of the calling process. + mMultiUserMode = context.checkCallingOrSelfPermission( + Manifest.permission.INTERACT_ACROSS_USERS_FULL) == PackageManager.PERMISSION_GRANTED; } private ILockSettings getLockSettings() { @@ -264,13 +273,12 @@ public class LockPatternUtils { } private int getCurrentOrCallingUserId() { - int callingUid = Binder.getCallingUid(); - if (callingUid == android.os.Process.SYSTEM_UID) { + if (mMultiUserMode) { // TODO: This is a little inefficient. See if all users of this are able to // handle USER_CURRENT and pass that instead. return getCurrentUser(); } else { - return UserHandle.getUserId(callingUid); + return UserHandle.getCallingUserId(); } } diff --git a/core/java/com/android/internal/widget/TransportControlView.java b/core/java/com/android/internal/widget/TransportControlView.java deleted file mode 100644 index ca797eb..0000000 --- a/core/java/com/android/internal/widget/TransportControlView.java +++ /dev/null @@ -1,515 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.widget; - -import java.lang.ref.WeakReference; - -import com.android.internal.widget.LockScreenWidgetCallback; -import com.android.internal.widget.LockScreenWidgetInterface; - -import android.app.PendingIntent; -import android.app.PendingIntent.CanceledException; -import android.content.Context; -import android.content.Intent; -import android.graphics.Bitmap; -import android.media.AudioManager; -import android.media.MediaMetadataRetriever; -import android.media.RemoteControlClient; -import android.media.IRemoteControlDisplay; -import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.RemoteException; -import android.os.SystemClock; -import android.text.Spannable; -import android.text.TextUtils; -import android.text.style.ForegroundColorSpan; -import android.util.AttributeSet; -import android.util.Log; -import android.view.KeyEvent; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.TextView; - - -import com.android.internal.R; - -public class TransportControlView extends FrameLayout implements OnClickListener, - LockScreenWidgetInterface { - - private static final int MSG_UPDATE_STATE = 100; - private static final int MSG_SET_METADATA = 101; - private static final int MSG_SET_TRANSPORT_CONTROLS = 102; - private static final int MSG_SET_ARTWORK = 103; - private static final int MSG_SET_GENERATION_ID = 104; - private static final int MAXDIM = 512; - private static final int DISPLAY_TIMEOUT_MS = 5000; // 5s - protected static final boolean DEBUG = false; - protected static final String TAG = "TransportControlView"; - - private ImageView mAlbumArt; - private TextView mTrackTitle; - private ImageView mBtnPrev; - private ImageView mBtnPlay; - private ImageView mBtnNext; - private int mClientGeneration; - private Metadata mMetadata = new Metadata(); - private boolean mAttached; - private PendingIntent mClientIntent; - private int mTransportControlFlags; - private int mCurrentPlayState; - private AudioManager mAudioManager; - private LockScreenWidgetCallback mWidgetCallbacks; - private IRemoteControlDisplayWeak mIRCD; - - /** - * The metadata which should be populated into the view once we've been attached - */ - private Bundle mPopulateMetadataWhenAttached = null; - - // This handler is required to ensure messages from IRCD are handled in sequence and on - // the UI thread. - private Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_UPDATE_STATE: - if (mClientGeneration == msg.arg1) updatePlayPauseState(msg.arg2); - break; - - case MSG_SET_METADATA: - if (mClientGeneration == msg.arg1) updateMetadata((Bundle) msg.obj); - break; - - case MSG_SET_TRANSPORT_CONTROLS: - if (mClientGeneration == msg.arg1) updateTransportControls(msg.arg2); - break; - - case MSG_SET_ARTWORK: - if (mClientGeneration == msg.arg1) { - if (mMetadata.bitmap != null) { - mMetadata.bitmap.recycle(); - } - mMetadata.bitmap = (Bitmap) msg.obj; - mAlbumArt.setImageBitmap(mMetadata.bitmap); - } - break; - - case MSG_SET_GENERATION_ID: - if (msg.arg2 != 0) { - // This means nobody is currently registered. Hide the view. - if (mWidgetCallbacks != null) { - mWidgetCallbacks.requestHide(TransportControlView.this); - } - } - if (DEBUG) Log.v(TAG, "New genId = " + msg.arg1 + ", clearing = " + msg.arg2); - mClientGeneration = msg.arg1; - mClientIntent = (PendingIntent) msg.obj; - break; - - } - } - }; - - /** - * This class is required to have weak linkage to the current TransportControlView - * because the remote process can hold a strong reference to this binder object and - * we can't predict when it will be GC'd in the remote process. Without this code, it - * would allow a heavyweight object to be held on this side of the binder when there's - * no requirement to run a GC on the other side. - */ - private static class IRemoteControlDisplayWeak extends IRemoteControlDisplay.Stub { - private WeakReference<Handler> mLocalHandler; - - IRemoteControlDisplayWeak(Handler handler) { - mLocalHandler = new WeakReference<Handler>(handler); - } - - public void setPlaybackState(int generationId, int state, long stateChangeTimeMs, - long currentPosMs, float speed) { - Handler handler = mLocalHandler.get(); - if (handler != null) { - handler.obtainMessage(MSG_UPDATE_STATE, generationId, state).sendToTarget(); - } - } - - public void setMetadata(int generationId, Bundle metadata) { - Handler handler = mLocalHandler.get(); - if (handler != null) { - handler.obtainMessage(MSG_SET_METADATA, generationId, 0, metadata).sendToTarget(); - } - } - - public void setTransportControlInfo(int generationId, int flags, int posCapabilities) { - Handler handler = mLocalHandler.get(); - if (handler != null) { - handler.obtainMessage(MSG_SET_TRANSPORT_CONTROLS, generationId, flags) - .sendToTarget(); - } - } - - public void setArtwork(int generationId, Bitmap bitmap) { - Handler handler = mLocalHandler.get(); - if (handler != null) { - handler.obtainMessage(MSG_SET_ARTWORK, generationId, 0, bitmap).sendToTarget(); - } - } - - public void setAllMetadata(int generationId, Bundle metadata, Bitmap bitmap) { - Handler handler = mLocalHandler.get(); - if (handler != null) { - handler.obtainMessage(MSG_SET_METADATA, generationId, 0, metadata).sendToTarget(); - handler.obtainMessage(MSG_SET_ARTWORK, generationId, 0, bitmap).sendToTarget(); - } - } - - public void setCurrentClientId(int clientGeneration, PendingIntent mediaIntent, - boolean clearing) throws RemoteException { - Handler handler = mLocalHandler.get(); - if (handler != null) { - handler.obtainMessage(MSG_SET_GENERATION_ID, - clientGeneration, (clearing ? 1 : 0), mediaIntent).sendToTarget(); - } - } - }; - - public TransportControlView(Context context, AttributeSet attrs) { - super(context, attrs); - if (DEBUG) Log.v(TAG, "Create TCV " + this); - mAudioManager = new AudioManager(mContext); - mCurrentPlayState = RemoteControlClient.PLAYSTATE_NONE; // until we get a callback - mIRCD = new IRemoteControlDisplayWeak(mHandler); - } - - private void updateTransportControls(int transportControlFlags) { - mTransportControlFlags = transportControlFlags; - } - - @Override - public void onFinishInflate() { - super.onFinishInflate(); - mTrackTitle = (TextView) findViewById(R.id.title); - mTrackTitle.setSelected(true); // enable marquee - mAlbumArt = (ImageView) findViewById(R.id.albumart); - mBtnPrev = (ImageView) findViewById(R.id.btn_prev); - mBtnPlay = (ImageView) findViewById(R.id.btn_play); - mBtnNext = (ImageView) findViewById(R.id.btn_next); - final View buttons[] = { mBtnPrev, mBtnPlay, mBtnNext }; - for (View view : buttons) { - view.setOnClickListener(this); - } - } - - @Override - public void onAttachedToWindow() { - super.onAttachedToWindow(); - if (mPopulateMetadataWhenAttached != null) { - updateMetadata(mPopulateMetadataWhenAttached); - mPopulateMetadataWhenAttached = null; - } - if (!mAttached) { - if (DEBUG) Log.v(TAG, "Registering TCV " + this); - mAudioManager.registerRemoteControlDisplay(mIRCD); - } - mAttached = true; - } - - @Override - public void onDetachedFromWindow() { - super.onDetachedFromWindow(); - if (mAttached) { - if (DEBUG) Log.v(TAG, "Unregistering TCV " + this); - mAudioManager.unregisterRemoteControlDisplay(mIRCD); - } - mAttached = false; - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - int dim = Math.min(MAXDIM, Math.max(getWidth(), getHeight())); -// Log.v(TAG, "setting max bitmap size: " + dim + "x" + dim); -// mAudioManager.remoteControlDisplayUsesBitmapSize(mIRCD, dim, dim); - } - - class Metadata { - private String artist; - private String trackTitle; - private String albumTitle; - private Bitmap bitmap; - - public String toString() { - return "Metadata[artist=" + artist + " trackTitle=" + trackTitle + " albumTitle=" + albumTitle + "]"; - } - } - - private String getMdString(Bundle data, int id) { - return data.getString(Integer.toString(id)); - } - - private void updateMetadata(Bundle data) { - if (mAttached) { - mMetadata.artist = getMdString(data, MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST); - mMetadata.trackTitle = getMdString(data, MediaMetadataRetriever.METADATA_KEY_TITLE); - mMetadata.albumTitle = getMdString(data, MediaMetadataRetriever.METADATA_KEY_ALBUM); - populateMetadata(); - } else { - mPopulateMetadataWhenAttached = data; - } - } - - /** - * Populates the given metadata into the view - */ - private void populateMetadata() { - StringBuilder sb = new StringBuilder(); - int trackTitleLength = 0; - if (!TextUtils.isEmpty(mMetadata.trackTitle)) { - sb.append(mMetadata.trackTitle); - trackTitleLength = mMetadata.trackTitle.length(); - } - if (!TextUtils.isEmpty(mMetadata.artist)) { - if (sb.length() != 0) { - sb.append(" - "); - } - sb.append(mMetadata.artist); - } - if (!TextUtils.isEmpty(mMetadata.albumTitle)) { - if (sb.length() != 0) { - sb.append(" - "); - } - sb.append(mMetadata.albumTitle); - } - mTrackTitle.setText(sb.toString(), TextView.BufferType.SPANNABLE); - Spannable str = (Spannable) mTrackTitle.getText(); - if (trackTitleLength != 0) { - str.setSpan(new ForegroundColorSpan(0xffffffff), 0, trackTitleLength, - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - trackTitleLength++; - } - if (sb.length() > trackTitleLength) { - str.setSpan(new ForegroundColorSpan(0x7fffffff), trackTitleLength, sb.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - } - - mAlbumArt.setImageBitmap(mMetadata.bitmap); - final int flags = mTransportControlFlags; - setVisibilityBasedOnFlag(mBtnPrev, flags, RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS); - setVisibilityBasedOnFlag(mBtnNext, flags, RemoteControlClient.FLAG_KEY_MEDIA_NEXT); - setVisibilityBasedOnFlag(mBtnPlay, flags, - RemoteControlClient.FLAG_KEY_MEDIA_PLAY - | RemoteControlClient.FLAG_KEY_MEDIA_PAUSE - | RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE - | RemoteControlClient.FLAG_KEY_MEDIA_STOP); - - updatePlayPauseState(mCurrentPlayState); - } - - private static void setVisibilityBasedOnFlag(View view, int flags, int flag) { - if ((flags & flag) != 0) { - view.setVisibility(View.VISIBLE); - } else { - view.setVisibility(View.GONE); - } - } - - private void updatePlayPauseState(int state) { - if (DEBUG) Log.v(TAG, - "updatePlayPauseState(), old=" + mCurrentPlayState + ", state=" + state); - if (state == mCurrentPlayState) { - return; - } - final int imageResId; - final int imageDescId; - boolean showIfHidden = false; - switch (state) { - case RemoteControlClient.PLAYSTATE_ERROR: - imageResId = com.android.internal.R.drawable.stat_sys_warning; - // TODO use more specific image description string for warning, but here the "play" - // message is still valid because this button triggers a play command. - imageDescId = com.android.internal.R.string.lockscreen_transport_play_description; - break; - - case RemoteControlClient.PLAYSTATE_PLAYING: - imageResId = com.android.internal.R.drawable.ic_media_pause; - imageDescId = com.android.internal.R.string.lockscreen_transport_pause_description; - showIfHidden = true; - break; - - case RemoteControlClient.PLAYSTATE_BUFFERING: - imageResId = com.android.internal.R.drawable.ic_media_stop; - imageDescId = com.android.internal.R.string.lockscreen_transport_stop_description; - showIfHidden = true; - break; - - case RemoteControlClient.PLAYSTATE_PAUSED: - default: - imageResId = com.android.internal.R.drawable.ic_media_play; - imageDescId = com.android.internal.R.string.lockscreen_transport_play_description; - showIfHidden = false; - break; - } - mBtnPlay.setImageResource(imageResId); - mBtnPlay.setContentDescription(getResources().getString(imageDescId)); - if (showIfHidden && mWidgetCallbacks != null && !mWidgetCallbacks.isVisible(this)) { - mWidgetCallbacks.requestShow(this); - } - mCurrentPlayState = state; - } - - static class SavedState extends BaseSavedState { - boolean wasShowing; - - SavedState(Parcelable superState) { - super(superState); - } - - private SavedState(Parcel in) { - super(in); - this.wasShowing = in.readInt() != 0; - } - - @Override - public void writeToParcel(Parcel out, int flags) { - super.writeToParcel(out, flags); - out.writeInt(this.wasShowing ? 1 : 0); - } - - public static final Parcelable.Creator<SavedState> CREATOR - = new Parcelable.Creator<SavedState>() { - public SavedState createFromParcel(Parcel in) { - return new SavedState(in); - } - - public SavedState[] newArray(int size) { - return new SavedState[size]; - } - }; - } - - @Override - public Parcelable onSaveInstanceState() { - if (DEBUG) Log.v(TAG, "onSaveInstanceState()"); - Parcelable superState = super.onSaveInstanceState(); - SavedState ss = new SavedState(superState); - ss.wasShowing = mWidgetCallbacks != null && mWidgetCallbacks.isVisible(this); - return ss; - } - - @Override - public void onRestoreInstanceState(Parcelable state) { - if (DEBUG) Log.v(TAG, "onRestoreInstanceState()"); - if (!(state instanceof SavedState)) { - super.onRestoreInstanceState(state); - return; - } - SavedState ss = (SavedState) state; - super.onRestoreInstanceState(ss.getSuperState()); - if (ss.wasShowing && mWidgetCallbacks != null) { - mWidgetCallbacks.requestShow(this); - } - } - - public void onClick(View v) { - int keyCode = -1; - if (v == mBtnPrev) { - keyCode = KeyEvent.KEYCODE_MEDIA_PREVIOUS; - } else if (v == mBtnNext) { - keyCode = KeyEvent.KEYCODE_MEDIA_NEXT; - } else if (v == mBtnPlay) { - keyCode = KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE; - - } - if (keyCode != -1) { - sendMediaButtonClick(keyCode); - if (mWidgetCallbacks != null) { - mWidgetCallbacks.userActivity(this); - } - } - } - - private void sendMediaButtonClick(int keyCode) { - if (mClientIntent == null) { - // Shouldn't be possible because this view should be hidden in this case. - Log.e(TAG, "sendMediaButtonClick(): No client is currently registered"); - return; - } - // use the registered PendingIntent that will be processed by the registered - // media button event receiver, which is the component of mClientIntent - KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode); - Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON); - intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent); - try { - mClientIntent.send(getContext(), 0, intent); - } catch (CanceledException e) { - Log.e(TAG, "Error sending intent for media button down: "+e); - e.printStackTrace(); - } - - keyEvent = new KeyEvent(KeyEvent.ACTION_UP, keyCode); - intent = new Intent(Intent.ACTION_MEDIA_BUTTON); - intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent); - try { - mClientIntent.send(getContext(), 0, intent); - } catch (CanceledException e) { - Log.e(TAG, "Error sending intent for media button up: "+e); - e.printStackTrace(); - } - } - - public void setCallback(LockScreenWidgetCallback callback) { - mWidgetCallbacks = callback; - } - - public boolean providesClock() { - return false; - } - - private boolean wasPlayingRecently(int state, long stateChangeTimeMs) { - switch (state) { - case RemoteControlClient.PLAYSTATE_PLAYING: - case RemoteControlClient.PLAYSTATE_FAST_FORWARDING: - case RemoteControlClient.PLAYSTATE_REWINDING: - case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS: - case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS: - case RemoteControlClient.PLAYSTATE_BUFFERING: - // actively playing or about to play - return true; - case RemoteControlClient.PLAYSTATE_NONE: - return false; - case RemoteControlClient.PLAYSTATE_STOPPED: - case RemoteControlClient.PLAYSTATE_PAUSED: - case RemoteControlClient.PLAYSTATE_ERROR: - // we have stopped playing, check how long ago - if (DEBUG) { - if ((SystemClock.elapsedRealtime() - stateChangeTimeMs) < DISPLAY_TIMEOUT_MS) { - Log.v(TAG, "wasPlayingRecently: time < TIMEOUT was playing recently"); - } else { - Log.v(TAG, "wasPlayingRecently: time > TIMEOUT"); - } - } - return ((SystemClock.elapsedRealtime() - stateChangeTimeMs) < DISPLAY_TIMEOUT_MS); - default: - Log.e(TAG, "Unknown playback state " + state + " in wasPlayingRecently()"); - return false; - } - } -} diff --git a/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java b/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java index 30f5f2f..16bec16 100644 --- a/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java +++ b/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java @@ -46,36 +46,6 @@ public class TargetDrawable { private boolean mEnabled = true; private final int mResourceId; - /* package */ static class DrawableWithAlpha extends Drawable { - private float mAlpha = 1.0f; - private Drawable mRealDrawable; - public DrawableWithAlpha(Drawable realDrawable) { - mRealDrawable = realDrawable; - } - public void setAlpha(float alpha) { - mAlpha = alpha; - } - public float getAlpha() { - return mAlpha; - } - public void draw(Canvas canvas) { - mRealDrawable.setAlpha((int) Math.round(mAlpha * 255f)); - mRealDrawable.draw(canvas); - } - @Override - public void setAlpha(int alpha) { - mRealDrawable.setAlpha(alpha); - } - @Override - public void setColorFilter(ColorFilter cf) { - mRealDrawable.setColorFilter(cf); - } - @Override - public int getOpacity() { - return mRealDrawable.getOpacity(); - } - } - public TargetDrawable(Resources res, int resId) { mResourceId = resId; setDrawable(res, resId); diff --git a/core/jni/Android.mk b/core/jni/Android.mk index 337c1ec..188941b 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -17,6 +17,10 @@ endif LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES +# When built as part of the system image we can enable certian non-NDK compliant +# Skia optimizations. +LOCAL_CFLAGS += -DSK_BUILD_FOR_ANDROID_FRAMEWORK + LOCAL_SRC_FILES:= \ AndroidRuntime.cpp \ Time.cpp \ @@ -51,6 +55,7 @@ LOCAL_SRC_FILES:= \ android_view_KeyEvent.cpp \ android_view_KeyCharacterMap.cpp \ android_view_HardwareRenderer.cpp \ + android_view_GraphicBuffer.cpp \ android_view_GLES20DisplayList.cpp \ android_view_GLES20Canvas.cpp \ android_view_MotionEvent.cpp \ @@ -158,10 +163,6 @@ LOCAL_C_INCLUDES += \ $(call include-path-for, libhardware)/hardware \ $(call include-path-for, libhardware_legacy)/hardware_legacy \ $(TOP)/frameworks/av/include \ - external/skia/include/core \ - external/skia/include/effects \ - external/skia/include/images \ - external/skia/include/ports \ external/skia/src/core \ external/skia/src/images \ external/skia/include/utils \ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index ca658da..bfa2e06 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -24,7 +24,6 @@ #include <utils/Log.h> #include <utils/misc.h> #include <binder/Parcel.h> -#include <utils/StringArray.h> #include <utils/threads.h> #include <cutils/properties.h> @@ -117,6 +116,7 @@ extern int register_android_graphics_SurfaceTexture(JNIEnv* env); extern int register_android_graphics_Xfermode(JNIEnv* env); extern int register_android_graphics_PixelFormat(JNIEnv* env); extern int register_android_view_DisplayEventReceiver(JNIEnv* env); +extern int register_android_view_GraphicBuffer(JNIEnv* env); extern int register_android_view_GLES20DisplayList(JNIEnv* env); extern int register_android_view_GLES20Canvas(JNIEnv* env); extern int register_android_view_HardwareRenderer(JNIEnv* env); @@ -1112,6 +1112,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_nio_utils), REG_JNI(register_android_graphics_PixelFormat), REG_JNI(register_android_graphics_Graphics), + REG_JNI(register_android_view_GraphicBuffer), REG_JNI(register_android_view_GLES20DisplayList), REG_JNI(register_android_view_GLES20Canvas), REG_JNI(register_android_view_HardwareRenderer), diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp index daabce3..d6549a1 100644 --- a/core/jni/android/graphics/BitmapFactory.cpp +++ b/core/jni/android/graphics/BitmapFactory.cpp @@ -211,19 +211,17 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding, SkBitmap* bitmap; bool useExistingBitmap = false; + unsigned int existingBufferSize = 0; if (javaBitmap == NULL) { bitmap = new SkBitmap; } else { - if (sampleSize != 1) { - return nullObjectReturn("SkImageDecoder: Cannot reuse bitmap with sampleSize != 1"); - } - bitmap = (SkBitmap*) env->GetIntField(javaBitmap, gBitmap_nativeBitmapFieldID); - // only reuse the provided bitmap if it is immutable + // only reuse the provided bitmap if it is mutable if (!bitmap->isImmutable()) { useExistingBitmap = true; // config of supplied bitmap overrules config set in options prefConfig = bitmap->getConfig(); + existingBufferSize = GraphicsJNI::getBitmapAllocationByteCount(env, javaBitmap); } else { ALOGW("Unable to reuse an immutable bitmap as an image decoder target."); bitmap = new SkBitmap; @@ -252,6 +250,26 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding, decodeMode = SkImageDecoder::kDecodeBounds_Mode; } + if (javaBitmap != NULL) { + // If we're reusing the pixelref from an existing bitmap, decode the bounds and + // reinitialize the native object for the new content, keeping the pixelRef + SkPixelRef* pixelRef = bitmap->pixelRef(); + SkSafeRef(pixelRef); + + SkBitmap boundsBitmap; + decoder->decode(stream, &boundsBitmap, prefConfig, SkImageDecoder::kDecodeBounds_Mode); + stream->rewind(); + + if (boundsBitmap.getSize() > existingBufferSize) { + return nullObjectReturn("bitmap marked for reuse too small to contain decoded data"); + } + + bitmap->setConfig(boundsBitmap.config(), boundsBitmap.width(), boundsBitmap.height(), 0); + bitmap->setPixelRef(pixelRef); + SkSafeUnref(pixelRef); + GraphicsJNI::reinitBitmap(env, javaBitmap); + } + SkBitmap* decoded; if (willScale) { decoded = new SkBitmap; diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp index d4c7600..7c420ad 100644 --- a/core/jni/android/graphics/Graphics.cpp +++ b/core/jni/android/graphics/Graphics.cpp @@ -152,6 +152,8 @@ static jfieldID gPointF_yFieldID; static jclass gBitmap_class; static jfieldID gBitmap_nativeInstanceID; static jmethodID gBitmap_constructorMethodID; +static jmethodID gBitmap_reinitMethodID; +static jmethodID gBitmap_getAllocationByteCountMethodID; static jclass gBitmapConfig_class; static jfieldID gBitmapConfig_nativeInstanceID; @@ -363,6 +365,15 @@ jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, bool isMutable, return createBitmap(env, bitmap, NULL, isMutable, ninepatch, NULL, density); } +void GraphicsJNI::reinitBitmap(JNIEnv* env, jobject javaBitmap) +{ + env->CallVoidMethod(javaBitmap, gBitmap_reinitMethodID); +} + +int GraphicsJNI::getBitmapAllocationByteCount(JNIEnv* env, jobject javaBitmap) +{ + return env->CallIntMethod(javaBitmap, gBitmap_getAllocationByteCountMethodID); +} jobject GraphicsJNI::createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap) { @@ -398,7 +409,7 @@ static JNIEnv* vm2env(JavaVM* vm) /////////////////////////////////////////////////////////////////////////////// AndroidPixelRef::AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj, - SkColorTable* ctable) : SkMallocPixelRef(storage, size, ctable) { + SkColorTable* ctable) : SkMallocPixelRef(storage, size, ctable, (storageObj == NULL)) { SkASSERT(storage); SkASSERT(env); @@ -423,10 +434,6 @@ AndroidPixelRef::~AndroidPixelRef() { env->DeleteGlobalRef(fStorageObj); } fStorageObj = NULL; - - // Set this to NULL to prevent the SkMallocPixelRef destructor - // from freeing the memory. - fStorage = NULL; } } @@ -588,6 +595,8 @@ int register_android_graphics_Graphics(JNIEnv* env) gBitmap_nativeInstanceID = getFieldIDCheck(env, gBitmap_class, "mNativeBitmap", "I"); gBitmap_constructorMethodID = env->GetMethodID(gBitmap_class, "<init>", "(I[BZ[B[II)V"); + gBitmap_reinitMethodID = env->GetMethodID(gBitmap_class, "reinit", "()V"); + gBitmap_getAllocationByteCountMethodID = env->GetMethodID(gBitmap_class, "getAllocationByteCount", "()I"); gBitmapRegionDecoder_class = make_globalref(env, "android/graphics/BitmapRegionDecoder"); gBitmapRegionDecoder_constructorMethodID = env->GetMethodID(gBitmapRegionDecoder_class, "<init>", "(I)V"); diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h index c5b06f5..69b67cb 100644 --- a/core/jni/android/graphics/GraphicsJNI.h +++ b/core/jni/android/graphics/GraphicsJNI.h @@ -59,6 +59,10 @@ public: static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, bool isMutable, jbyteArray ninepatch, int density = -1); + static void reinitBitmap(JNIEnv* env, jobject javaBitmap); + + static int getBitmapAllocationByteCount(JNIEnv* env, jobject javaBitmap); + static jobject createRegion(JNIEnv* env, SkRegion* region); static jobject createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap); diff --git a/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp b/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp index ce31c5b..a75efcf 100644 --- a/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp +++ b/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp @@ -138,16 +138,15 @@ static hb_font_funcs_t* harfbuzzSkiaGetFontFuncs() hb_blob_t* harfbuzzSkiaReferenceTable(hb_face_t* face, hb_tag_t tag, void* userData) { SkTypeface* typeface = reinterpret_cast<SkTypeface*>(userData); - SkFontID uniqueID = typeface->uniqueID(); - const size_t tableSize = SkFontHost::GetTableSize(uniqueID, tag); + const size_t tableSize = typeface->getTableSize(tag); if (!tableSize) return 0; char* buffer = reinterpret_cast<char*>(malloc(tableSize)); if (!buffer) return 0; - size_t actualSize = SkFontHost::GetTableData(uniqueID, tag, 0, tableSize, buffer); + size_t actualSize = typeface->getTableData(tag, 0, tableSize, buffer); if (tableSize != actualSize) { free(buffer); return 0; diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp index 5454c08..380f061 100644 --- a/core/jni/android/graphics/Paint.cpp +++ b/core/jni/android/graphics/Paint.cpp @@ -58,6 +58,10 @@ static JMetricsID gFontMetricsInt_fieldID; static void defaultSettingsForAndroid(SkPaint* paint) { // GlyphID encoding is required because we are using Harfbuzz shaping paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding); + + SkPaintOptionsAndroid paintOpts = paint->getPaintOptionsAndroid(); + paintOpts.setUseFontFallbacks(true); + paint->setPaintOptionsAndroid(paintOpts); } class SkPaintGlue { @@ -300,7 +304,10 @@ public: ScopedUtfChars localeChars(env, locale); char langTag[ULOC_FULLNAME_CAPACITY]; toLanguageTag(langTag, ULOC_FULLNAME_CAPACITY, localeChars.c_str()); - obj->setLanguage(SkLanguage(langTag)); + + SkPaintOptionsAndroid paintOpts = obj->getPaintOptionsAndroid(); + paintOpts.setLanguage(langTag); + obj->setPaintOptionsAndroid(paintOpts); } static jfloat getTextSize(JNIEnv* env, jobject paint) { diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp index b2cf9c1..73f3639 100644 --- a/core/jni/android/graphics/TextLayoutCache.cpp +++ b/core/jni/android/graphics/TextLayoutCache.cpp @@ -20,7 +20,6 @@ #include "TextLayoutCache.h" #include "TextLayout.h" -#include "SkFontHost.h" #include "SkTypeface_android.h" #include "HarfBuzzNGFaceSkia.h" #include <unicode/unistr.h> @@ -219,7 +218,8 @@ void TextLayoutCache::dumpCacheStats() { */ TextLayoutCacheKey::TextLayoutCacheKey(): start(0), count(0), contextCount(0), dirFlags(0), typeface(NULL), textSize(0), textSkewX(0), textScaleX(0), flags(0), - hinting(SkPaint::kNo_Hinting), variant(SkPaint::kDefault_Variant), language() { + hinting(SkPaint::kNo_Hinting) { + paintOpts.setUseFontFallbacks(true); } TextLayoutCacheKey::TextLayoutCacheKey(const SkPaint* paint, const UChar* text, @@ -233,8 +233,7 @@ TextLayoutCacheKey::TextLayoutCacheKey(const SkPaint* paint, const UChar* text, textScaleX = paint->getTextScaleX(); flags = paint->getFlags(); hinting = paint->getHinting(); - variant = paint->getFontVariant(); - language = paint->getLanguage(); + paintOpts = paint->getPaintOptionsAndroid(); } TextLayoutCacheKey::TextLayoutCacheKey(const TextLayoutCacheKey& other) : @@ -249,8 +248,7 @@ TextLayoutCacheKey::TextLayoutCacheKey(const TextLayoutCacheKey& other) : textScaleX(other.textScaleX), flags(other.flags), hinting(other.hinting), - variant(other.variant), - language(other.language) { + paintOpts(other.paintOpts) { } int TextLayoutCacheKey::compare(const TextLayoutCacheKey& lhs, const TextLayoutCacheKey& rhs) { @@ -284,11 +282,8 @@ int TextLayoutCacheKey::compare(const TextLayoutCacheKey& lhs, const TextLayoutC deltaInt = lhs.dirFlags - rhs.dirFlags; if (deltaInt) return (deltaInt); - deltaInt = lhs.variant - rhs.variant; - if (deltaInt) return (deltaInt); - - if (lhs.language < rhs.language) return -1; - if (lhs.language > rhs.language) return +1; + if (lhs.paintOpts != rhs.paintOpts) + return memcmp(&lhs.paintOpts, &rhs.paintOpts, sizeof(SkPaintOptionsAndroid)); return memcmp(lhs.getText(), rhs.getText(), lhs.contextCount * sizeof(UChar)); } @@ -307,7 +302,7 @@ hash_t TextLayoutCacheKey::hash() const { hash = JenkinsHashMix(hash, hash_type(textScaleX)); hash = JenkinsHashMix(hash, flags); hash = JenkinsHashMix(hash, hinting); - hash = JenkinsHashMix(hash, variant); + hash = JenkinsHashMix(hash, paintOpts.getFontVariant()); // Note: leaving out language is not problematic, as equality comparisons // are still valid - the only bad thing that could happen is collisions. hash = JenkinsHashMixShorts(hash, getText(), contextCount); @@ -319,6 +314,7 @@ hash_t TextLayoutCacheKey::hash() const { */ TextLayoutValue::TextLayoutValue(size_t contextCount) : mTotalAdvance(0), mElapsedTime(0) { + mBounds.setEmpty(); // Give a hint for advances and glyphs vectors size mAdvances.setCapacity(contextCount); mGlyphs.setCapacity(contextCount); @@ -346,11 +342,11 @@ TextLayoutShaper::~TextLayoutShaper() { hb_buffer_destroy(mBuffer); } -void TextLayoutShaper::computeValues(TextLayoutValue* value, const SkPaint* paint, const UChar* chars, - size_t start, size_t count, size_t contextCount, int dirFlags) { - +void TextLayoutShaper::computeValues(TextLayoutValue* value, const SkPaint* paint, + const UChar* chars, size_t start, size_t count, size_t contextCount, int dirFlags) { computeValues(paint, chars, start, count, contextCount, dirFlags, - &value->mAdvances, &value->mTotalAdvance, &value->mGlyphs, &value->mPos); + &value->mAdvances, &value->mTotalAdvance, &value->mBounds, + &value->mGlyphs, &value->mPos); #if DEBUG_ADVANCES ALOGD("Advances - start = %d, count = %d, contextCount = %d, totalAdvance = %f", start, count, contextCount, value->mTotalAdvance); @@ -359,7 +355,7 @@ void TextLayoutShaper::computeValues(TextLayoutValue* value, const SkPaint* pain void TextLayoutShaper::computeValues(const SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount, int dirFlags, - Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, + Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, SkRect* outBounds, Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos) { *outTotalAdvance = 0; if (!count) { @@ -455,7 +451,7 @@ void TextLayoutShaper::computeValues(const SkPaint* paint, const UChar* chars, i, startRun, lengthRun, isRTL); #endif computeRunValues(paint, chars, startRun, lengthRun, contextCount, isRTL, - outAdvances, outTotalAdvance, outGlyphs, outPos); + outAdvances, outTotalAdvance, outBounds, outGlyphs, outPos); } } @@ -479,7 +475,7 @@ void TextLayoutShaper::computeValues(const SkPaint* paint, const UChar* chars, "-- run-start = %d, run-len = %d, isRTL = %d", start, count, isRTL); #endif computeRunValues(paint, chars, start, count, contextCount, isRTL, - outAdvances, outTotalAdvance, outGlyphs, outPos); + outAdvances, outTotalAdvance, outBounds, outGlyphs, outPos); } #if DEBUG_GLYPHS @@ -676,7 +672,7 @@ static void logGlyphs(hb_buffer_t* buffer) { void TextLayoutShaper::computeRunValues(const SkPaint* paint, const UChar* contextChars, size_t start, size_t count, size_t contextCount, bool isRTL, - Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, + Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, SkRect* outBounds, Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos) { if (!count) { // We cannot shape an empty run. @@ -698,8 +694,7 @@ void TextLayoutShaper::computeRunValues(const SkPaint* paint, const UChar* conte mShapingPaint.setTextScaleX(paint->getTextScaleX()); mShapingPaint.setFlags(paint->getFlags()); mShapingPaint.setHinting(paint->getHinting()); - mShapingPaint.setFontVariant(paint->getFontVariant()); - mShapingPaint.setLanguage(paint->getLanguage()); + mShapingPaint.setPaintOptionsAndroid(paint->getPaintOptionsAndroid()); // Split the BiDi run into Script runs. Harfbuzz will populate the pos, length and script // into the shaperItem @@ -750,12 +745,22 @@ void TextLayoutShaper::computeRunValues(const SkPaint* paint, const UChar* conte size_t cluster = info[i].cluster - start; float xAdvance = HBFixedToFloat(positions[i].x_advance); outAdvances->replaceAt(outAdvances->itemAt(cluster) + xAdvance, cluster); - outGlyphs->add(info[i].codepoint + glyphBaseCount); + jchar glyphId = info[i].codepoint + glyphBaseCount; + outGlyphs->add(glyphId); float xo = HBFixedToFloat(positions[i].x_offset); float yo = -HBFixedToFloat(positions[i].y_offset); - outPos->add(totalAdvance + xo + yo * skewX); - outPos->add(yo); + + float xpos = totalAdvance + xo + yo * skewX; + float ypos = yo; + outPos->add(xpos); + outPos->add(ypos); totalAdvance += xAdvance; + + // TODO: consider using glyph cache + const SkGlyph& metrics = mShapingPaint.getGlyphMetrics(glyphId, NULL); + outBounds->join(xpos + metrics.fLeft, ypos + metrics.fTop, + xpos + metrics.fLeft + metrics.fWidth, ypos + metrics.fTop + metrics.fHeight); + } } @@ -839,7 +844,7 @@ size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint) { if (typeface) { SkSafeRef(typeface); } else { - typeface = SkFontHost::CreateTypeface(NULL, NULL, SkTypeface::kNormal); + typeface = SkTypeface::CreateFromName(NULL, SkTypeface::kNormal); #if DEBUG_GLYPHS ALOGD("Using Default Typeface (normal style)"); #endif diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h index 5414a11..54704ec 100644 --- a/core/jni/android/graphics/TextLayoutCache.h +++ b/core/jni/android/graphics/TextLayoutCache.h @@ -28,7 +28,6 @@ #include <utils/Singleton.h> #include <SkAutoKern.h> -#include <SkLanguage.h> #include <SkPaint.h> #include <SkTemplates.h> #include <SkTypeface.h> @@ -104,8 +103,7 @@ private: SkScalar textScaleX; uint32_t flags; SkPaint::Hinting hinting; - SkPaint::FontVariant variant; - SkLanguage language; + SkPaintOptionsAndroid paintOpts; }; // TextLayoutCacheKey @@ -134,6 +132,7 @@ public: inline const jfloat* getAdvances() const { return mAdvances.array(); } inline size_t getAdvancesCount() const { return mAdvances.size(); } inline jfloat getTotalAdvance() const { return mTotalAdvance; } + inline const SkRect& getBounds() const { return mBounds; } inline const jchar* getGlyphs() const { return mGlyphs.array(); } inline size_t getGlyphsCount() const { return mGlyphs.size(); } inline const jfloat* getPos() const { return mPos.array(); } @@ -150,6 +149,11 @@ public: jfloat mTotalAdvance; /** + * Bounds containing all glyphs + */ + SkRect mBounds; + + /** * Glyphs vector */ Vector<jchar> mGlyphs; @@ -208,12 +212,12 @@ private: void computeValues(const SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount, int dirFlags, - Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, + Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, SkRect* outBounds, Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos); void computeRunValues(const SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount, bool isRTL, - Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, + Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, SkRect* outBounds, Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos); SkTypeface* setCachedTypeface(SkTypeface** typeface, hb_script_t script, SkTypeface::Style style); diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp index 686e4e3..dec4cd4 100644 --- a/core/jni/android_hardware_Camera.cpp +++ b/core/jni/android_hardware_Camera.cpp @@ -586,6 +586,30 @@ static void android_hardware_Camera_setPreviewTexture(JNIEnv *env, } } +static void android_hardware_Camera_setPreviewCallbackSurface(JNIEnv *env, + jobject thiz, jobject jSurface) +{ + ALOGV("setPreviewCallbackSurface"); + JNICameraContext* context; + sp<Camera> camera = get_native_camera(env, thiz, &context); + if (camera == 0) return; + + sp<IGraphicBufferProducer> gbp; + sp<Surface> surface; + if (jSurface) { + surface = android_view_Surface_getSurface(env, jSurface); + if (surface != NULL) { + gbp = surface->getIGraphicBufferProducer(); + } + } + // Clear out normal preview callbacks + context->setCallbackMode(env, false, false); + // Then set up callback surface + if (camera->setPreviewCallbackTarget(gbp) != NO_ERROR) { + jniThrowException(env, "java/io/IOException", "setPreviewCallbackTarget failed"); + } +} + static void android_hardware_Camera_startPreview(JNIEnv *env, jobject thiz) { ALOGV("startPreview"); @@ -881,6 +905,9 @@ static JNINativeMethod camMethods[] = { { "setPreviewTexture", "(Landroid/graphics/SurfaceTexture;)V", (void *)android_hardware_Camera_setPreviewTexture }, + { "setPreviewCallbackSurface", + "(Landroid/view/Surface;)V", + (void *)android_hardware_Camera_setPreviewCallbackSurface }, { "startPreview", "()V", (void *)android_hardware_Camera_startPreview }, diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp index 9537ac4..08962e2 100644 --- a/core/jni/android_net_wifi_Wifi.cpp +++ b/core/jni/android_net_wifi_Wifi.cpp @@ -33,11 +33,11 @@ namespace android { static jint DBG = false; -static int doCommand(const char *ifname, const char *cmd, char *replybuf, int replybuflen) +static int doCommand(const char *ifname, char *cmd, char *replybuf, int replybuflen) { size_t reply_len = replybuflen - 1; - if (::wifi_command(ifname, cmd, replybuf, &reply_len) != 0) + if (::wifi_command(ifname, cmd, BUF_SIZE, replybuf, &reply_len) != 0) return -1; else { // Strip off trailing newline diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp index 664af07..48babb3 100644 --- a/core/jni/android_opengl_EGL14.cpp +++ b/core/jni/android_opengl_EGL14.cpp @@ -136,7 +136,7 @@ android_eglGetError (JNIEnv *_env, jobject _this) { EGLint _returnValue = (EGLint) 0; _returnValue = eglGetError(); - return _returnValue; + return (jint)_returnValue; } /* EGLDisplay eglGetDisplay ( EGLNativeDisplayType display_id ) */ @@ -230,7 +230,7 @@ exit: if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); } - return _returnValue; + return (jboolean)_returnValue; } /* EGLBoolean eglTerminate ( EGLDisplay dpy ) */ @@ -243,7 +243,7 @@ android_eglTerminate _returnValue = eglTerminate( (EGLDisplay)dpy_native ); - return _returnValue; + return (jboolean)_returnValue; } /* const char * eglQueryString ( EGLDisplay dpy, EGLint name ) */ @@ -331,7 +331,7 @@ exit: if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); } - return _returnValue; + return (jboolean)_returnValue; } /* EGLBoolean eglChooseConfig ( EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config ) */ @@ -454,7 +454,7 @@ exit: if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); } - return _returnValue; + return (jboolean)_returnValue; } /* EGLBoolean eglGetConfigAttrib ( EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value ) */ @@ -509,7 +509,7 @@ exit: if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); } - return _returnValue; + return (jboolean)_returnValue; } /* EGLSurface eglCreateWindowSurface ( EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list ) */ @@ -753,7 +753,7 @@ android_eglDestroySurface (EGLDisplay)dpy_native, (EGLSurface)surface_native ); - return _returnValue; + return (jboolean)_returnValue; } /* EGLBoolean eglQuerySurface ( EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value ) */ @@ -808,7 +808,7 @@ exit: if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); } - return _returnValue; + return (jboolean)_returnValue; } /* EGLBoolean eglBindAPI ( EGLenum api ) */ @@ -819,7 +819,7 @@ android_eglBindAPI _returnValue = eglBindAPI( (EGLenum)api ); - return _returnValue; + return (jboolean)_returnValue; } /* EGLenum eglQueryAPI ( void ) */ @@ -828,7 +828,7 @@ android_eglQueryAPI (JNIEnv *_env, jobject _this) { EGLenum _returnValue = (EGLenum) 0; _returnValue = eglQueryAPI(); - return _returnValue; + return (jint)_returnValue; } /* EGLBoolean eglWaitClient ( void ) */ @@ -837,7 +837,7 @@ android_eglWaitClient (JNIEnv *_env, jobject _this) { EGLBoolean _returnValue = (EGLBoolean) 0; _returnValue = eglWaitClient(); - return _returnValue; + return (jboolean)_returnValue; } /* EGLBoolean eglReleaseThread ( void ) */ @@ -846,7 +846,7 @@ android_eglReleaseThread (JNIEnv *_env, jobject _this) { EGLBoolean _returnValue = (EGLBoolean) 0; _returnValue = eglReleaseThread(); - return _returnValue; + return (jboolean)_returnValue; } /* EGLSurface eglCreatePbufferFromClientBuffer ( EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list ) */ @@ -927,7 +927,7 @@ android_eglSurfaceAttrib (EGLint)attribute, (EGLint)value ); - return _returnValue; + return (jboolean)_returnValue; } /* EGLBoolean eglBindTexImage ( EGLDisplay dpy, EGLSurface surface, EGLint buffer ) */ @@ -943,7 +943,7 @@ android_eglBindTexImage (EGLSurface)surface_native, (EGLint)buffer ); - return _returnValue; + return (jboolean)_returnValue; } /* EGLBoolean eglReleaseTexImage ( EGLDisplay dpy, EGLSurface surface, EGLint buffer ) */ @@ -959,7 +959,7 @@ android_eglReleaseTexImage (EGLSurface)surface_native, (EGLint)buffer ); - return _returnValue; + return (jboolean)_returnValue; } /* EGLBoolean eglSwapInterval ( EGLDisplay dpy, EGLint interval ) */ @@ -973,7 +973,7 @@ android_eglSwapInterval (EGLDisplay)dpy_native, (EGLint)interval ); - return _returnValue; + return (jboolean)_returnValue; } /* EGLContext eglCreateContext ( EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list ) */ @@ -1052,7 +1052,7 @@ android_eglDestroyContext (EGLDisplay)dpy_native, (EGLContext)ctx_native ); - return _returnValue; + return (jboolean)_returnValue; } /* EGLBoolean eglMakeCurrent ( EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx ) */ @@ -1071,7 +1071,7 @@ android_eglMakeCurrent (EGLSurface)read_native, (EGLContext)ctx_native ); - return _returnValue; + return (jboolean)_returnValue; } /* EGLContext eglGetCurrentContext ( void ) */ @@ -1155,7 +1155,7 @@ exit: if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); } - return _returnValue; + return (jboolean)_returnValue; } /* EGLBoolean eglWaitGL ( void ) */ @@ -1164,7 +1164,7 @@ android_eglWaitGL (JNIEnv *_env, jobject _this) { EGLBoolean _returnValue = (EGLBoolean) 0; _returnValue = eglWaitGL(); - return _returnValue; + return (jboolean)_returnValue; } /* EGLBoolean eglWaitNative ( EGLint engine ) */ @@ -1175,7 +1175,7 @@ android_eglWaitNative _returnValue = eglWaitNative( (EGLint)engine ); - return _returnValue; + return (jboolean)_returnValue; } /* EGLBoolean eglSwapBuffers ( EGLDisplay dpy, EGLSurface surface ) */ @@ -1190,7 +1190,7 @@ android_eglSwapBuffers (EGLDisplay)dpy_native, (EGLSurface)surface_native ); - return _returnValue; + return (jboolean)_returnValue; } /* EGLBoolean eglCopyBuffers ( EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target ) */ diff --git a/core/jni/android_opengl_GLES10.cpp b/core/jni/android_opengl_GLES10.cpp index 336c0ec..cc34e99 100644 --- a/core/jni/android_opengl_GLES10.cpp +++ b/core/jni/android_opengl_GLES10.cpp @@ -63,6 +63,12 @@ static void glVertexAttribPointerBounds(GLuint indx, GLint size, GLenum type, glVertexAttribPointer(indx, size, type, normalized, stride, pointer); } #endif +#ifdef GL_ES_VERSION_3_0 +static void glVertexAttribIPointerBounds(GLuint indx, GLint size, GLenum type, + GLsizei stride, const GLvoid *pointer, GLsizei count) { + glVertexAttribIPointer(indx, size, type, stride, pointer); +} +#endif } /* Cache method IDs each time the class is loaded. */ @@ -288,6 +294,7 @@ getarray int _needed = 0; params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset); + _remaining /= sizeof(CTYPE); // convert from bytes to item count _needed = getNeededCount(pname); // if we didn't find this pname, we just assume the user passed // an array of the right size -- this might happen with extensions @@ -1184,7 +1191,7 @@ android_glGetError__ (JNIEnv *_env, jobject _this) { GLenum _returnValue; _returnValue = glGetError(); - return _returnValue; + return (jint)_returnValue; } /* void glGetIntegerv ( GLenum pname, GLint *params ) */ diff --git a/core/jni/android_opengl_GLES10Ext.cpp b/core/jni/android_opengl_GLES10Ext.cpp index 59e63e1..9284384 100644 --- a/core/jni/android_opengl_GLES10Ext.cpp +++ b/core/jni/android_opengl_GLES10Ext.cpp @@ -63,6 +63,12 @@ static void glVertexAttribPointerBounds(GLuint indx, GLint size, GLenum type, glVertexAttribPointer(indx, size, type, normalized, stride, pointer); } #endif +#ifdef GL_ES_VERSION_3_0 +static void glVertexAttribIPointerBounds(GLuint indx, GLint size, GLenum type, + GLsizei stride, const GLvoid *pointer, GLsizei count) { + glVertexAttribIPointer(indx, size, type, stride, pointer); +} +#endif } /* Cache method IDs each time the class is loaded. */ @@ -288,6 +294,7 @@ getarray int _needed = 0; params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset); + _remaining /= sizeof(CTYPE); // convert from bytes to item count _needed = getNeededCount(pname); // if we didn't find this pname, we just assume the user passed // an array of the right size -- this might happen with extensions @@ -395,7 +402,7 @@ exit: if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); } - return _returnValue; + return (jint)_returnValue; } /* GLbitfield glQueryMatrixxOES ( GLfixed *mantissa, GLint *exponent ) */ @@ -452,7 +459,7 @@ exit: if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); } - return _returnValue; + return (jint)_returnValue; } static const char *classPathName = "android/opengl/GLES10Ext"; diff --git a/core/jni/android_opengl_GLES11.cpp b/core/jni/android_opengl_GLES11.cpp index 352f5bf..871e84d 100644 --- a/core/jni/android_opengl_GLES11.cpp +++ b/core/jni/android_opengl_GLES11.cpp @@ -63,6 +63,12 @@ static void glVertexAttribPointerBounds(GLuint indx, GLint size, GLenum type, glVertexAttribPointer(indx, size, type, normalized, stride, pointer); } #endif +#ifdef GL_ES_VERSION_3_0 +static void glVertexAttribIPointerBounds(GLuint indx, GLint size, GLenum type, + GLsizei stride, const GLvoid *pointer, GLsizei count) { + glVertexAttribIPointer(indx, size, type, stride, pointer); +} +#endif } /* Cache method IDs each time the class is loaded. */ @@ -288,6 +294,7 @@ getarray int _needed = 0; params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset); + _remaining /= sizeof(CTYPE); // convert from bytes to item count _needed = getNeededCount(pname); // if we didn't find this pname, we just assume the user passed // an array of the right size -- this might happen with extensions @@ -571,7 +578,7 @@ android_glColorPointer__IIII (GLint)size, (GLenum)type, (GLsizei)stride, - (const GLvoid *)offset + (GLvoid *)offset ); } @@ -672,7 +679,7 @@ android_glDrawElements__IIII (GLenum)mode, (GLsizei)count, (GLenum)type, - (const GLvoid *)offset + (GLvoid *)offset ); if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); @@ -2263,7 +2270,7 @@ android_glIsBuffer__I _returnValue = glIsBuffer( (GLuint)buffer ); - return _returnValue; + return (jboolean)_returnValue; } /* GLboolean glIsEnabled ( GLenum cap ) */ @@ -2274,7 +2281,7 @@ android_glIsEnabled__I _returnValue = glIsEnabled( (GLenum)cap ); - return _returnValue; + return (jboolean)_returnValue; } /* GLboolean glIsTexture ( GLuint texture ) */ @@ -2285,7 +2292,7 @@ android_glIsTexture__I _returnValue = glIsTexture( (GLuint)texture ); - return _returnValue; + return (jboolean)_returnValue; } /* void glNormalPointer ( GLenum type, GLsizei stride, GLint offset ) */ @@ -2295,7 +2302,7 @@ android_glNormalPointer__III glNormalPointer( (GLenum)type, (GLsizei)stride, - (const GLvoid *)offset + (GLvoid *)offset ); } @@ -2522,7 +2529,7 @@ android_glTexCoordPointer__IIII (GLint)size, (GLenum)type, (GLsizei)stride, - (const GLvoid *)offset + (GLvoid *)offset ); } @@ -2930,7 +2937,7 @@ android_glVertexPointer__IIII (GLint)size, (GLenum)type, (GLsizei)stride, - (const GLvoid *)offset + (GLvoid *)offset ); } diff --git a/core/jni/android_opengl_GLES11Ext.cpp b/core/jni/android_opengl_GLES11Ext.cpp index c91baa2..3e038ad 100644 --- a/core/jni/android_opengl_GLES11Ext.cpp +++ b/core/jni/android_opengl_GLES11Ext.cpp @@ -63,6 +63,12 @@ static void glVertexAttribPointerBounds(GLuint indx, GLint size, GLenum type, glVertexAttribPointer(indx, size, type, normalized, stride, pointer); } #endif +#ifdef GL_ES_VERSION_3_0 +static void glVertexAttribIPointerBounds(GLuint indx, GLint size, GLenum type, + GLsizei stride, const GLvoid *pointer, GLsizei count) { + glVertexAttribIPointer(indx, size, type, stride, pointer); +} +#endif } /* Cache method IDs each time the class is loaded. */ @@ -288,6 +294,7 @@ getarray int _needed = 0; params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset); + _remaining /= sizeof(CTYPE); // convert from bytes to item count _needed = getNeededCount(pname); // if we didn't find this pname, we just assume the user passed // an array of the right size -- this might happen with extensions @@ -2129,7 +2136,7 @@ android_glIsRenderbufferOES__I _returnValue = glIsRenderbufferOES( (GLuint)renderbuffer ); - return _returnValue; + return (jboolean)_returnValue; } /* void glBindRenderbufferOES ( GLenum target, GLuint renderbuffer ) */ @@ -2422,7 +2429,7 @@ android_glIsFramebufferOES__I _returnValue = glIsFramebufferOES( (GLuint)framebuffer ); - return _returnValue; + return (jboolean)_returnValue; } /* void glBindFramebufferOES ( GLenum target, GLuint framebuffer ) */ @@ -2615,7 +2622,7 @@ android_glCheckFramebufferStatusOES__I _returnValue = glCheckFramebufferStatusOES( (GLenum)target ); - return _returnValue; + return (jint)_returnValue; } /* void glFramebufferRenderbufferOES ( GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer ) */ diff --git a/core/jni/android_opengl_GLES20.cpp b/core/jni/android_opengl_GLES20.cpp index 4179785..9bc69ae 100644 --- a/core/jni/android_opengl_GLES20.cpp +++ b/core/jni/android_opengl_GLES20.cpp @@ -63,6 +63,12 @@ static void glVertexAttribPointerBounds(GLuint indx, GLint size, GLenum type, glVertexAttribPointer(indx, size, type, normalized, stride, pointer); } #endif +#ifdef GL_ES_VERSION_3_0 +static void glVertexAttribIPointerBounds(GLuint indx, GLint size, GLenum type, + GLsizei stride, const GLvoid *pointer, GLsizei count) { + glVertexAttribIPointer(indx, size, type, stride, pointer); +} +#endif } /* Cache method IDs each time the class is loaded. */ @@ -288,6 +294,7 @@ getarray int _needed = 0; params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset); + _remaining /= sizeof(CTYPE); // convert from bytes to item count _needed = getNeededCount(pname); // if we didn't find this pname, we just assume the user passed // an array of the right size -- this might happen with extensions @@ -549,7 +556,7 @@ android_glCheckFramebufferStatus__I _returnValue = glCheckFramebufferStatus( (GLenum)target ); - return _returnValue; + return (jint)_returnValue; } /* void glClear ( GLbitfield mask ) */ @@ -709,7 +716,7 @@ android_glCreateProgram__ (JNIEnv *_env, jobject _this) { GLuint _returnValue; _returnValue = glCreateProgram(); - return _returnValue; + return (jint)_returnValue; } /* GLuint glCreateShader ( GLenum type ) */ @@ -720,7 +727,7 @@ android_glCreateShader__I _returnValue = glCreateShader( (GLenum)type ); - return _returnValue; + return (jint)_returnValue; } /* void glCullFace ( GLenum mode ) */ @@ -1172,7 +1179,7 @@ android_glDrawElements__IIII (GLenum)mode, (GLsizei)count, (GLenum)type, - (const GLvoid *)offset + (GLvoid *)offset ); if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); @@ -2466,7 +2473,7 @@ exit: if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); } - return _returnValue; + return (jint)_returnValue; } /* void glGetBooleanv ( GLenum pname, GLboolean *params ) */ @@ -2576,7 +2583,7 @@ android_glGetError__ (JNIEnv *_env, jobject _this) { GLenum _returnValue; _returnValue = glGetError(); - return _returnValue; + return (jint)_returnValue; } /* void glGetFloatv ( GLenum pname, GLfloat *params ) */ @@ -3614,7 +3621,7 @@ exit: if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); } - return _returnValue; + return (jint)_returnValue; } /* void glGetVertexAttribfv ( GLuint index, GLenum pname, GLfloat *params ) */ @@ -3855,7 +3862,7 @@ android_glIsBuffer__I _returnValue = glIsBuffer( (GLuint)buffer ); - return _returnValue; + return (jboolean)_returnValue; } /* GLboolean glIsEnabled ( GLenum cap ) */ @@ -3866,7 +3873,7 @@ android_glIsEnabled__I _returnValue = glIsEnabled( (GLenum)cap ); - return _returnValue; + return (jboolean)_returnValue; } /* GLboolean glIsFramebuffer ( GLuint framebuffer ) */ @@ -3877,7 +3884,7 @@ android_glIsFramebuffer__I _returnValue = glIsFramebuffer( (GLuint)framebuffer ); - return _returnValue; + return (jboolean)_returnValue; } /* GLboolean glIsProgram ( GLuint program ) */ @@ -3888,7 +3895,7 @@ android_glIsProgram__I _returnValue = glIsProgram( (GLuint)program ); - return _returnValue; + return (jboolean)_returnValue; } /* GLboolean glIsRenderbuffer ( GLuint renderbuffer ) */ @@ -3899,7 +3906,7 @@ android_glIsRenderbuffer__I _returnValue = glIsRenderbuffer( (GLuint)renderbuffer ); - return _returnValue; + return (jboolean)_returnValue; } /* GLboolean glIsShader ( GLuint shader ) */ @@ -3910,7 +3917,7 @@ android_glIsShader__I _returnValue = glIsShader( (GLuint)shader ); - return _returnValue; + return (jboolean)_returnValue; } /* GLboolean glIsTexture ( GLuint texture ) */ @@ -3921,7 +3928,7 @@ android_glIsTexture__I _returnValue = glIsTexture( (GLuint)texture ); - return _returnValue; + return (jboolean)_returnValue; } /* void glLineWidth ( GLfloat width ) */ @@ -5975,7 +5982,7 @@ android_glVertexAttribPointer__IIIZII (GLenum)type, (GLboolean)normalized, (GLsizei)stride, - (const GLvoid *)offset + (GLvoid *)offset ); } diff --git a/core/jni/android_opengl_GLES30.cpp b/core/jni/android_opengl_GLES30.cpp index 3c50aa0..832d643 100644 --- a/core/jni/android_opengl_GLES30.cpp +++ b/core/jni/android_opengl_GLES30.cpp @@ -294,6 +294,7 @@ getarray int _needed = 0; params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset); + _remaining /= sizeof(CTYPE); // convert from bytes to item count _needed = getNeededCount(pname); // if we didn't find this pname, we just assume the user passed // an array of the right size -- this might happen with extensions diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp index 2883c10..f4cf2ee 100644 --- a/core/jni/android_os_Debug.cpp +++ b/core/jni/android_os_Debug.cpp @@ -43,6 +43,7 @@ enum { HEAP_UNKNOWN, HEAP_DALVIK, HEAP_NATIVE, + HEAP_DALVIK_OTHER, HEAP_STACK, HEAP_CURSOR, HEAP_ASHMEM, @@ -52,38 +53,56 @@ enum { HEAP_APK, HEAP_TTF, HEAP_DEX, + HEAP_OAT, + HEAP_ART, HEAP_UNKNOWN_MAP, + HEAP_DALVIK_NORMAL, + HEAP_DALVIK_LARGE, + HEAP_DALVIK_LINEARALLOC, + HEAP_DALVIK_ACCOUNTING, + HEAP_DALVIK_CODE_CACHE, + _NUM_HEAP, + _NUM_EXCLUSIVE_HEAP = HEAP_UNKNOWN_MAP+1, _NUM_CORE_HEAP = HEAP_NATIVE+1 }; struct stat_fields { jfieldID pss_field; + jfieldID pssSwappable_field; jfieldID privateDirty_field; jfieldID sharedDirty_field; + jfieldID privateClean_field; + jfieldID sharedClean_field; }; struct stat_field_names { const char* pss_name; + const char* pssSwappable_name; const char* privateDirty_name; const char* sharedDirty_name; + const char* privateClean_name; + const char* sharedClean_name; }; static stat_fields stat_fields[_NUM_CORE_HEAP]; static stat_field_names stat_field_names[_NUM_CORE_HEAP] = { - { "otherPss", "otherPrivateDirty", "otherSharedDirty" }, - { "dalvikPss", "dalvikPrivateDirty", "dalvikSharedDirty" }, - { "nativePss", "nativePrivateDirty", "nativeSharedDirty" } + { "otherPss", "otherSwappablePss", "otherPrivateDirty", "otherSharedDirty", "otherPrivateClean", "otherSharedClean" }, + { "dalvikPss", "dalvikSwappablePss", "dalvikPrivateDirty", "dalvikSharedDirty", "dalvikPrivateClean", "dalvikSharedClean" }, + { "nativePss", "nativeSwappablePss", "nativePrivateDirty", "nativeSharedDirty", "nativePrivateClean", "nativeSharedClean" } }; jfieldID otherStats_field; struct stats_t { int pss; + int swappablePss; int privateDirty; int sharedDirty; + int privateClean; + int sharedClean; }; #define BINDER_STATS "/proc/binder/stats" @@ -124,9 +143,11 @@ static void read_mapinfo(FILE *fp, stats_t* stats) int len, nameLen; bool skip, done = false; - unsigned size = 0, resident = 0, pss = 0; + unsigned size = 0, resident = 0, pss = 0, swappable_pss = 0; + float sharing_proportion = 0.0; unsigned shared_clean = 0, shared_dirty = 0; unsigned private_clean = 0, private_dirty = 0; + bool is_swappable = false; unsigned referenced = 0; unsigned temp; @@ -137,6 +158,7 @@ static void read_mapinfo(FILE *fp, stats_t* stats) int name_pos; int whichHeap = HEAP_UNKNOWN; + int subHeap = HEAP_UNKNOWN; int prevHeap = HEAP_UNKNOWN; if(fgets(line, sizeof(line), fp) == 0) return; @@ -145,7 +167,9 @@ static void read_mapinfo(FILE *fp, stats_t* stats) prevHeap = whichHeap; prevEnd = end; whichHeap = HEAP_UNKNOWN; + subHeap = HEAP_UNKNOWN; skip = false; + is_swappable = false; len = strlen(line); if (len < 1) return; @@ -160,30 +184,68 @@ static void read_mapinfo(FILE *fp, stats_t* stats) name = line + name_pos; nameLen = strlen(name); - if ((strstr(name, "[heap]") == name) || - (strstr(name, "/dev/ashmem/libc malloc") == name)) { + if ((strstr(name, "[heap]") == name)) { whichHeap = HEAP_NATIVE; - } else if (strstr(name, "/dev/ashmem/dalvik-") == name) { - whichHeap = HEAP_DALVIK; - } else if (strstr(name, "[stack") == name) { + } else if (strncmp(name, "/dev/ashmem", 11) == 0) { + if (strncmp(name, "/dev/ashmem/dalvik-", 19) == 0) { + whichHeap = HEAP_DALVIK_OTHER; + if (strstr(name, "/dev/ashmem/dalvik-LinearAlloc") == name) { + subHeap = HEAP_DALVIK_LINEARALLOC; + } else if ((strstr(name, "/dev/ashmem/dalvik-mark") == name) || + (strstr(name, "/dev/ashmem/dalvik-allocspace alloc space live-bitmap") == name) || + (strstr(name, "/dev/ashmem/dalvik-allocspace alloc space mark-bitmap") == name) || + (strstr(name, "/dev/ashmem/dalvik-card table") == name) || + (strstr(name, "/dev/ashmem/dalvik-allocation stack") == name) || + (strstr(name, "/dev/ashmem/dalvik-live stack") == name) || + (strstr(name, "/dev/ashmem/dalvik-imagespace") == name) || + (strstr(name, "/dev/ashmem/dalvik-bitmap") == name) || + (strstr(name, "/dev/ashmem/dalvik-card-table") == name) || + (strstr(name, "/dev/ashmem/dalvik-mark-stack") == name) || + (strstr(name, "/dev/ashmem/dalvik-aux-structure") == name)) { + subHeap = HEAP_DALVIK_ACCOUNTING; + } else if (strstr(name, "/dev/ashmem/dalvik-large") == name) { + whichHeap = HEAP_DALVIK; + subHeap = HEAP_DALVIK_LARGE; + } else if (strstr(name, "/dev/ashmem/dalvik-jit-code-cache") == name) { + subHeap = HEAP_DALVIK_CODE_CACHE; + } else { + // This is the regular Dalvik heap. + whichHeap = HEAP_DALVIK; + subHeap = HEAP_DALVIK_NORMAL; + } + } else if (strncmp(name, "/dev/ashmem/CursorWindow", 24) == 0) { + whichHeap = HEAP_CURSOR; + } else if (strncmp(name, "/dev/ashmem/libc malloc", 23) == 0) { + whichHeap = HEAP_NATIVE; + } else { + whichHeap = HEAP_ASHMEM; + } + } else if (strncmp(name, "[stack", 6) == 0) { whichHeap = HEAP_STACK; - } else if (strstr(name, "/dev/ashmem/CursorWindow") == name) { - whichHeap = HEAP_CURSOR; - } else if (strstr(name, "/dev/ashmem/") == name) { - whichHeap = HEAP_ASHMEM; - } else if (strstr(name, "/dev/") == name) { + } else if (strncmp(name, "/dev/", 5) == 0) { whichHeap = HEAP_UNKNOWN_DEV; } else if (nameLen > 3 && strcmp(name+nameLen-3, ".so") == 0) { whichHeap = HEAP_SO; + is_swappable = true; } else if (nameLen > 4 && strcmp(name+nameLen-4, ".jar") == 0) { whichHeap = HEAP_JAR; + is_swappable = true; } else if (nameLen > 4 && strcmp(name+nameLen-4, ".apk") == 0) { whichHeap = HEAP_APK; + is_swappable = true; } else if (nameLen > 4 && strcmp(name+nameLen-4, ".ttf") == 0) { whichHeap = HEAP_TTF; + is_swappable = true; } else if ((nameLen > 4 && strcmp(name+nameLen-4, ".dex") == 0) || (nameLen > 5 && strcmp(name+nameLen-5, ".odex") == 0)) { whichHeap = HEAP_DEX; + is_swappable = true; + } else if (nameLen > 4 && strcmp(name+nameLen-4, ".oat") == 0) { + whichHeap = HEAP_OAT; + is_swappable = true; + } else if (nameLen > 4 && strcmp(name+nameLen-4, ".art") == 0) { + whichHeap = HEAP_ART; + is_swappable = true; } else if (nameLen > 0) { whichHeap = HEAP_UNKNOWN_MAP; } else if (start == prevEnd && prevHeap == HEAP_SO) { @@ -225,9 +287,29 @@ static void read_mapinfo(FILE *fp, stats_t* stats) } if (!skip) { + if (is_swappable && (pss > 0)) { + sharing_proportion = 0.0; + if ((shared_clean > 0) || (shared_dirty > 0)) { + sharing_proportion = (pss - private_clean - private_dirty)/(shared_clean+shared_dirty); + } + swappable_pss = (sharing_proportion*shared_clean) + private_clean; + } else + swappable_pss = 0; + stats[whichHeap].pss += pss; + stats[whichHeap].swappablePss += swappable_pss; stats[whichHeap].privateDirty += private_dirty; stats[whichHeap].sharedDirty += shared_dirty; + stats[whichHeap].privateClean += private_clean; + stats[whichHeap].sharedClean += shared_clean; + if (whichHeap == HEAP_DALVIK || whichHeap == HEAP_DALVIK_OTHER) { + stats[subHeap].pss += pss; + stats[subHeap].swappablePss += swappable_pss; + stats[subHeap].privateDirty += private_dirty; + stats[subHeap].sharedDirty += shared_dirty; + stats[subHeap].privateClean += private_clean; + stats[subHeap].sharedClean += shared_clean; + } } } } @@ -251,20 +333,28 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, stats_t stats[_NUM_HEAP]; memset(&stats, 0, sizeof(stats)); + load_maps(pid, stats); - for (int i=_NUM_CORE_HEAP; i<_NUM_HEAP; i++) { + for (int i=_NUM_CORE_HEAP; i<_NUM_EXCLUSIVE_HEAP; i++) { stats[HEAP_UNKNOWN].pss += stats[i].pss; + stats[HEAP_UNKNOWN].swappablePss += stats[i].swappablePss; stats[HEAP_UNKNOWN].privateDirty += stats[i].privateDirty; stats[HEAP_UNKNOWN].sharedDirty += stats[i].sharedDirty; + stats[HEAP_UNKNOWN].privateClean += stats[i].privateClean; + stats[HEAP_UNKNOWN].sharedClean += stats[i].sharedClean; } for (int i=0; i<_NUM_CORE_HEAP; i++) { env->SetIntField(object, stat_fields[i].pss_field, stats[i].pss); + env->SetIntField(object, stat_fields[i].pssSwappable_field, stats[i].swappablePss); env->SetIntField(object, stat_fields[i].privateDirty_field, stats[i].privateDirty); env->SetIntField(object, stat_fields[i].sharedDirty_field, stats[i].sharedDirty); + env->SetIntField(object, stat_fields[i].privateClean_field, stats[i].privateClean); + env->SetIntField(object, stat_fields[i].sharedClean_field, stats[i].sharedClean); } + jintArray otherIntArray = (jintArray)env->GetObjectField(object, otherStats_field); jint* otherArray = (jint*)env->GetPrimitiveArrayCritical(otherIntArray, 0); @@ -275,8 +365,11 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, int j=0; for (int i=_NUM_CORE_HEAP; i<_NUM_HEAP; i++) { otherArray[j++] = stats[i].pss; + otherArray[j++] = stats[i].swappablePss; otherArray[j++] = stats[i].privateDirty; otherArray[j++] = stats[i].sharedDirty; + otherArray[j++] = stats[i].privateClean; + otherArray[j++] = stats[i].sharedClean; } env->ReleasePrimitiveArrayCritical(otherIntArray, otherArray, 0); @@ -617,11 +710,13 @@ int register_android_os_Debug(JNIEnv *env) // Sanity check the number of other statistics expected in Java matches here. jfieldID numOtherStats_field = env->GetStaticFieldID(clazz, "NUM_OTHER_STATS", "I"); jint numOtherStats = env->GetStaticIntField(clazz, numOtherStats_field); + jfieldID numDvkStats_field = env->GetStaticFieldID(clazz, "NUM_DVK_STATS", "I"); + jint numDvkStats = env->GetStaticIntField(clazz, numDvkStats_field); int expectedNumOtherStats = _NUM_HEAP - _NUM_CORE_HEAP; - if (numOtherStats != expectedNumOtherStats) { + if ((numOtherStats + numDvkStats) != expectedNumOtherStats) { jniThrowExceptionFmt(env, "java/lang/RuntimeException", - "android.os.Debug.Meminfo.NUM_OTHER_STATS=%d expected %d", - numOtherStats, expectedNumOtherStats); + "android.os.Debug.Meminfo.NUM_OTHER_STATS+android.os.Debug.Meminfo.NUM_DVK_STATS=%d expected %d", + numOtherStats+numDvkStats, expectedNumOtherStats); return JNI_ERR; } @@ -630,10 +725,16 @@ int register_android_os_Debug(JNIEnv *env) for (int i=0; i<_NUM_CORE_HEAP; i++) { stat_fields[i].pss_field = env->GetFieldID(clazz, stat_field_names[i].pss_name, "I"); + stat_fields[i].pssSwappable_field = + env->GetFieldID(clazz, stat_field_names[i].pssSwappable_name, "I"); stat_fields[i].privateDirty_field = env->GetFieldID(clazz, stat_field_names[i].privateDirty_name, "I"); stat_fields[i].sharedDirty_field = env->GetFieldID(clazz, stat_field_names[i].sharedDirty_name, "I"); + stat_fields[i].privateClean_field = + env->GetFieldID(clazz, stat_field_names[i].privateClean_name, "I"); + stat_fields[i].sharedClean_field = + env->GetFieldID(clazz, stat_field_names[i].sharedClean_name, "I"); } return jniRegisterNativeMethods(env, "android/os/Debug", gMethods, NELEM(gMethods)); diff --git a/core/jni/android_os_MessageQueue.cpp b/core/jni/android_os_MessageQueue.cpp index 7540645..c9c3720 100644 --- a/core/jni/android_os_MessageQueue.cpp +++ b/core/jni/android_os_MessageQueue.cpp @@ -141,6 +141,11 @@ static void android_os_MessageQueue_nativeWake(JNIEnv* env, jclass clazz, jint p return nativeMessageQueue->wake(); } +static jboolean android_os_MessageQueue_nativeIsIdling(JNIEnv* env, jclass clazz, jint ptr) { + NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr); + return nativeMessageQueue->getLooper()->isIdling(); +} + // ---------------------------------------------------------------------------- static JNINativeMethod gMessageQueueMethods[] = { @@ -148,7 +153,8 @@ static JNINativeMethod gMessageQueueMethods[] = { { "nativeInit", "()I", (void*)android_os_MessageQueue_nativeInit }, { "nativeDestroy", "(I)V", (void*)android_os_MessageQueue_nativeDestroy }, { "nativePollOnce", "(II)V", (void*)android_os_MessageQueue_nativePollOnce }, - { "nativeWake", "(I)V", (void*)android_os_MessageQueue_nativeWake } + { "nativeWake", "(I)V", (void*)android_os_MessageQueue_nativeWake }, + { "nativeIsIdling", "(I)Z", (void*)android_os_MessageQueue_nativeIsIdling } }; #define FIND_CLASS(var, className) \ diff --git a/core/jni/android_os_SystemClock.cpp b/core/jni/android_os_SystemClock.cpp index 5c135ee..d20b800 100644 --- a/core/jni/android_os_SystemClock.cpp +++ b/core/jni/android_os_SystemClock.cpp @@ -19,18 +19,67 @@ * System clock functions. */ +#ifdef HAVE_ANDROID_OS +#include <linux/ioctl.h> +#include <linux/rtc.h> +#include <utils/Atomic.h> +#include <linux/android_alarm.h> +#endif + +#include <sys/time.h> +#include <limits.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> + #include "JNIHelp.h" #include "jni.h" #include "android_runtime/AndroidRuntime.h" -#include "utils/SystemClock.h" - #include <sys/time.h> #include <time.h> +#include <utils/SystemClock.h> + namespace android { /* + * Set the current time. This only works when running as root. + */ +static int setCurrentTimeMillis(int64_t millis) +{ + struct timeval tv; + struct timespec ts; + int fd; + int res; + int ret = 0; + + if (millis <= 0 || millis / 1000LL >= INT_MAX) { + return -1; + } + + tv.tv_sec = (time_t) (millis / 1000LL); + tv.tv_usec = (suseconds_t) ((millis % 1000LL) * 1000LL); + + ALOGD("Setting time of day to sec=%d\n", (int) tv.tv_sec); + + fd = open("/dev/alarm", O_RDWR); + if(fd < 0) { + ALOGW("Unable to open alarm driver: %s\n", strerror(errno)); + return -1; + } + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = tv.tv_usec * 1000; + res = ioctl(fd, ANDROID_ALARM_SET_RTC, &ts); + if(res < 0) { + ALOGW("Unable to set rtc to %ld: %s\n", tv.tv_sec, strerror(errno)); + ret = -1; + } + close(fd); + return ret; +} + +/* * native public static void setCurrentTimeMillis(long millis) * * Set the current time. This only works when running as root. diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index 8766cf9..1c92803 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -986,6 +986,7 @@ static bool push_eventlog_int(char** pos, const char* end, jint val) { } // From frameworks/base/core/java/android/content/EventLogTags.logtags: +#define ENABLE_BINDER_SAMPLE 0 #define LOGTAG_BINDER_OPERATION 52004 static void conditionally_log_binder_call(int64_t start_millis, @@ -1063,6 +1064,7 @@ static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, ALOGV("Java code calling transact on %p in Java object %p with code %d\n", target, obj, code); +#if ENABLE_BINDER_SAMPLE // Only log the binder call duration for things on the Java-level main thread. // But if we don't const bool time_binder_calls = should_time_binder_calls(); @@ -1071,12 +1073,15 @@ static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, if (time_binder_calls) { start_millis = uptimeMillis(); } +#endif //printf("Transact from Java code to %p sending: ", target); data->print(); status_t err = target->transact(code, *data, reply, flags); //if (reply) printf("Transact from Java code to %p received: ", target); reply->print(); +#if ENABLE_BINDER_SAMPLE if (time_binder_calls) { conditionally_log_binder_call(start_millis, target, code); } +#endif if (err == NO_ERROR) { return JNI_TRUE; diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp index 5d32328..61eb31b 100644 --- a/core/jni/android_util_Process.cpp +++ b/core/jni/android_util_Process.cpp @@ -99,6 +99,11 @@ jint android_os_Process_myPid(JNIEnv* env, jobject clazz) return getpid(); } +jint android_os_Process_myPpid(JNIEnv* env, jobject clazz) +{ + return getppid(); +} + jint android_os_Process_myUid(JNIEnv* env, jobject clazz) { return getuid(); @@ -990,6 +995,7 @@ jintArray android_os_Process_getPidsForCommands(JNIEnv* env, jobject clazz, static const JNINativeMethod methods[] = { {"myPid", "()I", (void*)android_os_Process_myPid}, + {"myPpid", "()I", (void*)android_os_Process_myPpid}, {"myTid", "()I", (void*)android_os_Process_myTid}, {"myUid", "()I", (void*)android_os_Process_myUid}, {"getUidForName", "(Ljava/lang/String;)I", (void*)android_os_Process_getUidForName}, diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index b87fe27..983a838 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -16,18 +16,19 @@ #define LOG_TAG "OpenGLRenderer" -#include <EGL/egl.h> - #include "jni.h" #include "GraphicsJNI.h" #include <nativehelper/JNIHelp.h> +#include "android_view_GraphicBuffer.h" + #include <android_runtime/AndroidRuntime.h> #include <android_runtime/android_graphics_SurfaceTexture.h> -#include <gui/GLConsumer.h> #include <androidfw/ResourceTypes.h> +#include <gui/GLConsumer.h> + #include <private/hwui/DrawGlInfo.h> #include <cutils/properties.h> @@ -99,10 +100,11 @@ static void android_view_GLES20Canvas_flushCaches(JNIEnv* env, jobject clazz, } } -static void android_view_GLES20Canvas_initCaches(JNIEnv* env, jobject clazz) { +static bool android_view_GLES20Canvas_initCaches(JNIEnv* env, jobject clazz) { if (Caches::hasInstance()) { - Caches::getInstance().init(); + return Caches::getInstance().init(); } + return false; } static void android_view_GLES20Canvas_terminateCaches(JNIEnv* env, jobject clazz) { @@ -112,6 +114,21 @@ static void android_view_GLES20Canvas_terminateCaches(JNIEnv* env, jobject clazz } // ---------------------------------------------------------------------------- +// Caching +// ---------------------------------------------------------------------------- + +static void android_view_GLES20Canvas_initAtlas(JNIEnv* env, jobject clazz, + jobject graphicBuffer, jintArray atlasMapArray, jint count) { + + sp<GraphicBuffer> buffer = graphicBufferForJavaObject(env, graphicBuffer); + jint* atlasMap = env->GetIntArrayElements(atlasMapArray, NULL); + + Caches::getInstance().assetAtlas.init(buffer, atlasMap, count); + + env->ReleaseIntArrayElements(atlasMapArray, atlasMap, 0); +} + +// ---------------------------------------------------------------------------- // Constructors // ---------------------------------------------------------------------------- @@ -168,6 +185,16 @@ static void android_view_GLES20Canvas_setName(JNIEnv* env, } } +static void android_view_GLES20Canvas_setCountOverdrawEnabled(JNIEnv* env, jobject clazz, + OpenGLRenderer* renderer, jboolean enabled) { + renderer->setCountOverdrawEnabled(enabled); +} + +static jfloat android_view_GLES20Canvas_getOverdraw(JNIEnv* env, jobject clazz, + OpenGLRenderer* renderer) { + return renderer->getOverdraw(); +} + // ---------------------------------------------------------------------------- // Functor // ---------------------------------------------------------------------------- @@ -350,31 +377,20 @@ static void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject clazz, // ---------------------------------------------------------------------------- static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject clazz, - OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, - jfloat left, jfloat top, SkPaint* paint) { - // This object allows the renderer to allocate a global JNI ref to the buffer object. - JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); - + OpenGLRenderer* renderer, SkBitmap* bitmap, jfloat left, jfloat top, SkPaint* paint) { renderer->drawBitmap(bitmap, left, top, paint); } static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz, - OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, + OpenGLRenderer* renderer, SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint) { - // This object allows the renderer to allocate a global JNI ref to the buffer object. - JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); - renderer->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom, dstLeft, dstTop, dstRight, dstBottom, paint); } static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject clazz, - OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, SkMatrix* matrix, - SkPaint* paint) { - // This object allows the renderer to allocate a global JNI ref to the buffer object. - JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); - + OpenGLRenderer* renderer, SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) { renderer->drawBitmap(bitmap, matrix, paint); } @@ -404,12 +420,8 @@ static void android_view_GLES20Canvas_drawBitmapData(JNIEnv* env, jobject clazz, } static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz, - OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, - jint meshWidth, jint meshHeight, jfloatArray vertices, jint offset, - jintArray colors, jint colorOffset, SkPaint* paint) { - // This object allows the renderer to allocate a global JNI ref to the buffer object. - JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); - + OpenGLRenderer* renderer, SkBitmap* bitmap, jint meshWidth, jint meshHeight, + jfloatArray vertices, jint offset, jintArray colors, jint colorOffset, SkPaint* paint) { jfloat* verticesArray = vertices ? env->GetFloatArrayElements(vertices, NULL) + offset : NULL; jint* colorsArray = colors ? env->GetIntArrayElements(colors, NULL) + colorOffset : NULL; @@ -420,18 +432,13 @@ static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz, } static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject clazz, - OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, jbyteArray chunks, + OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray chunks, float left, float top, float right, float bottom, SkPaint* paint) { - // This object allows the renderer to allocate a global JNI ref to the buffer object. - JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); - jbyte* storage = env->GetByteArrayElements(chunks, NULL); Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(storage); Res_png_9patch::deserialize(patch); - renderer->drawPatch(bitmap, &patch->xDivs[0], &patch->yDivs[0], - &patch->colors[0], patch->numXDivs, patch->numYDivs, patch->numColors, - left, top, right, bottom, paint); + renderer->drawPatch(bitmap, patch, left, top, right, bottom, paint); env->ReleaseByteArrayElements(chunks, storage, 0); } @@ -567,6 +574,20 @@ static void android_view_GLES20Canvas_resetPaintFilter(JNIEnv* env, jobject claz // Text // ---------------------------------------------------------------------------- +static float xOffsetForTextAlign(SkPaint* paint, float totalAdvance) { + switch (paint->getTextAlign()) { + case SkPaint::kCenter_Align: + return -totalAdvance / 2.0f; + break; + case SkPaint::kRight_Align: + return -totalAdvance; + break; + default: + break; + } + return 0; +} + static void renderText(OpenGLRenderer* renderer, const jchar* text, int count, jfloat x, jfloat y, int flags, SkPaint* paint) { sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint, @@ -579,8 +600,12 @@ static void renderText(OpenGLRenderer* renderer, const jchar* text, int count, jfloat totalAdvance = value->getTotalAdvance(); const float* positions = value->getPos(); int bytesCount = glyphsCount * sizeof(jchar); - renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y, - positions, paint, totalAdvance); + const SkRect& r = value->getBounds(); + android::uirenderer::Rect bounds(r.fLeft, r.fTop, r.fRight, r.fBottom); + + renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, + x + xOffsetForTextAlign(paint, totalAdvance), y, positions, + paint, totalAdvance, bounds); } static void renderTextOnPath(OpenGLRenderer* renderer, const jchar* text, int count, @@ -610,8 +635,12 @@ static void renderTextRun(OpenGLRenderer* renderer, const jchar* text, jfloat totalAdvance = value->getTotalAdvance(); const float* positions = value->getPos(); int bytesCount = glyphsCount * sizeof(jchar); - renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y, - positions, paint, totalAdvance); + const SkRect& r = value->getBounds(); + android::uirenderer::Rect bounds(r.fLeft, r.fTop, r.fRight, r.fBottom); + + renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, + x + xOffsetForTextAlign(paint, totalAdvance), y, positions, + paint, totalAdvance, bounds); } static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject clazz, @@ -932,9 +961,12 @@ static JNINativeMethod gMethods[] = { #ifdef USE_OPENGL_RENDERER { "nFlushCaches", "(I)V", (void*) android_view_GLES20Canvas_flushCaches }, - { "nInitCaches", "()V", (void*) android_view_GLES20Canvas_initCaches }, + { "nInitCaches", "()Z", (void*) android_view_GLES20Canvas_initCaches }, { "nTerminateCaches", "()V", (void*) android_view_GLES20Canvas_terminateCaches }, + { "nInitAtlas", "(Landroid/view/GraphicBuffer;[II)V", + (void*) android_view_GLES20Canvas_initAtlas }, + { "nCreateRenderer", "()I", (void*) android_view_GLES20Canvas_createRenderer }, { "nDestroyRenderer", "(I)V", (void*) android_view_GLES20Canvas_destroyRenderer }, { "nSetViewport", "(III)V", (void*) android_view_GLES20Canvas_setViewport }, @@ -944,6 +976,9 @@ static JNINativeMethod gMethods[] = { { "nSetName", "(ILjava/lang/String;)V", (void*) android_view_GLES20Canvas_setName }, + { "nSetCountOverdrawEnabled", "(IZ)V", (void*) android_view_GLES20Canvas_setCountOverdrawEnabled }, + { "nGetOverdraw", "(I)F", (void*) android_view_GLES20Canvas_getOverdraw }, + { "nGetStencilSize", "()I", (void*) android_view_GLES20Canvas_getStencilSize }, { "nCallDrawGLFunction", "(II)I", (void*) android_view_GLES20Canvas_callDrawGLFunction }, @@ -977,14 +1012,14 @@ static JNINativeMethod gMethods[] = { { "nGetMatrix", "(II)V", (void*) android_view_GLES20Canvas_getMatrix }, { "nConcatMatrix", "(II)V", (void*) android_view_GLES20Canvas_concatMatrix }, - { "nDrawBitmap", "(II[BFFI)V", (void*) android_view_GLES20Canvas_drawBitmap }, - { "nDrawBitmap", "(II[BFFFFFFFFI)V",(void*) android_view_GLES20Canvas_drawBitmapRect }, - { "nDrawBitmap", "(II[BII)V", (void*) android_view_GLES20Canvas_drawBitmapMatrix }, + { "nDrawBitmap", "(IIFFI)V", (void*) android_view_GLES20Canvas_drawBitmap }, + { "nDrawBitmap", "(IIFFFFFFFFI)V", (void*) android_view_GLES20Canvas_drawBitmapRect }, + { "nDrawBitmap", "(IIII)V", (void*) android_view_GLES20Canvas_drawBitmapMatrix }, { "nDrawBitmap", "(I[IIIFFIIZI)V", (void*) android_view_GLES20Canvas_drawBitmapData }, - { "nDrawBitmapMesh", "(II[BII[FI[III)V",(void*) android_view_GLES20Canvas_drawBitmapMesh }, + { "nDrawBitmapMesh", "(IIII[FI[III)V", (void*) android_view_GLES20Canvas_drawBitmapMesh }, - { "nDrawPatch", "(II[B[BFFFFI)V", (void*) android_view_GLES20Canvas_drawPatch }, + { "nDrawPatch", "(II[BFFFFI)V", (void*) android_view_GLES20Canvas_drawPatch }, { "nDrawColor", "(III)V", (void*) android_view_GLES20Canvas_drawColor }, { "nDrawRect", "(IFFFFI)V", (void*) android_view_GLES20Canvas_drawRect }, diff --git a/core/jni/android_view_GraphicBuffer.cpp b/core/jni/android_view_GraphicBuffer.cpp new file mode 100644 index 0000000..d68c0b2 --- /dev/null +++ b/core/jni/android_view_GraphicBuffer.cpp @@ -0,0 +1,331 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "GraphicBuffer" + +#include "jni.h" +#include "JNIHelp.h" + +#include "android_os_Parcel.h" +#include "android_view_GraphicBuffer.h" + +#include <android_runtime/AndroidRuntime.h> + +#include <binder/Parcel.h> + +#include <ui/GraphicBuffer.h> +#include <ui/PixelFormat.h> + +#include <gui/IGraphicBufferAlloc.h> +#include <gui/ISurfaceComposer.h> + +#include <SkCanvas.h> +#include <SkBitmap.h> + +#include <private/gui/ComposerService.h> + +namespace android { + +// ---------------------------------------------------------------------------- +// Defines +// ---------------------------------------------------------------------------- + +// Debug +#define DEBUG_GRAPHIC_BUFFER 0 + +// Debug +#if DEBUG_GRAPHIC_BUFFER + #define GB_LOGD(...) ALOGD(__VA_ARGS__) + #define GB_LOGW(...) ALOGW(__VA_ARGS__) +#else + #define GB_LOGD(...) + #define GB_LOGW(...) +#endif + +#define LOCK_CANVAS_USAGE GraphicBuffer::USAGE_SW_READ_OFTEN | GraphicBuffer::USAGE_SW_WRITE_OFTEN + +// ---------------------------------------------------------------------------- +// JNI Helpers +// ---------------------------------------------------------------------------- + +static struct { + jfieldID mNativeObject; +} gGraphicBufferClassInfo; + +static struct { + jmethodID set; + jfieldID left; + jfieldID top; + jfieldID right; + jfieldID bottom; +} gRectClassInfo; + +static struct { + jfieldID mFinalizer; + jfieldID mNativeCanvas; + jfieldID mSurfaceFormat; +} gCanvasClassInfo; + +static struct { + jfieldID mNativeCanvas; +} gCanvasFinalizerClassInfo; + +#define GET_INT(object, field) \ + env->GetIntField(object, field) + +#define SET_INT(object, field, value) \ + env->SetIntField(object, field, value) + +#define INVOKEV(object, method, ...) \ + env->CallVoidMethod(object, method, __VA_ARGS__) + +// ---------------------------------------------------------------------------- +// Types +// ---------------------------------------------------------------------------- + +class GraphicBufferWrapper { +public: + GraphicBufferWrapper(const sp<GraphicBuffer>& buffer): buffer(buffer) { + } + + sp<GraphicBuffer> buffer; +}; + +// ---------------------------------------------------------------------------- +// GraphicBuffer lifecycle +// ---------------------------------------------------------------------------- + +static GraphicBufferWrapper* android_view_GraphiceBuffer_create(JNIEnv* env, jobject clazz, + jint width, jint height, jint format, jint usage) { + + sp<ISurfaceComposer> composer(ComposerService::getComposerService()); + sp<IGraphicBufferAlloc> alloc(composer->createGraphicBufferAlloc()); + if (alloc == NULL) { + GB_LOGW("createGraphicBufferAlloc() failed in GraphicBuffer.create()"); + return NULL; + } + + status_t error; + sp<GraphicBuffer> buffer(alloc->createGraphicBuffer(width, height, format, usage, &error)); + if (buffer == NULL) { + GB_LOGW("createGraphicBuffer() failed in GraphicBuffer.create()"); + return NULL; + } + + return new GraphicBufferWrapper(buffer); +} + +static void android_view_GraphiceBuffer_destroy(JNIEnv* env, jobject clazz, + GraphicBufferWrapper* wrapper) { + delete wrapper; +} + +// ---------------------------------------------------------------------------- +// Canvas management +// ---------------------------------------------------------------------------- + +static inline void swapCanvasPtr(JNIEnv* env, jobject canvasObj, SkCanvas* newCanvas) { + jobject canvasFinalizerObj = env->GetObjectField(canvasObj, gCanvasClassInfo.mFinalizer); + SkCanvas* previousCanvas = reinterpret_cast<SkCanvas*>( + GET_INT(canvasObj, gCanvasClassInfo.mNativeCanvas)); + SET_INT(canvasObj, gCanvasClassInfo.mNativeCanvas, (int) newCanvas); + SET_INT(canvasFinalizerObj, gCanvasFinalizerClassInfo.mNativeCanvas, (int) newCanvas); + SkSafeUnref(previousCanvas); +} + +static inline SkBitmap::Config convertPixelFormat(int32_t format) { + switch (format) { + case PIXEL_FORMAT_RGBA_8888: + return SkBitmap::kARGB_8888_Config; + case PIXEL_FORMAT_RGBX_8888: + return SkBitmap::kARGB_8888_Config; + case PIXEL_FORMAT_RGB_565: + return SkBitmap::kRGB_565_Config; + default: + return SkBitmap::kNo_Config; + } +} + +static jboolean android_view_GraphicBuffer_lockCanvas(JNIEnv* env, jobject, + GraphicBufferWrapper* wrapper, jobject canvas, jobject dirtyRect) { + + if (!wrapper) { + return false; + } + + sp<GraphicBuffer> buffer(wrapper->buffer); + + Rect rect; + if (dirtyRect) { + rect.left = GET_INT(dirtyRect, gRectClassInfo.left); + rect.top = GET_INT(dirtyRect, gRectClassInfo.top); + rect.right = GET_INT(dirtyRect, gRectClassInfo.right); + rect.bottom = GET_INT(dirtyRect, gRectClassInfo.bottom); + } else { + rect.set(Rect(buffer->getWidth(), buffer->getHeight())); + } + + void* bits = NULL; + status_t status = buffer->lock(LOCK_CANVAS_USAGE, rect, &bits); + + if (status) return false; + if (!bits) { + buffer->unlock(); + return false; + } + + ssize_t bytesCount = buffer->getStride() * bytesPerPixel(buffer->getPixelFormat()); + + SkBitmap bitmap; + bitmap.setConfig(convertPixelFormat(buffer->getPixelFormat()), + buffer->getWidth(), buffer->getHeight(), bytesCount); + + if (buffer->getWidth() > 0 && buffer->getHeight() > 0) { + bitmap.setPixels(bits); + } else { + bitmap.setPixels(NULL); + } + + SET_INT(canvas, gCanvasClassInfo.mSurfaceFormat, buffer->getPixelFormat()); + + SkCanvas* nativeCanvas = SkNEW_ARGS(SkCanvas, (bitmap)); + swapCanvasPtr(env, canvas, nativeCanvas); + + SkRect clipRect; + clipRect.set(rect.left, rect.top, rect.right, rect.bottom); + nativeCanvas->clipRect(clipRect); + + if (dirtyRect) { + INVOKEV(dirtyRect, gRectClassInfo.set, + int(rect.left), int(rect.top), int(rect.right), int(rect.bottom)); + } + + return true; +} + +static jboolean android_view_GraphicBuffer_unlockCanvasAndPost(JNIEnv* env, jobject, + GraphicBufferWrapper* wrapper, jobject canvas) { + + SkCanvas* nativeCanvas = SkNEW(SkCanvas); + swapCanvasPtr(env, canvas, nativeCanvas); + + if (wrapper) { + status_t status = wrapper->buffer->unlock(); + return status == 0; + } + + return false; +} + +// ---------------------------------------------------------------------------- +// Serialization +// ---------------------------------------------------------------------------- + +static void android_view_GraphiceBuffer_write(JNIEnv* env, jobject clazz, + GraphicBufferWrapper* wrapper, jobject dest) { + Parcel* parcel = parcelForJavaObject(env, dest); + if (parcel) { + parcel->write(*wrapper->buffer); + } +} + +static GraphicBufferWrapper* android_view_GraphiceBuffer_read(JNIEnv* env, jobject clazz, + jobject in) { + + Parcel* parcel = parcelForJavaObject(env, in); + if (parcel) { + sp<GraphicBuffer> buffer = new GraphicBuffer(); + parcel->read(*buffer); + return new GraphicBufferWrapper(buffer); + } + + return NULL; +} + +// ---------------------------------------------------------------------------- +// External helpers +// ---------------------------------------------------------------------------- + +sp<GraphicBuffer> graphicBufferForJavaObject(JNIEnv* env, jobject obj) { + if (obj) { + jint nativeObject = env->GetIntField(obj, gGraphicBufferClassInfo.mNativeObject); + GraphicBufferWrapper* wrapper = (GraphicBufferWrapper*) nativeObject; + if (wrapper != NULL) { + sp<GraphicBuffer> buffer(wrapper->buffer); + return buffer; + } + } + return NULL; +} + +// ---------------------------------------------------------------------------- +// JNI Glue +// ---------------------------------------------------------------------------- + +#define FIND_CLASS(var, className) \ + var = env->FindClass(className); \ + LOG_FATAL_IF(! var, "Unable to find class " className); + +#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ + var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ + LOG_FATAL_IF(! var, "Unable to find field " fieldName); + +#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ + var = env->GetMethodID(clazz, methodName, methodDescriptor); \ + LOG_FATAL_IF(!var, "Unable to find method " methodName); + +const char* const kClassPathName = "android/view/GraphicBuffer"; + +static JNINativeMethod gMethods[] = { + { "nCreateGraphicBuffer", "(IIII)I", (void*) android_view_GraphiceBuffer_create }, + { "nDestroyGraphicBuffer", "(I)V", (void*) android_view_GraphiceBuffer_destroy }, + + { "nWriteGraphicBufferToParcel", "(ILandroid/os/Parcel;)V", + (void*) android_view_GraphiceBuffer_write }, + { "nReadGraphicBufferFromParcel", "(Landroid/os/Parcel;)I", + (void*) android_view_GraphiceBuffer_read }, + + { "nLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)Z", + (void*) android_view_GraphicBuffer_lockCanvas }, + { "nUnlockCanvasAndPost", "(ILandroid/graphics/Canvas;)Z", + (void*) android_view_GraphicBuffer_unlockCanvasAndPost }, +}; + +int register_android_view_GraphicBuffer(JNIEnv* env) { + jclass clazz; + FIND_CLASS(clazz, "android/view/GraphicBuffer"); + GET_FIELD_ID(gGraphicBufferClassInfo.mNativeObject, clazz, "mNativeObject", "I"); + + FIND_CLASS(clazz, "android/graphics/Rect"); + GET_METHOD_ID(gRectClassInfo.set, clazz, "set", "(IIII)V"); + GET_FIELD_ID(gRectClassInfo.left, clazz, "left", "I"); + GET_FIELD_ID(gRectClassInfo.top, clazz, "top", "I"); + GET_FIELD_ID(gRectClassInfo.right, clazz, "right", "I"); + GET_FIELD_ID(gRectClassInfo.bottom, clazz, "bottom", "I"); + + FIND_CLASS(clazz, "android/graphics/Canvas"); + GET_FIELD_ID(gCanvasClassInfo.mFinalizer, clazz, "mFinalizer", + "Landroid/graphics/Canvas$CanvasFinalizer;"); + GET_FIELD_ID(gCanvasClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "I"); + GET_FIELD_ID(gCanvasClassInfo.mSurfaceFormat, clazz, "mSurfaceFormat", "I"); + + FIND_CLASS(clazz, "android/graphics/Canvas$CanvasFinalizer"); + GET_FIELD_ID(gCanvasFinalizerClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "I"); + + return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); +} + +}; diff --git a/core/jni/android_view_GraphicBuffer.h b/core/jni/android_view_GraphicBuffer.h new file mode 100644 index 0000000..509587c --- /dev/null +++ b/core/jni/android_view_GraphicBuffer.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <ui/GraphicBuffer.h> + +#include "jni.h" + +namespace android { + +// This function does not perform any type checking, the specified +// object must be an instance of android.view.GraphicBuffer +extern sp<GraphicBuffer> graphicBufferForJavaObject(JNIEnv* env, jobject obj); + +} diff --git a/core/jni/android_view_HardwareRenderer.cpp b/core/jni/android_view_HardwareRenderer.cpp index 948a966..479fbe2 100644 --- a/core/jni/android_view_HardwareRenderer.cpp +++ b/core/jni/android_view_HardwareRenderer.cpp @@ -20,9 +20,14 @@ #include <nativehelper/JNIHelp.h> #include <android_runtime/AndroidRuntime.h> +#include <EGL/egl.h> +#include <EGL/eglext.h> #include <EGL/egl_cache.h> +#include <utils/Timers.h> + #include <Caches.h> +#include <Extensions.h> #ifdef USE_OPENGL_RENDERER EGLAPI void EGLAPIENTRY eglBeginFrame(EGLDisplay dpy, EGLSurface surface); @@ -119,6 +124,13 @@ static void android_view_HardwareRenderer_beginFrame(JNIEnv* env, jobject clazz, eglBeginFrame(display, surface); } +static jlong android_view_HardwareRenderer_getSystemTime(JNIEnv* env, jobject clazz) { + if (uirenderer::Extensions::getInstance().hasNvSystemTime()) { + return eglGetSystemTimeNV(); + } + return systemTime(SYSTEM_TIME_MONOTONIC); +} + #endif // USE_OPENGL_RENDERER // ---------------------------------------------------------------------------- @@ -146,6 +158,8 @@ static JNINativeMethod gMethods[] = { { "nLoadProperties", "()Z", (void*) android_view_HardwareRenderer_loadProperties }, { "nBeginFrame", "([I)V", (void*) android_view_HardwareRenderer_beginFrame }, + + { "nGetSystemTime", "()J", (void*) android_view_HardwareRenderer_getSystemTime }, #endif { "nSetupShadersDiskCache", "(Ljava/lang/String;)V", diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index d9f6be9..842a7f7 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -208,25 +208,19 @@ static void nativeLockCanvas(JNIEnv* env, jclass clazz, return; } - // get dirty region - Region dirtyRegion; + Rect dirtyRect; + Rect* dirtyRectPtr = NULL; + if (dirtyRectObj) { - Rect dirty; - dirty.left = env->GetIntField(dirtyRectObj, gRectClassInfo.left); - dirty.top = env->GetIntField(dirtyRectObj, gRectClassInfo.top); - dirty.right = env->GetIntField(dirtyRectObj, gRectClassInfo.right); - dirty.bottom = env->GetIntField(dirtyRectObj, gRectClassInfo.bottom); - if (!dirty.isEmpty()) { - dirtyRegion.set(dirty); - } - } else { - dirtyRegion.set(Rect(0x3FFF, 0x3FFF)); + dirtyRect.left = env->GetIntField(dirtyRectObj, gRectClassInfo.left); + dirtyRect.top = env->GetIntField(dirtyRectObj, gRectClassInfo.top); + dirtyRect.right = env->GetIntField(dirtyRectObj, gRectClassInfo.right); + dirtyRect.bottom = env->GetIntField(dirtyRectObj, gRectClassInfo.bottom); + dirtyRectPtr = &dirtyRect; } ANativeWindow_Buffer outBuffer; - Rect dirtyBounds(dirtyRegion.getBounds()); - status_t err = surface->lock(&outBuffer, &dirtyBounds); - dirtyRegion.set(dirtyBounds); + status_t err = surface->lock(&outBuffer, dirtyRectPtr); if (err < 0) { const char* const exception = (err == NO_MEMORY) ? OutOfResourcesException : @@ -254,27 +248,15 @@ static void nativeLockCanvas(JNIEnv* env, jclass clazz, SkCanvas* nativeCanvas = SkNEW_ARGS(SkCanvas, (bitmap)); swapCanvasPtr(env, canvasObj, nativeCanvas); - SkRegion clipReg; - if (dirtyRegion.isRect()) { // very common case - const Rect b(dirtyRegion.getBounds()); - clipReg.setRect(b.left, b.top, b.right, b.bottom); - } else { - size_t count; - Rect const* r = dirtyRegion.getArray(&count); - while (count) { - clipReg.op(r->left, r->top, r->right, r->bottom, SkRegion::kUnion_Op); - r++, count--; - } + if (dirtyRectPtr) { + nativeCanvas->clipRect( SkRect::Make(reinterpret_cast<const SkIRect&>(dirtyRect)) ); } - nativeCanvas->clipRegion(clipReg); - if (dirtyRectObj) { - const Rect& bounds(dirtyRegion.getBounds()); - env->SetIntField(dirtyRectObj, gRectClassInfo.left, bounds.left); - env->SetIntField(dirtyRectObj, gRectClassInfo.top, bounds.top); - env->SetIntField(dirtyRectObj, gRectClassInfo.right, bounds.right); - env->SetIntField(dirtyRectObj, gRectClassInfo.bottom, bounds.bottom); + env->SetIntField(dirtyRectObj, gRectClassInfo.left, dirtyRect.left); + env->SetIntField(dirtyRectObj, gRectClassInfo.top, dirtyRect.top); + env->SetIntField(dirtyRectObj, gRectClassInfo.right, dirtyRect.right); + env->SetIntField(dirtyRectObj, gRectClassInfo.bottom, dirtyRect.bottom); } } @@ -392,7 +374,7 @@ int register_android_view_Surface(JNIEnv* env) jclass clazz = env->FindClass("android/view/Surface"); gSurfaceClassInfo.clazz = jclass(env->NewGlobalRef(clazz)); gSurfaceClassInfo.mNativeObject = - env->GetFieldID(gSurfaceClassInfo.clazz, "mNativeSurface", "I"); + env->GetFieldID(gSurfaceClassInfo.clazz, "mNativeObject", "I"); gSurfaceClassInfo.mLock = env->GetFieldID(gSurfaceClassInfo.clazz, "mLock", "Ljava/lang/Object;"); gSurfaceClassInfo.ctor = env->GetMethodID(gSurfaceClassInfo.clazz, "<init>", "(I)V"); diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp index 5baae84..d515696 100644 --- a/core/jni/android_view_TextureView.cpp +++ b/core/jni/android_view_TextureView.cpp @@ -126,19 +126,19 @@ static void android_view_TextureView_destroyNativeWindow(JNIEnv* env, jobject te } static inline void swapCanvasPtr(JNIEnv* env, jobject canvasObj, SkCanvas* newCanvas) { - jobject canvasFinalizerObj = env->GetObjectField(canvasObj, gCanvasClassInfo.mFinalizer); - SkCanvas* previousCanvas = reinterpret_cast<SkCanvas*>( + jobject canvasFinalizerObj = env->GetObjectField(canvasObj, gCanvasClassInfo.mFinalizer); + SkCanvas* previousCanvas = reinterpret_cast<SkCanvas*>( env->GetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas)); - env->SetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas, (int)newCanvas); - env->SetIntField(canvasFinalizerObj, gCanvasFinalizerClassInfo.mNativeCanvas, (int)newCanvas); - SkSafeUnref(previousCanvas); + env->SetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas, (int)newCanvas); + env->SetIntField(canvasFinalizerObj, gCanvasFinalizerClassInfo.mNativeCanvas, (int)newCanvas); + SkSafeUnref(previousCanvas); } -static void android_view_TextureView_lockCanvas(JNIEnv* env, jobject, +static jboolean android_view_TextureView_lockCanvas(JNIEnv* env, jobject, jint nativeWindow, jobject canvas, jobject dirtyRect) { if (!nativeWindow) { - return; + return false; } ANativeWindow_Buffer buffer; @@ -154,7 +154,8 @@ static void android_view_TextureView_lockCanvas(JNIEnv* env, jobject, } sp<ANativeWindow> window((ANativeWindow*) nativeWindow); - native_window_lock(window.get(), &buffer, &rect); + int32_t status = native_window_lock(window.get(), &buffer, &rect); + if (status) return false; ssize_t bytesCount = buffer.stride * bytesPerPixel(buffer.format); @@ -184,6 +185,8 @@ static void android_view_TextureView_lockCanvas(JNIEnv* env, jobject, INVOKEV(dirtyRect, gRectClassInfo.set, int(rect.left), int(rect.top), int(rect.right), int(rect.bottom)); } + + return true; } static void android_view_TextureView_unlockCanvasAndPost(JNIEnv* env, jobject, @@ -213,7 +216,7 @@ static JNINativeMethod gMethods[] = { { "nDestroyNativeWindow", "()V", (void*) android_view_TextureView_destroyNativeWindow }, - { "nLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)V", + { "nLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)Z", (void*) android_view_TextureView_lockCanvas }, { "nUnlockCanvasAndPost", "(ILandroid/graphics/Canvas;)V", (void*) android_view_TextureView_unlockCanvasAndPost }, @@ -241,7 +244,8 @@ int register_android_view_TextureView(JNIEnv* env) { GET_FIELD_ID(gRectClassInfo.bottom, clazz, "bottom", "I"); FIND_CLASS(clazz, "android/graphics/Canvas"); - GET_FIELD_ID(gCanvasClassInfo.mFinalizer, clazz, "mFinalizer", "Landroid/graphics/Canvas$CanvasFinalizer;"); + GET_FIELD_ID(gCanvasClassInfo.mFinalizer, clazz, "mFinalizer", + "Landroid/graphics/Canvas$CanvasFinalizer;"); GET_FIELD_ID(gCanvasClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "I"); GET_FIELD_ID(gCanvasClassInfo.mSurfaceFormat, clazz, "mSurfaceFormat", "I"); diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp index 8d6fab4..bf5accd 100644 --- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp +++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp @@ -20,7 +20,7 @@ #include <android_runtime/AndroidRuntime.h> #include <utils/Log.h> -#include <utils/ZipFileRO.h> +#include <androidfw/ZipFileRO.h> #include <ScopedUtfChars.h> #include <zlib.h> diff --git a/core/jni/com_google_android_gles_jni_GLImpl.cpp b/core/jni/com_google_android_gles_jni_GLImpl.cpp index badd697..b0c26c5 100644 --- a/core/jni/com_google_android_gles_jni_GLImpl.cpp +++ b/core/jni/com_google_android_gles_jni_GLImpl.cpp @@ -1181,7 +1181,7 @@ android_glGetError__ (JNIEnv *_env, jobject _this) { GLenum _returnValue; _returnValue = glGetError(); - return _returnValue; + return (jint)_returnValue; } /* void glGetIntegerv ( GLenum pname, GLint *params ) */ @@ -4017,7 +4017,7 @@ exit: if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); } - return _returnValue; + return (jint)_returnValue; } /* GLbitfield glQueryMatrixxOES ( GLfixed *mantissa, GLint *exponent ) */ @@ -4074,7 +4074,7 @@ exit: if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); } - return _returnValue; + return (jint)_returnValue; } /* void glBindBuffer ( GLenum target, GLuint buffer ) */ @@ -4359,7 +4359,7 @@ android_glColorPointer__IIII (GLint)size, (GLenum)type, (GLsizei)stride, - (const GLvoid *)offset + (GLvoid *)offset ); } @@ -4460,7 +4460,7 @@ android_glDrawElements__IIII (GLenum)mode, (GLsizei)count, (GLenum)type, - (const GLvoid *)offset + (GLvoid *)offset ); if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); @@ -6067,7 +6067,7 @@ android_glIsBuffer__I _returnValue = glIsBuffer( (GLuint)buffer ); - return _returnValue; + return (jboolean)_returnValue; } /* GLboolean glIsEnabled ( GLenum cap ) */ @@ -6078,7 +6078,7 @@ android_glIsEnabled__I _returnValue = glIsEnabled( (GLenum)cap ); - return _returnValue; + return (jboolean)_returnValue; } /* GLboolean glIsTexture ( GLuint texture ) */ @@ -6089,7 +6089,7 @@ android_glIsTexture__I _returnValue = glIsTexture( (GLuint)texture ); - return _returnValue; + return (jboolean)_returnValue; } /* void glNormalPointer ( GLenum type, GLsizei stride, GLint offset ) */ @@ -6099,7 +6099,7 @@ android_glNormalPointer__III glNormalPointer( (GLenum)type, (GLsizei)stride, - (const GLvoid *)offset + (GLvoid *)offset ); } @@ -6326,7 +6326,7 @@ android_glTexCoordPointer__IIII (GLint)size, (GLenum)type, (GLsizei)stride, - (const GLvoid *)offset + (GLvoid *)offset ); } @@ -6756,7 +6756,7 @@ android_glVertexPointer__IIII (GLint)size, (GLenum)type, (GLsizei)stride, - (const GLvoid *)offset + (GLvoid *)offset ); } @@ -7196,7 +7196,7 @@ android_glMatrixIndexPointerOES__IIII (GLint)size, (GLenum)type, (GLsizei)stride, - (const GLvoid *)offset + (GLvoid *)offset ); } @@ -7232,7 +7232,7 @@ android_glWeightPointerOES__IIII (GLint)size, (GLenum)type, (GLsizei)stride, - (const GLvoid *)offset + (GLvoid *)offset ); } @@ -7325,7 +7325,7 @@ android_glCheckFramebufferStatusOES__I _returnValue = glCheckFramebufferStatusOES( (GLint)target ); - return _returnValue; + return (jint)_returnValue; } /* void glDeleteFramebuffersOES ( GLint n, GLuint *framebuffers ) */ @@ -8166,7 +8166,7 @@ android_glIsFramebufferOES__I _returnValue = glIsFramebufferOES( (GLint)framebuffer ); - return _returnValue; + return (jboolean)_returnValue; } /* GLboolean glIsRenderbufferOES ( GLint renderbuffer ) */ @@ -8182,7 +8182,7 @@ android_glIsRenderbufferOES__I _returnValue = glIsRenderbufferOES( (GLint)renderbuffer ); - return _returnValue; + return (jboolean)_returnValue; } /* void glRenderbufferStorageOES ( GLint target, GLint internalformat, GLint width, GLint height ) */ diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 619a10b..6918099 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1078,6 +1078,14 @@ android:description="@string/permdesc_mediaStorageWrite" android:protectionLevel="signature|system" /> + <!-- Allows an application to manage access to documents, usually as part + of a document picker. --> + <permission android:name="android.permission.MANAGE_DOCUMENTS" + android:permissionGroup="android.permission-group.STORAGE" + android:label="@string/permlab_manageDocs" + android:description="@string/permdesc_manageDocs" + android:protectionLevel="signature|system" /> + <!-- ================================== --> <!-- Permissions for screenlock --> <!-- ================================== --> @@ -2202,6 +2210,20 @@ android:description="@string/permdesc_accessNotifications" android:protectionLevel="signature|system" /> + <!-- Allows access to keyguard secure storage. Only allowed for system processes. + @hide --> + <permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" + android:protectionLevel="signature" + android:label="@string/permlab_access_keyguard_secure_storage" + android:description="@string/permdesc_access_keyguard_secure_storage" /> + + <!-- Allows an application to control keyguard. Only allowed for system processes. + @hide --> + <permission android:name="android.permission.CONTROL_KEYGUARD" + android:protectionLevel="signature" + android:label="@string/permlab_control_keyguard" + android:description="@string/permdesc_control_keyguard" /> + <!-- Must be required by an {@link android.service.notification.NotificationListenerService}, to ensure that only the system can bind to it. --> @@ -2276,8 +2298,7 @@ <activity android:name="android.accounts.CantAddAccountActivity" android:excludeFromRecents="true" android:exported="true" - android:theme="@android:style/Theme.Holo.Dialog" - android:label="@string/error_message_title" + android:theme="@android:style/Theme.Holo.Dialog.NoActionBar" android:process=":ui"> </activity> diff --git a/core/res/res/anim/keyguard_action_assist_enter.xml b/core/res/res/anim/keyguard_action_assist_enter.xml deleted file mode 100644 index f3333b7..0000000 --- a/core/res/res/anim/keyguard_action_assist_enter.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** Copyright 2012, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<set xmlns:android="http://schemas.android.com/apk/res/android" - android:shareInterpolator="false" android:zAdjustment="top"> - - <alpha android:fromAlpha="0" android:toAlpha="1.0" - android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" - android:interpolator="@android:interpolator/decelerate_cubic" - android:duration="300"/> - - <translate android:fromYDelta="100%" android:toYDelta="0" - android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" - android:interpolator="@android:interpolator/decelerate_cubic" - android:duration="300" /> -</set> diff --git a/core/res/res/anim/keyguard_security_animate_in.xml b/core/res/res/anim/keyguard_security_animate_in.xml deleted file mode 100644 index 4ee30c3..0000000 --- a/core/res/res/anim/keyguard_security_animate_in.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2012 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> - - <scale - android:interpolator="@android:anim/decelerate_interpolator" - android:fromXScale="0.0" - android:toXScale="1.0" - android:fromYScale="1.0" - android:toYScale="1.0" - android:pivotX="50%" - android:pivotY="50%" - android:fillEnabled="true" - android:fillAfter="true" - android:duration="@integer/kg_security_flip_duration" - android:startOffset="@integer/kg_security_flip_duration" /> - -</set> - diff --git a/core/res/res/anim/keyguard_security_animate_out.xml b/core/res/res/anim/keyguard_security_animate_out.xml deleted file mode 100644 index 76d065c..0000000 --- a/core/res/res/anim/keyguard_security_animate_out.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2012 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> - - <scale - android:interpolator="@android:anim/accelerate_interpolator" - android:fromXScale="1.0" - android:toXScale="0.0" - android:fromYScale="1.0" - android:toYScale="1.0" - android:pivotX="50%" - android:pivotY="50%" - android:fillEnabled="true" - android:fillAfter="true" - android:duration="@integer/kg_security_flip_duration" /> - -</set> - diff --git a/core/res/res/anim/keyguard_security_fade_in.xml b/core/res/res/anim/keyguard_security_fade_in.xml deleted file mode 100644 index 6293432..0000000 --- a/core/res/res/anim/keyguard_security_fade_in.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2012 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. ---> - -<alpha xmlns:android="http://schemas.android.com/apk/res/android" - android:interpolator="@android:interpolator/decelerate_quad" - android:fromAlpha="0.0" android:toAlpha="1.0" - android:duration="@*android:integer/kg_security_fade_duration" /> - - diff --git a/core/res/res/anim/keyguard_security_fade_out.xml b/core/res/res/anim/keyguard_security_fade_out.xml deleted file mode 100644 index 4ab0229..0000000 --- a/core/res/res/anim/keyguard_security_fade_out.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2012 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. ---> -<alpha xmlns:android="http://schemas.android.com/apk/res/android" - android:interpolator="@android:interpolator/accelerate_quad" - android:fromAlpha="1.0" - android:toAlpha="0.0" - android:duration="@*android:integer/kg_security_fade_duration" -/> diff --git a/core/res/res/anim/keyguard_action_assist_exit.xml b/core/res/res/anim/toast_bar_enter.xml index b4ed278..5c0dfcf 100644 --- a/core/res/res/anim/keyguard_action_assist_exit.xml +++ b/core/res/res/anim/toast_bar_enter.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- -/* -** Copyright 2012, The Android Open Source Project +** Copyright 2013, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. @@ -17,7 +16,12 @@ */ --> -<translate xmlns:android="http://schemas.android.com/apk/res/android" - android:interpolator="@android:anim/accelerate_interpolator" - android:fromXDelta="0" android:toXDelta="0" - android:duration="300" /> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:shareInterpolator="false"> + <translate android:fromYDelta="10%" android:toYDelta="0" + android:interpolator="@interpolator/decelerate_quint" + android:duration="@android:integer/config_shortAnimTime"/> + <alpha android:fromAlpha="0.5" android:toAlpha="1.0" + android:interpolator="@interpolator/decelerate_cubic" + android:duration="@android:integer/config_shortAnimTime" /> +</set> diff --git a/core/res/res/values-land/alias.xml b/core/res/res/anim/toast_bar_exit.xml index eac5ece..4e3b7da 100644 --- a/core/res/res/values-land/alias.xml +++ b/core/res/res/anim/toast_bar_exit.xml @@ -1,8 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- -/* //device/apps/common/assets/res/any/colors.xml -** -** Copyright 2012, The Android Open Source Project +** Copyright 2013, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. @@ -17,7 +15,12 @@ ** limitations under the License. */ --> -<resources> - <!-- Alias used to reference one of two possible layouts in keyguard. --> - <item type="layout" name="keyguard_eca">@android:layout/keyguard_emergency_carrier_area_empty</item> -</resources> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:shareInterpolator="false"> + <translate android:fromYDelta="0" android:toYDelta="10%" + android:interpolator="@interpolator/accelerate_quint" + android:duration="@android:integer/config_shortAnimTime"/> + <alpha android:fromAlpha="1.0" android:toAlpha="0.0" + android:interpolator="@interpolator/accelerate_cubic" + android:duration="@android:integer/config_shortAnimTime"/> +</set> diff --git a/core/res/res/drawable-hdpi/ic_facial_backup.png b/core/res/res/drawable-hdpi/ic_facial_backup.png Binary files differdeleted file mode 100644 index 2956109..0000000 --- a/core/res/res/drawable-hdpi/ic_facial_backup.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_alarm.png b/core/res/res/drawable-hdpi/ic_lockscreen_alarm.png Binary files differdeleted file mode 100644 index d7a8cfc..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_alarm.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_camera_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_camera_activated.png Binary files differdeleted file mode 100644 index 19c8eb2..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_camera_activated.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_camera_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_camera_normal.png Binary files differdeleted file mode 100644 index c79a245..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_camera_normal.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_emergencycall_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_emergencycall_normal.png Binary files differdeleted file mode 100644 index 460495a..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_emergencycall_normal.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_emergencycall_pressed.png b/core/res/res/drawable-hdpi/ic_lockscreen_emergencycall_pressed.png Binary files differdeleted file mode 100644 index b0f7ae9..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_emergencycall_pressed.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_forgotpassword_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_forgotpassword_normal.png Binary files differdeleted file mode 100644 index 6402d3d..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_forgotpassword_normal.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_forgotpassword_pressed.png b/core/res/res/drawable-hdpi/ic_lockscreen_forgotpassword_pressed.png Binary files differdeleted file mode 100644 index 83be046..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_forgotpassword_pressed.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_google_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_google_activated.png Binary files differdeleted file mode 100644 index 2c4847c..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_google_activated.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_google_focused.png b/core/res/res/drawable-hdpi/ic_lockscreen_google_focused.png Binary files differdeleted file mode 100644 index d98557d..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_google_focused.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_google_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_google_normal.png Binary files differdeleted file mode 100644 index 656f3ba..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_google_normal.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_handle_normal.png Binary files differdeleted file mode 100644 index 1780ec0..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_handle_normal.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_ime.png b/core/res/res/drawable-hdpi/ic_lockscreen_ime.png Binary files differdeleted file mode 100644 index 29a7989..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_ime.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_lock_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_lock_normal.png Binary files differdeleted file mode 100644 index 732133c..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_lock_normal.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_lock_pressed.png b/core/res/res/drawable-hdpi/ic_lockscreen_lock_pressed.png Binary files differdeleted file mode 100644 index 0bbf62f..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_lock_pressed.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_player_background.9.png b/core/res/res/drawable-hdpi/ic_lockscreen_player_background.9.png Binary files differdeleted file mode 100644 index fbb75b5..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_player_background.9.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_search_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_search_activated.png Binary files differdeleted file mode 100644 index 0d2e2ef..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_search_activated.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_search_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_search_normal.png Binary files differdeleted file mode 100644 index 66d14ae..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_search_normal.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_silent_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_silent_activated.png Binary files differdeleted file mode 100644 index 7060d59..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_silent_activated.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_silent_focused.png b/core/res/res/drawable-hdpi/ic_lockscreen_silent_focused.png Binary files differdeleted file mode 100644 index f9a8c7c..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_silent_focused.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_silent_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_silent_normal.png Binary files differdeleted file mode 100644 index b47cd08..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_silent_normal.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_sim.png b/core/res/res/drawable-hdpi/ic_lockscreen_sim.png Binary files differdeleted file mode 100644 index 7cf9e36..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_sim.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_soundon_activated.png Binary files differdeleted file mode 100644 index 88d0a9f..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_activated.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_focused.png b/core/res/res/drawable-hdpi/ic_lockscreen_soundon_focused.png Binary files differdeleted file mode 100644 index 6e16e40..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_focused.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_soundon_normal.png Binary files differdeleted file mode 100644 index 0dd81c0..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_normal.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_unlock_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_unlock_activated.png Binary files differdeleted file mode 100644 index 374a62a..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_unlock_activated.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_unlock_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_unlock_normal.png Binary files differdeleted file mode 100644 index 3960893..0000000 --- a/core/res/res/drawable-hdpi/ic_lockscreen_unlock_normal.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/intro_bg.png b/core/res/res/drawable-hdpi/intro_bg.png Binary files differdeleted file mode 100644 index a758e7d..0000000 --- a/core/res/res/drawable-hdpi/intro_bg.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/kg_add_widget.png b/core/res/res/drawable-hdpi/kg_add_widget.png Binary files differdeleted file mode 100644 index 68971a5..0000000 --- a/core/res/res/drawable-hdpi/kg_add_widget.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/kg_add_widget_disabled.png b/core/res/res/drawable-hdpi/kg_add_widget_disabled.png Binary files differdeleted file mode 100644 index f24cf642..0000000 --- a/core/res/res/drawable-hdpi/kg_add_widget_disabled.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/kg_add_widget_pressed.png b/core/res/res/drawable-hdpi/kg_add_widget_pressed.png Binary files differdeleted file mode 100644 index 55112ca..0000000 --- a/core/res/res/drawable-hdpi/kg_add_widget_pressed.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/kg_bouncer_bg_white.9.png b/core/res/res/drawable-hdpi/kg_bouncer_bg_white.9.png Binary files differdeleted file mode 100644 index cfd5db3..0000000 --- a/core/res/res/drawable-hdpi/kg_bouncer_bg_white.9.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/kg_security_grip.9.png b/core/res/res/drawable-hdpi/kg_security_grip.9.png Binary files differdeleted file mode 100644 index 1e40aef..0000000 --- a/core/res/res/drawable-hdpi/kg_security_grip.9.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/kg_security_lock.png b/core/res/res/drawable-hdpi/kg_security_lock.png Binary files differdeleted file mode 100644 index c3c94c4..0000000 --- a/core/res/res/drawable-hdpi/kg_security_lock.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/kg_security_lock_focused.png b/core/res/res/drawable-hdpi/kg_security_lock_focused.png Binary files differdeleted file mode 100644 index abcf683..0000000 --- a/core/res/res/drawable-hdpi/kg_security_lock_focused.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/kg_security_lock_normal.png b/core/res/res/drawable-hdpi/kg_security_lock_normal.png Binary files differdeleted file mode 100644 index e8cff24..0000000 --- a/core/res/res/drawable-hdpi/kg_security_lock_normal.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/kg_security_lock_pressed.png b/core/res/res/drawable-hdpi/kg_security_lock_pressed.png Binary files differdeleted file mode 100644 index 3214dcb..0000000 --- a/core/res/res/drawable-hdpi/kg_security_lock_pressed.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/kg_widget_bg_padded.9.png b/core/res/res/drawable-hdpi/kg_widget_bg_padded.9.png Binary files differdeleted file mode 100644 index dff1dfa..0000000 --- a/core/res/res/drawable-hdpi/kg_widget_bg_padded.9.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/kg_widget_delete_drop_target.png b/core/res/res/drawable-hdpi/kg_widget_delete_drop_target.png Binary files differdeleted file mode 100644 index 84549ff..0000000 --- a/core/res/res/drawable-hdpi/kg_widget_delete_drop_target.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/lockscreen_protection_pattern.png b/core/res/res/drawable-hdpi/lockscreen_protection_pattern.png Binary files differdeleted file mode 100644 index 681d8be..0000000 --- a/core/res/res/drawable-hdpi/lockscreen_protection_pattern.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/sym_keyboard_return_holo.png b/core/res/res/drawable-hdpi/sym_keyboard_return_holo.png Binary files differdeleted file mode 100644 index f1bcf48..0000000 --- a/core/res/res/drawable-hdpi/sym_keyboard_return_holo.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/toast_bar_bg.9.png b/core/res/res/drawable-hdpi/toast_bar_bg.9.png Binary files differnew file mode 100644 index 0000000..2396b26 --- /dev/null +++ b/core/res/res/drawable-hdpi/toast_bar_bg.9.png diff --git a/core/res/res/drawable-mdpi/ic_facial_backup.png b/core/res/res/drawable-mdpi/ic_facial_backup.png Binary files differdeleted file mode 100644 index 6ed1327..0000000 --- a/core/res/res/drawable-mdpi/ic_facial_backup.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_alarm.png b/core/res/res/drawable-mdpi/ic_lockscreen_alarm.png Binary files differdeleted file mode 100644 index 330ade1..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_alarm.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_camera_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_camera_activated.png Binary files differdeleted file mode 100644 index 862f33b..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_camera_activated.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_camera_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_camera_normal.png Binary files differdeleted file mode 100644 index 30df0a3..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_camera_normal.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_emergencycall_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_emergencycall_normal.png Binary files differdeleted file mode 100644 index cae795f..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_emergencycall_normal.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_emergencycall_pressed.png b/core/res/res/drawable-mdpi/ic_lockscreen_emergencycall_pressed.png Binary files differdeleted file mode 100644 index 2867956..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_emergencycall_pressed.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_forgotpassword_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_forgotpassword_normal.png Binary files differdeleted file mode 100644 index a7e063a..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_forgotpassword_normal.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_forgotpassword_pressed.png b/core/res/res/drawable-mdpi/ic_lockscreen_forgotpassword_pressed.png Binary files differdeleted file mode 100644 index 53af5a5..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_forgotpassword_pressed.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_google_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_google_activated.png Binary files differdeleted file mode 100644 index 32a68e0..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_google_activated.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_google_focused.png b/core/res/res/drawable-mdpi/ic_lockscreen_google_focused.png Binary files differdeleted file mode 100644 index 3f96d03..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_google_focused.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_google_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_google_normal.png Binary files differdeleted file mode 100644 index 2f7efcf..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_google_normal.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_handle_normal.png Binary files differdeleted file mode 100644 index 1d547e1..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_handle_normal.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_ime.png b/core/res/res/drawable-mdpi/ic_lockscreen_ime.png Binary files differdeleted file mode 100644 index b27e059..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_ime.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_lock_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_lock_normal.png Binary files differdeleted file mode 100644 index 30eb974..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_lock_normal.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_lock_pressed.png b/core/res/res/drawable-mdpi/ic_lockscreen_lock_pressed.png Binary files differdeleted file mode 100644 index aab2f6b..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_lock_pressed.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_player_background.9.png b/core/res/res/drawable-mdpi/ic_lockscreen_player_background.9.png Binary files differdeleted file mode 100644 index 17d97c4..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_player_background.9.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_search_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_search_activated.png Binary files differdeleted file mode 100644 index 73c6be6..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_search_activated.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_search_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_search_normal.png Binary files differdeleted file mode 100644 index 73c6be6..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_search_normal.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_silent_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_silent_activated.png Binary files differdeleted file mode 100644 index 2bc3f52..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_silent_activated.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_silent_focused.png b/core/res/res/drawable-mdpi/ic_lockscreen_silent_focused.png Binary files differdeleted file mode 100644 index 6a5af9d..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_silent_focused.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_silent_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_silent_normal.png Binary files differdeleted file mode 100644 index c288ce4..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_silent_normal.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_sim.png b/core/res/res/drawable-mdpi/ic_lockscreen_sim.png Binary files differdeleted file mode 100644 index 2e259c3..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_sim.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_soundon_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_soundon_activated.png Binary files differdeleted file mode 100644 index 637eec6..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_soundon_activated.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_soundon_focused.png b/core/res/res/drawable-mdpi/ic_lockscreen_soundon_focused.png Binary files differdeleted file mode 100644 index db59b5f..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_soundon_focused.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_soundon_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_soundon_normal.png Binary files differdeleted file mode 100644 index eb6ceed..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_soundon_normal.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_unlock_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_unlock_activated.png Binary files differdeleted file mode 100644 index 68409c5..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_unlock_activated.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_unlock_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_unlock_normal.png Binary files differdeleted file mode 100644 index 52866f2..0000000 --- a/core/res/res/drawable-mdpi/ic_lockscreen_unlock_normal.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/intro_bg.png b/core/res/res/drawable-mdpi/intro_bg.png Binary files differdeleted file mode 100644 index 540da31..0000000 --- a/core/res/res/drawable-mdpi/intro_bg.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/kg_add_widget.png b/core/res/res/drawable-mdpi/kg_add_widget.png Binary files differdeleted file mode 100644 index 136ae17..0000000 --- a/core/res/res/drawable-mdpi/kg_add_widget.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/kg_add_widget_disabled.png b/core/res/res/drawable-mdpi/kg_add_widget_disabled.png Binary files differdeleted file mode 100644 index 02e0f0e..0000000 --- a/core/res/res/drawable-mdpi/kg_add_widget_disabled.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/kg_add_widget_pressed.png b/core/res/res/drawable-mdpi/kg_add_widget_pressed.png Binary files differdeleted file mode 100644 index 34a7aaa..0000000 --- a/core/res/res/drawable-mdpi/kg_add_widget_pressed.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/kg_bouncer_bg_white.9.png b/core/res/res/drawable-mdpi/kg_bouncer_bg_white.9.png Binary files differdeleted file mode 100644 index e3cb6db..0000000 --- a/core/res/res/drawable-mdpi/kg_bouncer_bg_white.9.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/kg_security_grip.9.png b/core/res/res/drawable-mdpi/kg_security_grip.9.png Binary files differdeleted file mode 100644 index 334a39b..0000000 --- a/core/res/res/drawable-mdpi/kg_security_grip.9.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/kg_security_lock.png b/core/res/res/drawable-mdpi/kg_security_lock.png Binary files differdeleted file mode 100644 index a39f380..0000000 --- a/core/res/res/drawable-mdpi/kg_security_lock.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/kg_security_lock_focused.png b/core/res/res/drawable-mdpi/kg_security_lock_focused.png Binary files differdeleted file mode 100644 index c567a82..0000000 --- a/core/res/res/drawable-mdpi/kg_security_lock_focused.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/kg_security_lock_normal.png b/core/res/res/drawable-mdpi/kg_security_lock_normal.png Binary files differdeleted file mode 100644 index 6fbecc1..0000000 --- a/core/res/res/drawable-mdpi/kg_security_lock_normal.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/kg_security_lock_pressed.png b/core/res/res/drawable-mdpi/kg_security_lock_pressed.png Binary files differdeleted file mode 100644 index a883258..0000000 --- a/core/res/res/drawable-mdpi/kg_security_lock_pressed.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/kg_widget_bg_padded.9.png b/core/res/res/drawable-mdpi/kg_widget_bg_padded.9.png Binary files differdeleted file mode 100644 index c313df1..0000000 --- a/core/res/res/drawable-mdpi/kg_widget_bg_padded.9.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/kg_widget_delete_drop_target.png b/core/res/res/drawable-mdpi/kg_widget_delete_drop_target.png Binary files differdeleted file mode 100644 index 219f3e5..0000000 --- a/core/res/res/drawable-mdpi/kg_widget_delete_drop_target.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/lockscreen_protection_pattern.png b/core/res/res/drawable-mdpi/lockscreen_protection_pattern.png Binary files differdeleted file mode 100644 index 30bcea5..0000000 --- a/core/res/res/drawable-mdpi/lockscreen_protection_pattern.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/sym_keyboard_return_holo.png b/core/res/res/drawable-mdpi/sym_keyboard_return_holo.png Binary files differdeleted file mode 100644 index d5a7708..0000000 --- a/core/res/res/drawable-mdpi/sym_keyboard_return_holo.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/toast_bar_bg.9.png b/core/res/res/drawable-mdpi/toast_bar_bg.9.png Binary files differnew file mode 100644 index 0000000..291a936 --- /dev/null +++ b/core/res/res/drawable-mdpi/toast_bar_bg.9.png diff --git a/core/res/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_normal.png Binary files differdeleted file mode 100644 index f28fe38..0000000 --- a/core/res/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_normal.png +++ /dev/null diff --git a/core/res/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_normal.png Binary files differdeleted file mode 100644 index 99e742f..0000000 --- a/core/res/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_normal.png +++ /dev/null diff --git a/core/res/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_normal.png Binary files differdeleted file mode 100644 index 75e4783..0000000 --- a/core/res/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_normal.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_facial_backup.png b/core/res/res/drawable-xhdpi/ic_facial_backup.png Binary files differdeleted file mode 100644 index 942cf23..0000000 --- a/core/res/res/drawable-xhdpi/ic_facial_backup.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_alarm.png b/core/res/res/drawable-xhdpi/ic_lockscreen_alarm.png Binary files differdeleted file mode 100644 index e6cceef..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_alarm.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_camera_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_camera_activated.png Binary files differdeleted file mode 100644 index 760ef2d..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_camera_activated.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_camera_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_camera_normal.png Binary files differdeleted file mode 100644 index 093bc05..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_camera_normal.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_emergencycall_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_emergencycall_normal.png Binary files differdeleted file mode 100644 index a61f7a5..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_emergencycall_normal.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_emergencycall_pressed.png b/core/res/res/drawable-xhdpi/ic_lockscreen_emergencycall_pressed.png Binary files differdeleted file mode 100644 index dd5e481..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_emergencycall_pressed.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_forgotpassword_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_forgotpassword_normal.png Binary files differdeleted file mode 100644 index e4172ce..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_forgotpassword_normal.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_forgotpassword_pressed.png b/core/res/res/drawable-xhdpi/ic_lockscreen_forgotpassword_pressed.png Binary files differdeleted file mode 100644 index e2c7621..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_forgotpassword_pressed.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_google_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_google_activated.png Binary files differdeleted file mode 100644 index d643f83..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_google_activated.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_google_focused.png b/core/res/res/drawable-xhdpi/ic_lockscreen_google_focused.png Binary files differdeleted file mode 100644 index 51863f4..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_google_focused.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_google_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_google_normal.png Binary files differdeleted file mode 100644 index 9a9bf68..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_google_normal.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_handle_normal.png Binary files differdeleted file mode 100644 index b09071b..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_handle_normal.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_ime.png b/core/res/res/drawable-xhdpi/ic_lockscreen_ime.png Binary files differdeleted file mode 100644 index a40ddeb..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_ime.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_lock_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_lock_normal.png Binary files differdeleted file mode 100644 index c44a330..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_lock_normal.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_lock_pressed.png b/core/res/res/drawable-xhdpi/ic_lockscreen_lock_pressed.png Binary files differdeleted file mode 100644 index 2264dc3..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_lock_pressed.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_player_background.9.png b/core/res/res/drawable-xhdpi/ic_lockscreen_player_background.9.png Binary files differdeleted file mode 100644 index 393bca6..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_player_background.9.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_silent_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_silent_activated.png Binary files differdeleted file mode 100644 index 2900045..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_silent_activated.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_silent_focused.png b/core/res/res/drawable-xhdpi/ic_lockscreen_silent_focused.png Binary files differdeleted file mode 100644 index 5a93472..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_silent_focused.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_silent_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_silent_normal.png Binary files differdeleted file mode 100644 index 73f6a2e..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_silent_normal.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_sim.png b/core/res/res/drawable-xhdpi/ic_lockscreen_sim.png Binary files differdeleted file mode 100644 index f4de96a..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_sim.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_activated.png Binary files differdeleted file mode 100644 index da2adc2..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_activated.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_focused.png b/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_focused.png Binary files differdeleted file mode 100644 index 0485af0..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_focused.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_normal.png Binary files differdeleted file mode 100644 index 6af5375..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_normal.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_unlock_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_unlock_activated.png Binary files differdeleted file mode 100644 index 8a0331d..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_unlock_activated.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_unlock_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_unlock_normal.png Binary files differdeleted file mode 100644 index 0422117..0000000 --- a/core/res/res/drawable-xhdpi/ic_lockscreen_unlock_normal.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/intro_bg.png b/core/res/res/drawable-xhdpi/intro_bg.png Binary files differdeleted file mode 100644 index 00466c5..0000000 --- a/core/res/res/drawable-xhdpi/intro_bg.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/kg_add_widget.png b/core/res/res/drawable-xhdpi/kg_add_widget.png Binary files differdeleted file mode 100644 index ca48be2..0000000 --- a/core/res/res/drawable-xhdpi/kg_add_widget.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/kg_add_widget_disabled.png b/core/res/res/drawable-xhdpi/kg_add_widget_disabled.png Binary files differdeleted file mode 100644 index 55fa1ac..0000000 --- a/core/res/res/drawable-xhdpi/kg_add_widget_disabled.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/kg_add_widget_pressed.png b/core/res/res/drawable-xhdpi/kg_add_widget_pressed.png Binary files differdeleted file mode 100644 index 4b86727..0000000 --- a/core/res/res/drawable-xhdpi/kg_add_widget_pressed.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/kg_bouncer_bg_white.9.png b/core/res/res/drawable-xhdpi/kg_bouncer_bg_white.9.png Binary files differdeleted file mode 100644 index b9e30e2..0000000 --- a/core/res/res/drawable-xhdpi/kg_bouncer_bg_white.9.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/kg_security_grip.9.png b/core/res/res/drawable-xhdpi/kg_security_grip.9.png Binary files differdeleted file mode 100644 index c33b9d3..0000000 --- a/core/res/res/drawable-xhdpi/kg_security_grip.9.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/kg_security_lock.png b/core/res/res/drawable-xhdpi/kg_security_lock.png Binary files differdeleted file mode 100644 index 81d577e..0000000 --- a/core/res/res/drawable-xhdpi/kg_security_lock.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/kg_security_lock_focused.png b/core/res/res/drawable-xhdpi/kg_security_lock_focused.png Binary files differdeleted file mode 100644 index ee21647..0000000 --- a/core/res/res/drawable-xhdpi/kg_security_lock_focused.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/kg_security_lock_normal.png b/core/res/res/drawable-xhdpi/kg_security_lock_normal.png Binary files differdeleted file mode 100644 index eae7d8c..0000000 --- a/core/res/res/drawable-xhdpi/kg_security_lock_normal.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/kg_security_lock_pressed.png b/core/res/res/drawable-xhdpi/kg_security_lock_pressed.png Binary files differdeleted file mode 100644 index 5e9a52b..0000000 --- a/core/res/res/drawable-xhdpi/kg_security_lock_pressed.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/kg_widget_bg_padded.9.png b/core/res/res/drawable-xhdpi/kg_widget_bg_padded.9.png Binary files differdeleted file mode 100644 index a84bfa3..0000000 --- a/core/res/res/drawable-xhdpi/kg_widget_bg_padded.9.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/kg_widget_delete_drop_target.png b/core/res/res/drawable-xhdpi/kg_widget_delete_drop_target.png Binary files differdeleted file mode 100644 index d4965d9..0000000 --- a/core/res/res/drawable-xhdpi/kg_widget_delete_drop_target.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/lockscreen_protection_pattern.png b/core/res/res/drawable-xhdpi/lockscreen_protection_pattern.png Binary files differdeleted file mode 100644 index c13afe2..0000000 --- a/core/res/res/drawable-xhdpi/lockscreen_protection_pattern.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/sym_keyboard_return_holo.png b/core/res/res/drawable-xhdpi/sym_keyboard_return_holo.png Binary files differdeleted file mode 100644 index 55174e0..0000000 --- a/core/res/res/drawable-xhdpi/sym_keyboard_return_holo.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/toast_bar_bg.9.png b/core/res/res/drawable-xhdpi/toast_bar_bg.9.png Binary files differnew file mode 100644 index 0000000..1dc4927 --- /dev/null +++ b/core/res/res/drawable-xhdpi/toast_bar_bg.9.png diff --git a/core/res/res/drawable/ic_lockscreen_camera.xml b/core/res/res/drawable/ic_lockscreen_camera.xml deleted file mode 100644 index 41277fe..0000000 --- a/core/res/res/drawable/ic_lockscreen_camera.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2011 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - - <item - android:state_enabled="true" - android:state_active="false" - android:state_focused="false" - android:drawable="@drawable/ic_lockscreen_camera_normal" /> - - <item - android:state_enabled="true" - android:state_active="true" - android:state_focused="false" - android:drawable="@drawable/ic_lockscreen_camera_activated" /> - - <item - android:state_enabled="true" - android:state_active="false" - android:state_focused="true" - android:drawable="@drawable/ic_lockscreen_camera_activated" /> - -</selector> diff --git a/core/res/res/drawable/ic_lockscreen_handle.xml b/core/res/res/drawable/ic_lockscreen_handle.xml deleted file mode 100644 index e7b4a6e..0000000 --- a/core/res/res/drawable/ic_lockscreen_handle.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2011 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - - <item - android:state_enabled="true" - android:state_active="false" - android:state_focused="false" - android:drawable="@drawable/ic_lockscreen_handle_normal" /> - - <item - android:state_enabled="true" - android:state_active="true" - android:state_focused="false" - android:drawable="@drawable/ic_lockscreen_handle_pressed" /> - -</selector> diff --git a/core/res/res/drawable/ic_lockscreen_silent.xml b/core/res/res/drawable/ic_lockscreen_silent.xml deleted file mode 100644 index df23278..0000000 --- a/core/res/res/drawable/ic_lockscreen_silent.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2011 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - - <item - android:state_enabled="true" - android:state_active="false" - android:state_focused="false" - android:drawable="@drawable/ic_lockscreen_silent_normal" /> - - <item - android:state_enabled="true" - android:state_active="true" - android:state_focused="false" - android:drawable="@drawable/ic_lockscreen_silent_activated" /> - - <item - android:state_enabled="true" - android:state_active="false" - android:state_focused="true" - android:drawable="@drawable/ic_lockscreen_silent_activated" /> - -</selector> diff --git a/core/res/res/drawable/ic_lockscreen_soundon.xml b/core/res/res/drawable/ic_lockscreen_soundon.xml deleted file mode 100644 index b44c86c..0000000 --- a/core/res/res/drawable/ic_lockscreen_soundon.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2011 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - - <item - android:state_enabled="true" - android:state_active="false" - android:state_focused="false" - android:drawable="@drawable/ic_lockscreen_soundon_normal" /> - - <item - android:state_enabled="true" - android:state_active="true" - android:state_focused="false" - android:drawable="@drawable/ic_lockscreen_soundon_activated" /> - - <item - android:state_enabled="true" - android:state_active="false" - android:state_focused="true" - android:drawable="@drawable/ic_lockscreen_soundon_activated" /> - -</selector> diff --git a/core/res/res/drawable/ic_lockscreen_unlock.xml b/core/res/res/drawable/ic_lockscreen_unlock.xml deleted file mode 100644 index bb1d0ee..0000000 --- a/core/res/res/drawable/ic_lockscreen_unlock.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2011 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - - <item - android:state_enabled="true" - android:state_active="false" - android:state_focused="false" - android:drawable="@drawable/ic_lockscreen_unlock_normal" /> - - <item - android:state_enabled="true" - android:state_active="true" - android:state_focused="false" - android:drawable="@drawable/ic_lockscreen_unlock_activated" /> - - <item - android:state_enabled="true" - android:state_active="false" - android:state_focused="true" - android:drawable="@drawable/ic_lockscreen_unlock_activated" /> - -</selector> diff --git a/core/res/res/drawable/ic_lockscreen_unlock_phantom.xml b/core/res/res/drawable/ic_lockscreen_unlock_phantom.xml deleted file mode 100644 index 83f0aed..0000000 --- a/core/res/res/drawable/ic_lockscreen_unlock_phantom.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2011 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - - <item - android:state_enabled="true" - android:state_active="false" - android:state_focused="false" - android:drawable="@color/transparent" /> - - <item - android:state_enabled="true" - android:state_active="true" - android:state_focused="false" - android:drawable="@drawable/ic_lockscreen_unlock_activated" /> - - <item - android:state_enabled="true" - android:state_active="false" - android:state_focused="true" - android:drawable="@drawable/ic_lockscreen_unlock_activated" /> - -</selector> diff --git a/core/res/res/drawable/keyguard_add_widget_button.xml b/core/res/res/drawable/keyguard_add_widget_button.xml deleted file mode 100644 index c26f81d..0000000 --- a/core/res/res/drawable/keyguard_add_widget_button.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2012 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_pressed="true" android:drawable="@drawable/kg_add_widget_pressed" /> - <item android:state_enabled="false" android:drawable="@drawable/kg_add_widget_disabled" /> - <item android:drawable="@drawable/kg_add_widget" /> -</selector> diff --git a/core/res/res/drawable/keyguard_expand_challenge_handle.xml b/core/res/res/drawable/keyguard_expand_challenge_handle.xml deleted file mode 100644 index 3e0780b..0000000 --- a/core/res/res/drawable/keyguard_expand_challenge_handle.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2012 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/kg_security_lock_focused" /> - <item android:state_pressed="true" android:drawable="@drawable/kg_security_lock_pressed" /> - <item android:drawable="@drawable/kg_security_lock_normal" /> -</selector> diff --git a/core/res/res/drawable/lockscreen_emergency_button.xml b/core/res/res/drawable/lockscreen_emergency_button.xml deleted file mode 100644 index 4ec6a96..0000000 --- a/core/res/res/drawable/lockscreen_emergency_button.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2008 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_enabled="true" android:drawable="@drawable/ic_lockscreen_emergencycall_normal" /> - <item android:state_pressed="true" android:drawable="@drawable/ic_lockscreen_emergencycall_pressed" /> - <item android:drawable="@drawable/ic_lockscreen_emergencycall_normal" /> -</selector> diff --git a/core/res/res/drawable/lockscreen_forgot_password_button.xml b/core/res/res/drawable/lockscreen_forgot_password_button.xml deleted file mode 100644 index 6c081bf..0000000 --- a/core/res/res/drawable/lockscreen_forgot_password_button.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2008 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_enabled="true" android:drawable="@drawable/ic_lockscreen_forgotpassword_normal" /> - <item android:state_pressed="true" android:drawable="@drawable/ic_lockscreen_forgotpassword_pressed" /> - <item android:drawable="@drawable/ic_lockscreen_forgotpassword_normal" /> -</selector> diff --git a/core/res/res/drawable/lockscreen_password_field_dark.xml b/core/res/res/drawable/lockscreen_password_field_dark.xml deleted file mode 100644 index 92ceb79..0000000 --- a/core/res/res/drawable/lockscreen_password_field_dark.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?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:state_enabled="true" android:drawable="@drawable/textfield_bg_default_holo_dark" /> - <item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/textfield_bg_disabled_holo_dark" /> - <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_bg_activated_holo_dark" /> - <iten android:state_enabled="true" android:state_activated="true" android:drawable="@drawable/textfield_bg_focused_holo_dark" /> - <item android:state_enabled="true" android:drawable="@drawable/textfield_bg_default_holo_dark" /> - <item android:state_focused="true" android:drawable="@drawable/textfield_bg_disabled_focused_holo_dark" /> - <item android:drawable="@drawable/textfield_bg_disabled_holo_dark" /> -</selector> - diff --git a/core/res/res/layout-land/keyguard_glow_pad_container.xml b/core/res/res/layout-land/keyguard_glow_pad_container.xml deleted file mode 100644 index f8364f1..0000000 --- a/core/res/res/layout-land/keyguard_glow_pad_container.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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. -*/ ---> - -<merge xmlns:android="http://schemas.android.com/apk/res/android"> - <include layout="@layout/keyguard_glow_pad_view" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" /> -</merge>
\ No newline at end of file diff --git a/core/res/res/layout-land/keyguard_host_view.xml b/core/res/res/layout-land/keyguard_host_view.xml deleted file mode 100644 index 6b36235..0000000 --- a/core/res/res/layout-land/keyguard_host_view.xml +++ /dev/null @@ -1,80 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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. -*/ ---> - -<!-- This is the host view that generally contains two sub views: the widget view - and the security view. --> -<com.android.internal.policy.impl.keyguard.KeyguardHostView - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:androidprv="http://schemas.android.com/apk/res/android" - android:id="@+id/keyguard_host_view" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="horizontal"> - - <com.android.internal.policy.impl.keyguard.MultiPaneChallengeLayout - android:id="@+id/multi_pane_challenge" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:clipChildren="false"> - - <include layout="@layout/keyguard_widget_remove_drop_target" - android:id="@+id/keyguard_widget_pager_delete_target" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="top|center_horizontal" - androidprv:layout_childType="pageDeleteDropTarget" /> - - <include layout="@layout/keyguard_widget_pager" - android:id="@+id/app_widget_container" - android:layout_width="match_parent" - android:layout_height="match_parent" - androidprv:layout_centerWithinArea="0.55" - androidprv:layout_childType="widget" - androidprv:layout_maxWidth="480dp" - androidprv:layout_maxHeight="480dp" /> - <include layout="@layout/keyguard_multi_user_selector"/> - - <View android:layout_width="match_parent" - android:layout_height="match_parent" - androidprv:layout_childType="scrim" - android:background="#99000000" /> - - <com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer - android:id="@+id/keyguard_security_container" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - androidprv:layout_childType="challenge" - androidprv:layout_centerWithinArea="0.55"> - <com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper - android:id="@+id/view_flipper" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:clipChildren="false" - android:clipToPadding="false" - android:paddingLeft="@dimen/keyguard_security_view_margin" - android:paddingTop="@dimen/keyguard_security_view_margin" - android:paddingRight="@dimen/keyguard_security_view_margin" - android:paddingBottom="@dimen/keyguard_security_view_margin" - android:gravity="center"> - </com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper> - </com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer> - - </com.android.internal.policy.impl.keyguard.MultiPaneChallengeLayout> -</com.android.internal.policy.impl.keyguard.KeyguardHostView> - diff --git a/core/res/res/layout-land/keyguard_status_area.xml b/core/res/res/layout-land/keyguard_status_area.xml deleted file mode 100644 index 51ee740..0000000 --- a/core/res/res/layout-land/keyguard_status_area.xml +++ /dev/null @@ -1,56 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2009, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License") -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<!-- This is a view that shows general status information in Keyguard. --> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/keyguard_status_area" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="end" - android:layout_marginTop="-16dp" - android:orientation="vertical"> - - <TextView - android:id="@+id/date" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="end" - android:layout_marginEnd="@dimen/kg_status_line_font_right_margin" - android:singleLine="true" - android:ellipsize="marquee" - android:textAppearance="?android:attr/textAppearanceMedium" - android:textSize="@dimen/kg_status_date_font_size" - /> - - <TextView - android:id="@+id/alarm_status" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="end" - android:layout_marginTop="28dp" - android:layout_marginEnd="@dimen/kg_status_line_font_right_margin" - android:singleLine="true" - android:ellipsize="marquee" - android:textAppearance="?android:attr/textAppearance" - android:textSize="@dimen/kg_status_line_font_size" - android:drawablePadding="4dip" - /> - -</LinearLayout>
\ No newline at end of file diff --git a/core/res/res/layout-land/keyguard_widget_pager.xml b/core/res/res/layout-land/keyguard_widget_pager.xml deleted file mode 100644 index 02c6d0e..0000000 --- a/core/res/res/layout-land/keyguard_widget_pager.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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. -*/ ---> - -<!-- This is the selector widget that allows the user to select an action. --> -<com.android.internal.policy.impl.keyguard.KeyguardWidgetCarousel - xmlns:androidprv="http://schemas.android.com/apk/res/android" - xmlns:android="http://schemas.android.com/apk/res/android" - android:paddingLeft="25dp" - android:paddingRight="25dp" - android:paddingTop="25dp" - android:paddingBottom="25dp" - android:clipToPadding="false" - androidprv:pageSpacing="10dp"> -</com.android.internal.policy.impl.keyguard.KeyguardWidgetCarousel>
\ No newline at end of file diff --git a/core/res/res/layout-port/keyguard_host_view.xml b/core/res/res/layout-port/keyguard_host_view.xml deleted file mode 100644 index fb25f9c..0000000 --- a/core/res/res/layout-port/keyguard_host_view.xml +++ /dev/null @@ -1,94 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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. -*/ ---> - -<!-- This is the host view that generally contains two sub views: the widget view - and the security view. --> -<com.android.internal.policy.impl.keyguard.KeyguardHostView - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:androidprv="http://schemas.android.com/apk/res/android" - android:id="@+id/keyguard_host_view" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:gravity="center_horizontal" - android:orientation="vertical"> - - <com.android.internal.policy.impl.keyguard.SlidingChallengeLayout - android:id="@+id/sliding_layout" - android:layout_width="match_parent" - android:layout_height="match_parent"> - - <FrameLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - androidprv:layout_childType="pageDeleteDropTarget"> - <include layout="@layout/keyguard_widget_remove_drop_target" - android:id="@+id/keyguard_widget_pager_delete_target" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="top|center_horizontal" /> - </FrameLayout> - - <FrameLayout - android:layout_width="match_parent" - android:layout_height="match_parent" - androidprv:layout_childType="widgets"> - <include layout="@layout/keyguard_widget_pager" - android:id="@+id/app_widget_container" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_gravity="center"/> - </FrameLayout> - - <View android:layout_width="match_parent" - android:layout_height="match_parent" - androidprv:layout_childType="scrim" - android:background="#99000000" /> - - <com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer - android:id="@+id/keyguard_security_container" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_maxHeight="@dimen/keyguard_security_height" - androidprv:layout_childType="challenge" - android:padding="0dp" - android:gravity="bottom|center_horizontal"> - <com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper - android:id="@+id/view_flipper" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:clipChildren="false" - android:clipToPadding="false" - android:paddingTop="@dimen/keyguard_security_view_margin" - android:gravity="center"> - </com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper> - </com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer> - - <ImageButton - android:layout_width="match_parent" - android:layout_height="@dimen/kg_widget_pager_bottom_padding" - androidprv:layout_childType="expandChallengeHandle" - android:focusable="true" - android:background="@null" - android:src="@drawable/keyguard_expand_challenge_handle" - android:scaleType="center" - android:contentDescription="@string/keyguard_accessibility_expand_lock_area" /> - - </com.android.internal.policy.impl.keyguard.SlidingChallengeLayout> -</com.android.internal.policy.impl.keyguard.KeyguardHostView> - diff --git a/core/res/res/layout-port/keyguard_status_area.xml b/core/res/res/layout-port/keyguard_status_area.xml deleted file mode 100644 index d274457..0000000 --- a/core/res/res/layout-port/keyguard_status_area.xml +++ /dev/null @@ -1,59 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2009, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License") -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<!-- This is a view that shows general status information in Keyguard. --> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/keyguard_status_area" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="right" - android:orientation="vertical"> - - <LinearLayout - android:orientation="horizontal" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="0dp" - android:layout_gravity="right"> - <TextView - android:id="@+id/date" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginEnd="@dimen/kg_status_line_font_right_margin" - android:singleLine="true" - android:ellipsize="marquee" - android:textAppearance="?android:attr/textAppearanceMedium" - android:textSize="@dimen/kg_status_date_font_size" - /> - - <TextView - android:id="@+id/alarm_status" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginEnd="@dimen/kg_status_line_font_right_margin" - android:singleLine="true" - android:ellipsize="marquee" - android:textAppearance="?android:attr/textAppearance" - android:textSize="@dimen/kg_status_line_font_size" - android:drawablePadding="4dip" - /> - </LinearLayout> - -</LinearLayout> diff --git a/core/res/res/layout-port/keyguard_widget_pager.xml b/core/res/res/layout-port/keyguard_widget_pager.xml deleted file mode 100644 index 7f22709..0000000 --- a/core/res/res/layout-port/keyguard_widget_pager.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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. -*/ ---> - -<!-- This is the selector widget that allows the user to select an action. --> -<com.android.internal.policy.impl.keyguard.KeyguardWidgetPager - xmlns:androidprv="http://schemas.android.com/apk/res/android" - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/app_widget_container" - android:paddingLeft="25dp" - android:paddingRight="25dp" - android:paddingTop="25dp" - android:paddingBottom="@dimen/kg_widget_pager_bottom_padding" - android:clipToPadding="false" - androidprv:pageSpacing="10dp"> -</com.android.internal.policy.impl.keyguard.KeyguardWidgetPager> diff --git a/core/res/res/layout-sw600dp-port/keyguard_host_view.xml b/core/res/res/layout-sw600dp-port/keyguard_host_view.xml deleted file mode 100644 index e3d577d..0000000 --- a/core/res/res/layout-sw600dp-port/keyguard_host_view.xml +++ /dev/null @@ -1,82 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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. -*/ ---> - -<!-- This is the host view that generally contains two sub views: the widget view - and the security view. --> -<com.android.internal.policy.impl.keyguard.KeyguardHostView - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:androidprv="http://schemas.android.com/apk/res/android" - android:id="@+id/keyguard_host_view" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="horizontal"> - - <com.android.internal.policy.impl.keyguard.MultiPaneChallengeLayout - android:id="@+id/multi_pane_challenge" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:clipChildren="false" - android:orientation="vertical"> - - <include layout="@layout/keyguard_widget_remove_drop_target" - android:id="@+id/keyguard_widget_pager_delete_target" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="top|center_horizontal" - androidprv:layout_childType="pageDeleteDropTarget" /> - - <include layout="@layout/keyguard_widget_pager" - android:id="@+id/app_widget_container" - android:layout_width="match_parent" - android:layout_height="match_parent" - androidprv:layout_centerWithinArea="0.5" - androidprv:layout_childType="widget" - androidprv:layout_maxWidth="480dp" - androidprv:layout_maxHeight="480dp" /> - - <include layout="@layout/keyguard_multi_user_selector"/> - - <View android:layout_width="match_parent" - android:layout_height="match_parent" - androidprv:layout_childType="scrim" - android:background="#99000000" /> - - <com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer - android:id="@+id/keyguard_security_container" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - androidprv:layout_centerWithinArea="0.5" - androidprv:layout_childType="challenge" - android:layout_gravity="center_horizontal|bottom"> - <com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper - android:id="@+id/view_flipper" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:clipChildren="false" - android:clipToPadding="false" - android:paddingLeft="@dimen/keyguard_security_view_margin" - android:paddingTop="@dimen/keyguard_security_view_margin" - android:paddingRight="@dimen/keyguard_security_view_margin" - android:paddingBottom="@dimen/keyguard_security_view_margin" - android:gravity="center"> - </com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper> - </com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer> - - </com.android.internal.policy.impl.keyguard.MultiPaneChallengeLayout> -</com.android.internal.policy.impl.keyguard.KeyguardHostView> diff --git a/core/res/res/layout-sw600dp-port/keyguard_status_area.xml b/core/res/res/layout-sw600dp-port/keyguard_status_area.xml deleted file mode 100644 index 88dd760..0000000 --- a/core/res/res/layout-sw600dp-port/keyguard_status_area.xml +++ /dev/null @@ -1,56 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2009, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License") -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<!-- This is a view that shows general status information in Keyguard. --> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/keyguard_status_area" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="end" - android:layout_marginTop="-16dp" - android:orientation="vertical"> - - <TextView - android:id="@+id/date" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="end" - android:layout_marginEnd="@dimen/kg_status_line_font_right_margin" - android:singleLine="true" - android:ellipsize="marquee" - android:textAppearance="?android:attr/textAppearanceMedium" - android:textSize="@dimen/kg_status_date_font_size" - /> - - <TextView - android:id="@+id/alarm_status" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="end" - android:layout_marginTop="28dp" - android:layout_marginEnd="@dimen/kg_status_line_font_right_margin" - android:singleLine="true" - android:ellipsize="marquee" - android:textAppearance="?android:attr/textAppearance" - android:textSize="@dimen/kg_status_line_font_size" - android:drawablePadding="4dip" - /> - -</LinearLayout> diff --git a/core/res/res/layout-sw600dp/keyguard_glow_pad_container.xml b/core/res/res/layout-sw600dp/keyguard_glow_pad_container.xml deleted file mode 100644 index 930b14e..0000000 --- a/core/res/res/layout-sw600dp/keyguard_glow_pad_container.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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. -*/ ---> -<merge xmlns:android="http://schemas.android.com/apk/res/android"> - <include layout="@layout/keyguard_glow_pad_view" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" /> -</merge>
\ No newline at end of file diff --git a/core/res/res/layout-sw600dp/keyguard_navigation.xml b/core/res/res/layout-sw600dp/keyguard_navigation.xml deleted file mode 100644 index 2e6fa37..0000000 --- a/core/res/res/layout-sw600dp/keyguard_navigation.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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. -*/ ---> -<merge xmlns:android="http://schemas.android.com/apk/res/android"> - <include layout="@layout/default_navigation" /> -</merge> diff --git a/core/res/res/layout-sw600dp/keyguard_sim_puk_pin_navigation.xml b/core/res/res/layout-sw600dp/keyguard_sim_puk_pin_navigation.xml deleted file mode 100644 index 2e6fa37..0000000 --- a/core/res/res/layout-sw600dp/keyguard_sim_puk_pin_navigation.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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. -*/ ---> -<merge xmlns:android="http://schemas.android.com/apk/res/android"> - <include layout="@layout/default_navigation" /> -</merge> diff --git a/core/res/res/layout-sw600dp/keyguard_transport_control.xml b/core/res/res/layout-sw600dp/keyguard_transport_control.xml deleted file mode 100644 index f864339..0000000 --- a/core/res/res/layout-sw600dp/keyguard_transport_control.xml +++ /dev/null @@ -1,111 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2011 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<!-- *** Note *** This should mirror the file in layout/ with the exception of the background set - here for adding a drop shadow on tablets. --> - -<com.android.internal.widget.TransportControlView - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/transport_controls" - android:background="@drawable/transportcontrol_bg"> - - <!-- FrameLayout used as scrim to show between album art and buttons --> - <FrameLayout - android:layout_width="match_parent" - android:layout_height="match_parent" - android:foreground="@drawable/ic_lockscreen_player_background"> - <!-- We use ImageView for its cropping features, otherwise could be android:background --> - <ImageView - android:id="@+id/albumart" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_gravity="fill" - android:scaleType="centerCrop" - android:adjustViewBounds="false" - /> - </FrameLayout> - - <LinearLayout - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_gravity="bottom"> - <TextView - android:id="@+id/title" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="8dip" - android:layout_marginStart="16dip" - android:layout_marginEnd="16dip" - android:gravity="center_horizontal" - android:singleLine="true" - android:ellipsize="end" - android:textAppearance="?android:attr/textAppearanceMedium" - /> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - android:layout_marginTop="5dip"> - <FrameLayout - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="1"> - <ImageView - android:id="@+id/btn_prev" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:src="@drawable/ic_media_previous" - android:clickable="true" - android:background="?android:attr/selectableItemBackground" - android:padding="10dip" - android:contentDescription="@string/lockscreen_transport_prev_description"/> - </FrameLayout> - <FrameLayout - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="1"> - <ImageView - android:id="@+id/btn_play" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:clickable="true" - android:src="@drawable/ic_media_play" - android:background="?android:attr/selectableItemBackground" - android:padding="10dip" - android:contentDescription="@string/lockscreen_transport_play_description"/> - </FrameLayout> - <FrameLayout - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="1"> - <ImageView - android:id="@+id/btn_next" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:clickable="true" - android:src="@drawable/ic_media_next" - android:background="?android:attr/selectableItemBackground" - android:padding="10dip" - android:contentDescription="@string/lockscreen_transport_next_description"/> - </FrameLayout> - </LinearLayout> - </LinearLayout> - -</com.android.internal.widget.TransportControlView> diff --git a/core/res/res/layout/keyguard_account_view.xml b/core/res/res/layout/keyguard_account_view.xml deleted file mode 100644 index fa36371..0000000 --- a/core/res/res/layout/keyguard_account_view.xml +++ /dev/null @@ -1,87 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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.policy.impl.keyguard.KeyguardAccountView - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/keyguard_account_view" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_maxWidth="@dimen/keyguard_security_width" - android:layout_maxHeight="@dimen/keyguard_security_height" - android:orientation="vertical"> - - <include layout="@layout/keyguard_message_area" - android:layout_width="match_parent" - android:layout_height="wrap_content" /> - - <RelativeLayout - android:layout_width="match_parent" - android:layout_height="0dip" - android:layout_weight="1"> - - <EditText - android:id="@+id/login" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="8dip" - android:layout_marginStart="7dip" - android:layout_marginEnd="7dip" - android:layout_alignParentTop="true" - android:hint="@string/kg_login_username_hint" - android:inputType="textEmailAddress" - /> - - <EditText - android:id="@+id/password" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_below="@id/login" - android:layout_toLeftOf="@+id/ok" - android:layout_marginTop="15dip" - android:layout_marginStart="7dip" - android:layout_marginEnd="7dip" - android:inputType="textPassword" - android:hint="@string/kg_login_password_hint" - android:nextFocusRight="@+id/ok" - android:nextFocusDown="@+id/ok" - /> - - <!-- ok below password, aligned to right of screen --> - <Button - android:id="@+id/ok" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_margin="7dip" - android:layout_alignParentEnd="true" - android:layout_below="@id/login" - android:text="@string/kg_login_submit_button" - /> - - </RelativeLayout> - - <!-- no room for ECA on this screen right now - <include layout="@layout/keyguard_eca" - android:id="@+id/keyguard_selector_fade_container" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical" - android:layout_gravity="bottom|center_horizontal" - android:gravity="center_horizontal" /> - --> - -</com.android.internal.policy.impl.keyguard.KeyguardAccountView> diff --git a/core/res/res/layout/keyguard_add_widget.xml b/core/res/res/layout/keyguard_add_widget.xml deleted file mode 100644 index d043fdb..0000000 --- a/core/res/res/layout/keyguard_add_widget.xml +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2009, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License") -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<!-- This is a view that shows general status information in Keyguard. --> -<com.android.internal.policy.impl.keyguard.KeyguardWidgetFrame - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/keyguard_add_widget" - android:layout_width="match_parent" - android:layout_height="match_parent" - > - <FrameLayout - android:layout_width="match_parent" - android:layout_height="match_parent" - android:contentDescription="@string/keyguard_accessibility_widget_empty_slot" - > - <ImageView - android:id="@+id/keyguard_add_widget_view" - android:clickable="true" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:padding="24dp" - android:src="@drawable/keyguard_add_widget_button" - android:contentDescription="@string/keyguard_accessibility_add_widget"/> - </FrameLayout> -</com.android.internal.policy.impl.keyguard.KeyguardWidgetFrame> diff --git a/core/res/res/layout/keyguard_emergency_carrier_area.xml b/core/res/res/layout/keyguard_emergency_carrier_area.xml deleted file mode 100644 index b8a7654..0000000 --- a/core/res/res/layout/keyguard_emergency_carrier_area.xml +++ /dev/null @@ -1,76 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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. -*/ ---> - -<!-- This contains emergency call button and carrier as shared by pin/pattern/password screens --> -<com.android.internal.policy.impl.keyguard.EmergencyCarrierArea - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical" - android:gravity="center" - android:layout_gravity="center_horizontal" - android:layout_alignParentBottom="true" - android:clickable="true"> - - <com.android.internal.policy.impl.keyguard.CarrierText - android:id="@+id/carrier_text" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:singleLine="true" - android:ellipsize="marquee" - android:textAppearance="?android:attr/textAppearanceMedium" - android:textSize="@dimen/kg_status_line_font_size" - android:textColor="?android:attr/textColorSecondary"/> - - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="-10dip" - style="?android:attr/buttonBarStyle" - android:orientation="horizontal" - android:gravity="center" - android:weightSum="2"> - - <com.android.internal.policy.impl.keyguard.EmergencyButton - android:id="@+id/emergency_call_button" - android:layout_width="0dip" - android:layout_height="wrap_content" - android:layout_weight="1" - android:drawableLeft="@*android:drawable/lockscreen_emergency_button" - android:text="@string/kg_emergency_call_label" - style="?android:attr/buttonBarButtonStyle" - android:textAppearance="?android:attr/textAppearanceMedium" - android:textSize="@dimen/kg_status_line_font_size" - android:textColor="?android:attr/textColorSecondary" - android:drawablePadding="8dip" /> - - <Button android:id="@+id/forgot_password_button" - android:layout_width="0dip" - android:layout_height="wrap_content" - android:layout_weight="1" - android:drawableLeft="@*android:drawable/lockscreen_forgot_password_button" - style="?android:attr/buttonBarButtonStyle" - android:textSize="@dimen/kg_status_line_font_size" - android:textColor="?android:attr/textColorSecondary" - android:textAppearance="?android:attr/textAppearanceMedium" - android:drawablePadding="8dip" - android:visibility="gone"/> - </LinearLayout> - -</com.android.internal.policy.impl.keyguard.EmergencyCarrierArea> diff --git a/core/res/res/layout/keyguard_emergency_carrier_area_empty.xml b/core/res/res/layout/keyguard_emergency_carrier_area_empty.xml deleted file mode 100644 index 2f4adae..0000000 --- a/core/res/res/layout/keyguard_emergency_carrier_area_empty.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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. -*/ ---> - -<!-- This is a blank layout to simplify implementation on landscape on phones - it is referenced indirectly by keyguard_eca --> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="0dip" - android:layout_height="0dip" - android:orientation="vertical" - android:gravity="center" - android:layout_gravity="center_horizontal" - android:layout_alignParentBottom="true"> - -</LinearLayout> diff --git a/core/res/res/layout/keyguard_face_unlock_view.xml b/core/res/res/layout/keyguard_face_unlock_view.xml deleted file mode 100644 index c9f1176..0000000 --- a/core/res/res/layout/keyguard_face_unlock_view.xml +++ /dev/null @@ -1,78 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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. -*/ ---> - -<!-- This is the screen that allows the user to unlock by showing their face. --> -<com.android.internal.policy.impl.keyguard.KeyguardFaceUnlockView - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/keyguard_face_unlock_view" - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_maxWidth="@dimen/keyguard_security_width" - android:layout_maxHeight="@dimen/keyguard_security_height" - android:contentDescription="@string/keyguard_accessibility_face_unlock"> - - <include layout="@layout/keyguard_message_area" - android:layout_width="match_parent" - android:layout_height="wrap_content" - /> - - <FrameLayout - android:id="@+id/keyguard_bouncer_frame" - android:background="@*android:drawable/kg_bouncer_bg_white" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1" - > - <com.android.internal.widget.FaceUnlockView - android:id="@+id/face_unlock_area_view" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_gravity="center_horizontal" - android:background="@*android:drawable/intro_bg" - android:gravity="center"> - - <View - android:id="@+id/spotlightMask" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@*android:color/facelock_spotlight_mask" - /> - - <ImageButton - android:id="@+id/face_unlock_cancel_button" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:padding="5dip" - android:layout_alignParentTop="true" - android:layout_alignParentEnd="true" - android:background="#00000000" - android:src="@*android:drawable/ic_facial_backup" - /> - </com.android.internal.widget.FaceUnlockView> - </FrameLayout> - - <include layout="@layout/keyguard_eca" - android:id="@+id/keyguard_selector_fade_container" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical" - android:layout_gravity="bottom|center_horizontal" - android:gravity="center_horizontal" /> -</com.android.internal.policy.impl.keyguard.KeyguardFaceUnlockView> diff --git a/core/res/res/layout/keyguard_glow_pad_container.xml b/core/res/res/layout/keyguard_glow_pad_container.xml deleted file mode 100644 index d86707f..0000000 --- a/core/res/res/layout/keyguard_glow_pad_container.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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. -*/ ---> - -<merge xmlns:android="http://schemas.android.com/apk/res/android"> - <include layout="@layout/keyguard_glow_pad_view" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="bottom|center_horizontal" - android:layout_marginBottom="-60dp"/> -</merge>
\ No newline at end of file diff --git a/core/res/res/layout/keyguard_glow_pad_view.xml b/core/res/res/layout/keyguard_glow_pad_view.xml deleted file mode 100644 index cfd8160..0000000 --- a/core/res/res/layout/keyguard_glow_pad_view.xml +++ /dev/null @@ -1,46 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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. -*/ ---> - -<!-- This is the selector widget that allows the user to select an action. --> -<com.android.internal.widget.multiwaveview.GlowPadView - xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android" - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/glow_pad_view" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:orientation="horizontal" - android:gravity="@integer/kg_selector_gravity" - android:contentDescription="@string/keyguard_accessibility_slide_area" - - prvandroid:targetDrawables="@array/lockscreen_targets_unlock_only" - prvandroid:targetDescriptions="@array/lockscreen_target_descriptions_unlock_only" - prvandroid:directionDescriptions="@*android:array/lockscreen_direction_descriptions" - prvandroid:handleDrawable="@*android:drawable/ic_lockscreen_handle" - prvandroid:outerRingDrawable="@*android:drawable/ic_lockscreen_outerring" - prvandroid:outerRadius="@*android:dimen/glowpadview_target_placement_radius" - prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius" - prvandroid:snapMargin="@*android:dimen/glowpadview_snap_margin" - prvandroid:firstItemOffset="@integer/kg_glowpad_rotation_offset" - prvandroid:magneticTargets="true" - prvandroid:feedbackCount="1" - prvandroid:vibrationDuration="20" - prvandroid:glowRadius="@*android:dimen/glowpadview_glow_radius" - prvandroid:pointDrawable="@*android:drawable/ic_lockscreen_glowdot" - prvandroid:allowScaling="true" /> diff --git a/core/res/res/layout/keyguard_message_area.xml b/core/res/res/layout/keyguard_message_area.xml deleted file mode 100644 index 37463cf..0000000 --- a/core/res/res/layout/keyguard_message_area.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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. -*/ ---> - -<!-- This contains emergency call button and carrier as shared by pin/pattern/password screens --> -<com.android.internal.policy.impl.keyguard.KeyguardMessageArea - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="center" - android:id="@+id/keyguard_message_area" - android:singleLine="true" - android:ellipsize="marquee" - android:textAppearance="?android:attr/textAppearance" - android:textSize="@dimen/kg_status_line_font_size" - android:textColor="?android:attr/textColorSecondary" - android:clickable="true" /> - diff --git a/core/res/res/layout/keyguard_message_area_large.xml b/core/res/res/layout/keyguard_message_area_large.xml deleted file mode 100644 index 584cec4..0000000 --- a/core/res/res/layout/keyguard_message_area_large.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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. -*/ ---> - -<!-- This contains emergency call button and carrier as shared by pin/pattern/password screens --> -<com.android.internal.policy.impl.keyguard.KeyguardMessageArea - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="center" - android:id="@+id/keyguard_message_area" - android:maxLines="4" - android:textAppearance="?android:attr/textAppearance" - android:textSize="@dimen/kg_status_line_font_size" - android:textColor="?android:attr/textColorSecondary" /> - diff --git a/core/res/res/layout/keyguard_multi_user_avatar.xml b/core/res/res/layout/keyguard_multi_user_avatar.xml deleted file mode 100644 index 2d8f02d..0000000 --- a/core/res/res/layout/keyguard_multi_user_avatar.xml +++ /dev/null @@ -1,45 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2009, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License") -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<!-- This is a view that shows general status information in Keyguard. --> -<com.android.internal.policy.impl.keyguard.KeyguardMultiUserAvatar - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="@dimen/keyguard_avatar_size" - android:layout_height="@dimen/keyguard_avatar_size" - android:background="#00000000" - android:gravity="center_horizontal"> - <ImageView - android:id="@+id/keyguard_user_avatar" - android:scaleType="center" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_gravity="center"/> - <TextView - android:id="@+id/keyguard_user_name" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_gravity="bottom" - android:gravity="center" - android:textSize="@dimen/keyguard_avatar_name_size" - android:textColor="#ffffff" - android:singleLine="true" - android:ellipsize="end" - android:paddingLeft="2dp" - android:paddingRight="2dp" /> -</com.android.internal.policy.impl.keyguard.KeyguardMultiUserAvatar> diff --git a/core/res/res/layout/keyguard_multi_user_selector.xml b/core/res/res/layout/keyguard_multi_user_selector.xml deleted file mode 100644 index ee01285..0000000 --- a/core/res/res/layout/keyguard_multi_user_selector.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2009, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License") -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> -<com.android.internal.policy.impl.keyguard.KeyguardMultiUserSelectorView - xmlns:androidprv="http://schemas.android.com/apk/res/android" - xmlns:android="http://schemas.android.com/apk/res/android" - androidprv:layout_childType="userSwitcher" - android:id="@+id/keyguard_user_selector" - android:orientation="horizontal" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_gravity="bottom" - android:contentDescription="@*android:string/keyguard_accessibility_user_selector" - android:visibility="gone"> - - <com.android.internal.policy.impl.keyguard.KeyguardLinearLayout - android:id="@+id/keyguard_users_grid" - android:orientation="horizontal" - android:layout_width="wrap_content" - android:layout_marginBottom="@dimen/keyguard_muliuser_selector_margin" - android:layout_height="@dimen/keyguard_avatar_size" - android:layout_gravity="center|bottom" /> - -</com.android.internal.policy.impl.keyguard.KeyguardMultiUserSelectorView> diff --git a/core/res/res/layout/keyguard_multi_user_selector_widget.xml b/core/res/res/layout/keyguard_multi_user_selector_widget.xml deleted file mode 100644 index fc126fe..0000000 --- a/core/res/res/layout/keyguard_multi_user_selector_widget.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2009, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License") -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<!-- This is a view that shows general status information in Keyguard. --> -<com.android.internal.policy.impl.keyguard.KeyguardWidgetFrame - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/keyguard_multi_user_selector" - android:layout_width="match_parent" - android:layout_height="match_parent"> -</com.android.internal.policy.impl.keyguard.KeyguardWidgetFrame>
\ No newline at end of file diff --git a/core/res/res/layout/keyguard_password_view.xml b/core/res/res/layout/keyguard_password_view.xml deleted file mode 100644 index aab54c3..0000000 --- a/core/res/res/layout/keyguard_password_view.xml +++ /dev/null @@ -1,104 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2008, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License") -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> -<com.android.internal.policy.impl.keyguard.KeyguardPasswordView - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/keyguard_password_view" - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_maxWidth="@dimen/keyguard_security_width" - android:layout_maxHeight="@dimen/keyguard_security_height" - android:gravity="bottom" - android:contentDescription="@string/keyguard_accessibility_password_unlock" - > - - <Space - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1" - /> - - <include layout="@layout/keyguard_message_area" - android:layout_width="match_parent" - android:layout_height="wrap_content" /> - - <!-- Password entry field --> - <!-- Note: the entire container is styled to look like the edit field, - since the backspace/IME switcher looks better inside --> - <FrameLayout - android:id="@+id/keyguard_bouncer_frame" - android:background="@*android:drawable/kg_bouncer_bg_white" - android:layout_height="wrap_content" - android:layout_width="match_parent" - > - <LinearLayout - android:layout_height="wrap_content" - android:layout_width="match_parent" - android:orientation="horizontal" - android:background="#70000000" - android:layout_marginTop="8dp" - android:layout_marginBottom="8dp" - > - - <EditText android:id="@+id/passwordEntry" - android:layout_width="0dip" - android:layout_height="wrap_content" - android:layout_weight="1" - android:gravity="center_horizontal" - android:layout_gravity="center_vertical" - android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left" - android:singleLine="true" - android:textStyle="normal" - android:inputType="textPassword" - android:textSize="36sp" - android:background="@null" - android:textAppearance="?android:attr/textAppearanceMedium" - android:textColor="#ffffffff" - android:imeOptions="flagForceAscii|actionDone" - /> - - <ImageView android:id="@+id/switch_ime_button" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:src="@*android:drawable/ic_lockscreen_ime" - android:clickable="true" - android:padding="8dip" - android:layout_gravity="center" - android:background="?android:attr/selectableItemBackground" - android:visibility="gone" - /> - - </LinearLayout> - </FrameLayout> - - <Space - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1" - /> - - <include layout="@layout/keyguard_eca" - android:id="@+id/keyguard_selector_fade_container" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical" - android:layout_gravity="bottom|center_horizontal" - android:gravity="center_horizontal" /> - -</com.android.internal.policy.impl.keyguard.KeyguardPasswordView> diff --git a/core/res/res/layout/keyguard_pattern_view.xml b/core/res/res/layout/keyguard_pattern_view.xml deleted file mode 100644 index 1bd3e4e..0000000 --- a/core/res/res/layout/keyguard_pattern_view.xml +++ /dev/null @@ -1,78 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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. -*/ ---> - -<!-- This is the screen that shows the 9 circle unlock widget and instructs - the user how to unlock their device, or make an emergency call. This - is the portrait layout. --> -<com.android.internal.policy.impl.keyguard.KeyguardPatternView - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/keyguard_pattern_view" - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_maxWidth="@dimen/keyguard_security_width" - android:layout_maxHeight="@dimen/keyguard_security_height" - android:gravity="center_horizontal" - android:contentDescription="@string/keyguard_accessibility_pattern_unlock"> - - <FrameLayout - android:layout_width="match_parent" - android:layout_height="match_parent"> - - <LinearLayout - android:layout_height="wrap_content" - android:layout_width="wrap_content" - android:orientation="vertical" - android:layout_gravity="center"> - - <include layout="@layout/keyguard_message_area" - android:layout_width="match_parent" - android:layout_height="wrap_content" - /> - - <FrameLayout - android:id="@+id/keyguard_bouncer_frame" - android:background="@*android:drawable/kg_bouncer_bg_white" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1" - > - <com.android.internal.widget.LockPatternView - android:id="@+id/lockPatternView" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_weight="1" - android:layout_marginEnd="8dip" - android:layout_marginBottom="4dip" - android:layout_marginStart="8dip" - android:layout_gravity="center_horizontal" - android:gravity="center" - android:contentDescription="@string/keyguard_accessibility_pattern_area" /> - </FrameLayout> - <include layout="@layout/keyguard_eca" - android:id="@+id/keyguard_selector_fade_container" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical" - android:layout_gravity="bottom|center_horizontal" - android:gravity="center_horizontal" /> - </LinearLayout> - </FrameLayout> - -</com.android.internal.policy.impl.keyguard.KeyguardPatternView> diff --git a/core/res/res/layout/keyguard_pin_view.xml b/core/res/res/layout/keyguard_pin_view.xml deleted file mode 100644 index 6a3b9e6..0000000 --- a/core/res/res/layout/keyguard_pin_view.xml +++ /dev/null @@ -1,224 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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.policy.impl.keyguard.KeyguardPINView - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:androidprv="http://schemas.android.com/apk/res/android" - android:id="@+id/keyguard_pin_view" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_maxWidth="@dimen/keyguard_security_width" - android:layout_maxHeight="@dimen/keyguard_security_height" - android:orientation="vertical" - android:contentDescription="@string/keyguard_accessibility_pin_unlock" - > - <include layout="@layout/keyguard_message_area" - android:layout_width="match_parent" - android:layout_height="wrap_content" - /> - <LinearLayout - android:id="@+id/keyguard_bouncer_frame" - android:background="@*android:drawable/kg_bouncer_bg_white" - android:layout_width="match_parent" - android:layout_height="0dp" - android:orientation="vertical" - android:layout_weight="1" - android:layoutDirection="ltr" - > - <LinearLayout - android:layout_width="match_parent" - android:layout_height="0dp" - android:orientation="horizontal" - android:layout_weight="1" - > - <TextView android:id="@+id/pinEntry" - android:editable="true" - android:layout_width="0dip" - android:layout_height="match_parent" - android:layout_weight="1" - android:gravity="center" - android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left" - android:singleLine="true" - android:cursorVisible="false" - android:background="@null" - android:textAppearance="@style/TextAppearance.NumPadKey" - android:imeOptions="flagForceAscii|actionDone" - /> - <ImageButton android:id="@+id/delete_button" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:gravity="center_vertical" - android:src="@*android:drawable/ic_input_delete" - android:clickable="true" - android:paddingTop="8dip" - android:paddingBottom="8dip" - android:paddingLeft="24dp" - android:paddingRight="24dp" - android:background="?android:attr/selectableItemBackground" - android:contentDescription="@string/keyboardview_keycode_delete" - /> - </LinearLayout> - <View - android:layout_width="wrap_content" - android:layout_height="1dp" - android:background="#55FFFFFF" - /> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1" - android:orientation="horizontal" - > - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key1" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="1" - /> - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key2" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="2" - /> - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key3" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="3" - /> - </LinearLayout> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1" - android:orientation="horizontal" - > - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key4" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="4" - /> - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key5" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="5" - /> - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key6" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="6" - /> - </LinearLayout> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="0dp" - android:orientation="horizontal" - android:layout_weight="1" - > - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key7" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="7" - /> - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key8" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="8" - /> - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key9" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="9" - /> - </LinearLayout> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1" - android:orientation="horizontal" - > - <Space - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - /> - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key0" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="0" - /> - <ImageButton - android:id="@+id/key_enter" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - android:paddingRight="30dp" - android:src="@drawable/sym_keyboard_return_holo" - android:contentDescription="@string/keyboardview_keycode_enter" - /> - </LinearLayout> - </LinearLayout> - <include layout="@layout/keyguard_eca" - android:id="@+id/keyguard_selector_fade_container" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical" - android:layout_gravity="bottom|center_horizontal" - android:gravity="center_horizontal" /> - -</com.android.internal.policy.impl.keyguard.KeyguardPINView> diff --git a/core/res/res/layout/keyguard_selector_view.xml b/core/res/res/layout/keyguard_selector_view.xml deleted file mode 100644 index dfacb6a..0000000 --- a/core/res/res/layout/keyguard_selector_view.xml +++ /dev/null @@ -1,64 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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. -*/ ---> - -<!-- This is the selector widget that allows the user to select an action. --> -<com.android.internal.policy.impl.keyguard.KeyguardSelectorView - xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android" - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/keyguard_selector_view" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_maxWidth="420dp" - android:layout_maxHeight="@dimen/keyguard_security_height" - android:clipChildren="false" - android:clipToPadding="false" - android:orientation="vertical" - android:contentDescription="@string/keyguard_accessibility_slide_unlock"> - - <FrameLayout - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_gravity="center" - android:clipChildren="false" - android:clipToPadding="false" - android:gravity="center"> - - <include layout="@layout/keyguard_message_area" - android:layout_width="match_parent" - android:layout_height="wrap_content" /> - - <View - android:id="@+id/keyguard_selector_view_frame" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_marginLeft="16dp" - android:layout_marginRight="16dp" - android:background="@*android:drawable/kg_bouncer_bg_white"/> - - <include layout="@layout/keyguard_glow_pad_container" /> - - <include layout="@layout/keyguard_eca" - android:id="@+id/keyguard_selector_fade_container" - android:layout_width="match_parent" - android:layout_height="48dp" - android:layout_gravity="bottom|center_horizontal" /> - </FrameLayout> - -</com.android.internal.policy.impl.keyguard.KeyguardSelectorView> - diff --git a/core/res/res/layout/keyguard_sim_pin_view.xml b/core/res/res/layout/keyguard_sim_pin_view.xml deleted file mode 100644 index 6e6fe08..0000000 --- a/core/res/res/layout/keyguard_sim_pin_view.xml +++ /dev/null @@ -1,230 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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. -*/ ---> -<!-- This is the SIM PIN view that allows the user to enter a SIM PIN to unlock the device. --> -<com.android.internal.policy.impl.keyguard.KeyguardSimPinView - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:androidprv="http://schemas.android.com/apk/res/android" - android:id="@+id/keyguard_sim_pin_view" - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_maxWidth="@dimen/keyguard_security_width" - android:layout_maxHeight="@dimen/keyguard_security_height" - android:gravity="center_horizontal"> - - <ImageView - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:src="@drawable/ic_lockscreen_sim"/> - - <include layout="@layout/keyguard_message_area" - android:layout_width="match_parent" - android:layout_height="wrap_content" - /> - <LinearLayout - android:id="@+id/keyguard_bouncer_frame" - android:background="@*android:drawable/kg_bouncer_bg_white" - android:layout_width="match_parent" - android:layout_height="0dp" - android:orientation="vertical" - android:layout_weight="1" - android:layoutDirection="ltr" - > - <LinearLayout - android:layout_width="match_parent" - android:layout_height="0dp" - android:orientation="horizontal" - android:layout_weight="1" - > - <TextView android:id="@+id/pinEntry" - android:editable="true" - android:layout_width="0dip" - android:layout_height="match_parent" - android:layout_weight="1" - android:gravity="center" - android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left" - android:singleLine="true" - android:cursorVisible="false" - android:background="@null" - android:textAppearance="@style/TextAppearance.NumPadKey" - android:imeOptions="flagForceAscii|actionDone" - /> - <ImageButton android:id="@+id/delete_button" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:gravity="center_vertical" - android:src="@*android:drawable/ic_input_delete" - android:clickable="true" - android:paddingTop="8dip" - android:paddingBottom="8dip" - android:paddingLeft="24dp" - android:paddingRight="24dp" - android:background="?android:attr/selectableItemBackground" - android:contentDescription="@string/keyboardview_keycode_delete" - /> - </LinearLayout> - <View - android:layout_width="wrap_content" - android:layout_height="1dp" - android:background="#55FFFFFF" - /> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1" - android:orientation="horizontal" - > - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key1" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="1" - /> - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key2" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="2" - /> - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key3" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="3" - /> - </LinearLayout> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1" - android:orientation="horizontal" - > - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key4" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="4" - /> - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key5" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="5" - /> - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key6" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="6" - /> - </LinearLayout> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="0dp" - android:orientation="horizontal" - android:layout_weight="1" - > - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key7" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="7" - /> - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key8" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="8" - /> - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key9" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="9" - /> - </LinearLayout> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1" - android:orientation="horizontal" - > - <Space - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - /> - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key0" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="0" - /> - <ImageButton - android:id="@+id/key_enter" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - android:paddingRight="30dp" - android:src="@drawable/sym_keyboard_return_holo" - android:contentDescription="@string/keyboardview_keycode_enter" - /> - </LinearLayout> - </LinearLayout> - - <include layout="@layout/keyguard_eca" - android:id="@+id/keyguard_selector_fade_container" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical" - android:layout_gravity="bottom|center_horizontal" - android:gravity="center_horizontal" /> - -</com.android.internal.policy.impl.keyguard.KeyguardSimPinView> diff --git a/core/res/res/layout/keyguard_sim_puk_pin_account_navigation.xml b/core/res/res/layout/keyguard_sim_puk_pin_account_navigation.xml deleted file mode 100644 index 2e6fa37..0000000 --- a/core/res/res/layout/keyguard_sim_puk_pin_account_navigation.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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. -*/ ---> -<merge xmlns:android="http://schemas.android.com/apk/res/android"> - <include layout="@layout/default_navigation" /> -</merge> diff --git a/core/res/res/layout/keyguard_sim_puk_view.xml b/core/res/res/layout/keyguard_sim_puk_view.xml deleted file mode 100644 index 0412fdc..0000000 --- a/core/res/res/layout/keyguard_sim_puk_view.xml +++ /dev/null @@ -1,230 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2008, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License") -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> -<!-- This is the SIM PUK view that allows the user to recover their device by entering the - carrier-provided PUK code and entering a new SIM PIN for it. --> -<com.android.internal.policy.impl.keyguard.KeyguardSimPukView - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:androidprv="http://schemas.android.com/apk/res/android" - android:id="@+id/keyguard_sim_puk_view" - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_maxWidth="@dimen/keyguard_security_width" - android:layout_maxHeight="@dimen/keyguard_security_height" - android:gravity="center_horizontal"> - - <ImageView - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:src="@drawable/ic_lockscreen_sim"/> - - <include layout="@layout/keyguard_message_area" - android:layout_width="match_parent" - android:layout_height="wrap_content" - /> - <LinearLayout - android:id="@+id/keyguard_bouncer_frame" - android:background="@*android:drawable/kg_bouncer_bg_white" - android:layout_width="match_parent" - android:layout_height="0dp" - android:orientation="vertical" - android:layout_weight="1" - android:layoutDirection="ltr" - > - <LinearLayout - android:layout_width="match_parent" - android:layout_height="0dp" - android:orientation="horizontal" - android:layout_weight="1" - > - <TextView android:id="@+id/pinEntry" - android:editable="true" - android:layout_width="0dip" - android:layout_height="match_parent" - android:layout_weight="1" - android:gravity="center" - android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left" - android:singleLine="true" - android:cursorVisible="false" - android:background="@null" - android:textAppearance="@style/TextAppearance.NumPadKey" - android:imeOptions="flagForceAscii|actionDone" - /> - <ImageButton android:id="@+id/delete_button" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:gravity="center_vertical" - android:src="@*android:drawable/ic_input_delete" - android:clickable="true" - android:paddingTop="8dip" - android:paddingBottom="8dip" - android:paddingLeft="24dp" - android:paddingRight="24dp" - android:background="?android:attr/selectableItemBackground" - android:contentDescription="@string/keyboardview_keycode_delete" - /> - </LinearLayout> - <View - android:layout_width="wrap_content" - android:layout_height="1dp" - android:background="#55FFFFFF" - /> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1" - android:orientation="horizontal" - > - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key1" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="1" - /> - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key2" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="2" - /> - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key3" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="3" - /> - </LinearLayout> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1" - android:orientation="horizontal" - > - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key4" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="4" - /> - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key5" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="5" - /> - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key6" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="6" - /> - </LinearLayout> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="0dp" - android:orientation="horizontal" - android:layout_weight="1" - > - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key7" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="7" - /> - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key8" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="8" - /> - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key9" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="9" - /> - </LinearLayout> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1" - android:orientation="horizontal" - > - <Space - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - /> - <view class="com.android.internal.policy.impl.keyguard.NumPadKey" - android:id="@+id/key0" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - androidprv:textView="@+id/pinEntry" - androidprv:digit="0" - /> - <ImageButton - android:id="@+id/key_enter" - style="@style/Widget.Button.NumPadKey" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_weight="1" - android:paddingRight="30dp" - android:src="@drawable/sym_keyboard_return_holo" - android:contentDescription="@string/keyboardview_keycode_enter" - /> - </LinearLayout> - </LinearLayout> - - <include layout="@layout/keyguard_eca" - android:id="@+id/keyguard_selector_fade_container" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical" - android:layout_gravity="bottom|center_horizontal" - android:gravity="center_horizontal" /> -</com.android.internal.policy.impl.keyguard.KeyguardSimPukView> diff --git a/core/res/res/layout/keyguard_status_view.xml b/core/res/res/layout/keyguard_status_view.xml deleted file mode 100644 index 9e36df3..0000000 --- a/core/res/res/layout/keyguard_status_view.xml +++ /dev/null @@ -1,67 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2009, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License") -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<!-- This is a view that shows general status information in Keyguard. --> -<com.android.internal.policy.impl.keyguard.KeyguardWidgetFrame - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/keyguard_status_view" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_maxWidth="@dimen/keyguard_security_width" - android:layout_maxHeight="@dimen/keyguard_security_height" - android:gravity="center_horizontal"> - - <com.android.internal.policy.impl.keyguard.KeyguardStatusView - android:id="@+id/keyguard_status_view_face_palm" - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:gravity="center_horizontal|top" - android:contentDescription="@android:string/keyguard_accessibility_status"> - - <LinearLayout android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_gravity="center_horizontal|top" - android:orientation="vertical" - android:focusable="true"> - <com.android.internal.policy.impl.keyguard.ClockView - android:id="@+id/clock_view" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginEnd="@dimen/kg_status_line_font_right_margin" - android:layout_gravity="right"> - - <TextView android:id="@+id/clock_text" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:singleLine="true" - android:ellipsize="none" - android:textSize="@dimen/kg_status_clock_font_size" - android:textAppearance="?android:attr/textAppearanceMedium" - android:textColor="#ffffffff" - android:drawablePadding="2dip" - /> - - </com.android.internal.policy.impl.keyguard.ClockView> - - <include layout="@layout/keyguard_status_area" /> - </LinearLayout> - - </com.android.internal.policy.impl.keyguard.KeyguardStatusView> -</com.android.internal.policy.impl.keyguard.KeyguardWidgetFrame> diff --git a/core/res/res/layout/keyguard_transport_control_view.xml b/core/res/res/layout/keyguard_transport_control_view.xml deleted file mode 100644 index 532322c..0000000 --- a/core/res/res/layout/keyguard_transport_control_view.xml +++ /dev/null @@ -1,112 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2011 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<!-- This is a view to control music playback in keyguard. --> -<com.android.internal.policy.impl.keyguard.KeyguardTransportControlView - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:gravity="center_horizontal" - android:id="@+id/keyguard_transport_control"> - - <!-- FrameLayout used as scrim to show between album art and buttons --> - <FrameLayout - android:layout_width="match_parent" - android:layout_height="match_parent" - android:foreground="@*android:drawable/ic_lockscreen_player_background" - android:contentDescription="@*android:string/keygaurd_accessibility_media_controls"> - <!-- Use ImageView for its cropping features; otherwise could be android:background --> - <ImageView - android:id="@+id/albumart" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_gravity="fill" - android:scaleType="centerCrop" - android:adjustViewBounds="false" - /> - </FrameLayout> - - <LinearLayout - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_gravity="bottom"> - <TextView - android:id="@+id/title" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="8dip" - android:layout_marginStart="16dip" - android:layout_marginEnd="16dip" - android:gravity="center_horizontal" - android:singleLine="true" - android:ellipsize="end" - android:textAppearance="?android:attr/textAppearanceMedium" - /> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - android:layout_marginTop="5dip"> - <FrameLayout - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="1"> - <ImageView - android:id="@+id/btn_prev" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:src="@*android:drawable/ic_media_previous" - android:clickable="true" - android:background="?android:attr/selectableItemBackground" - android:padding="10dip" - android:contentDescription="@*android:string/lockscreen_transport_prev_description"/> - </FrameLayout> - <FrameLayout - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="1"> - <ImageView - android:id="@+id/btn_play" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:clickable="true" - android:src="@*android:drawable/ic_media_play" - android:background="?android:attr/selectableItemBackground" - android:padding="10dip" - android:contentDescription="@*android:string/lockscreen_transport_play_description"/> - </FrameLayout> - <FrameLayout - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="1"> - <ImageView - android:id="@+id/btn_next" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:clickable="true" - android:src="@*android:drawable/ic_media_next" - android:background="?android:attr/selectableItemBackground" - android:padding="10dip" - android:contentDescription="@*android:string/lockscreen_transport_next_description"/> - </FrameLayout> - </LinearLayout> - </LinearLayout> - -</com.android.internal.policy.impl.keyguard.KeyguardTransportControlView>
\ No newline at end of file diff --git a/core/res/res/layout/keyguard_widget_remove_drop_target.xml b/core/res/res/layout/keyguard_widget_remove_drop_target.xml deleted file mode 100644 index 294c386..0000000 --- a/core/res/res/layout/keyguard_widget_remove_drop_target.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2012, 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. -*/ ---> -<TextView - xmlns:android="http://schemas.android.com/apk/res/android" - android:gravity="center" - android:padding="30dp" - android:paddingLeft="60dp" - android:paddingRight="60dp" - android:drawableLeft="@drawable/kg_widget_delete_drop_target" - android:drawablePadding="4dp" - android:text="@string/kg_reordering_delete_drop_target_text" - android:textColor="#FFF" - android:textSize="13sp" - android:shadowColor="#000" - android:shadowDy="1.0" - android:shadowRadius="1.0" - android:visibility="gone" /> diff --git a/core/res/res/layout/toast_bar.xml b/core/res/res/layout/toast_bar.xml new file mode 100644 index 0000000..b7443d5 --- /dev/null +++ b/core/res/res/layout/toast_bar.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2013 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<FrameLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <LinearLayout + android:background="@drawable/toast_bar_bg" + android:layout_height="50dp" + android:layout_width="match_parent"> + + <TextView + android:id="@android:id/message" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:ellipsize="end" + android:gravity="center_vertical" + android:paddingLeft="16dp" + android:paddingRight="16dp" + android:singleLine="true" + android:textColor="@android:color/white" + android:textSize="16sp" /> + + <LinearLayout + android:id="@android:id/button1" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:background="?android:attr/selectableItemBackground" + android:clickable="true"> + + <View + android:layout_width="1dp" + android:layout_height="match_parent" + android:layout_marginBottom="10dp" + android:layout_marginRight="12dp" + android:layout_marginTop="10dp" + android:background="#aaaaaa" /> + + <TextView + android:id="@android:id/text1" + android:textSize="12sp" + android:textColor="#aaaaaa" + android:textStyle="bold" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:gravity="center_vertical" + android:paddingLeft="8dp" + android:paddingRight="20dp" + android:textAllCaps="true" /> + </LinearLayout> + + </LinearLayout> + +</FrameLayout> diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 7306042..c3b1ac5 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Laat die program toe om na die SD-kaart te skryf."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"verander/vee uit interne mediabergingsinhoud"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Laat die program toe om die inhoud van die interne mediaberging te verander."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"bestuur dokumentberging"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Laat die program toe om dokumentberging te bestuur."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"verkry toegang tot alle gebruikers se eksterne berging"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Laat die program toe om toegang tot eksterne berging vir alle gebruikers te verkry."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"lees die kaslêerstelsel"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Laat die program toe om die verstek houerdiens in te roep om inhoud te kopieer. Nie vir gebruik deur normale programme nie."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Roeteer media-uitvoer"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Laat \'n program toe om media-uitvoere na ander eksterne toestelle te roeteer."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Kry toegang tot keyguard se veilige berging"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Laat \'n program toe om toegang tot keyguard se veilige berging te kry."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Beheer wys en versteek van keyguard"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Laat \'n program toe om keyguard te beheer."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Raak twee keer vir zoembeheer"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Kon nie legstuk byvoeg nie."</string> <string name="ime_action_go" msgid="8320845651737369027">"Gaan"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index eb58502..12cfbf4 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"መተግበሪያውን ወደ SD ካርድ ለመፃፍ ይፈቅዳል።"</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"የውስጥ ማህደረ መረጃ ማከማቻ ይዘቶችን ቀይር/ሰርዝ"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"የውስጥ ማህደረ መረጃ ማከማቻ ይዘትን ለመቀየር ለመተግበሪያው ይፈቅዳሉ፡፡"</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"የሰነድ ማከማቻን ያስተዳድሩ"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"መተግበሪያው የሰነድ ማከማቻን እንዲያስተዳድር ይፈቅድለታል።"</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"የሁሉም ተጠቃሚዎች ውጫዊ ማከማቻውን ይደርስበታል"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"መተግበሪያውን የሁሉም ተጠቃሚዎች ውጫዊ ማከማቻውን እንዲደርስ ይፈቅድለታል።"</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"የመሸጎጫ ስርዓተ ፋይል ድረስ"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"ይዘትን ለመቅዳት ነባሪ መያዣ አገልግሎት እንዲያስነሳ ለመተግበሪው ይፈቅዳሉ፡፡ ለመደበኛ መተግበሪያዎች ለመጠቀም አይሆንም፡፡"</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"የሚዲያ ውፅአት መንገድ"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"አንድ መተግበሪያ የሚዲያ ውፅአትን ወደ ሌላ ውጫዊ መሳሪያ እንዲመራ ይፈቅድለታል።"</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"ደህንነቱ በቁልፍ የተጠበቀ ማከማቻን ይድረሱ"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"አንድ መተግበሪያ ደህንነቱ በቁልፍ የተጠበቀ ማከማቻ እንዲደርስ ያስችለዋል።"</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"የቁልፍ መጠበቂያውን ማሳየት እና መደበቅ ይቆጣጠሩ"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"አንድ መተግበሪያ የቁልፍ መጠበቂያውን እንዲቆጣጠር ያስችለዋል።"</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"ለአጉላ መቆጣጠሪያ ሁለት ጊዜ ነካ አድርግ"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"ምግብር ማከል አልተቻለም።"</string> <string name="ime_action_go" msgid="8320845651737369027">"ሂድ"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index cade61d..9b2f284 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"للسماح للتطبيق بالكتابة إلى بطاقة SD."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"تعديل/حذف محتويات وحدة تخزين الوسائط الداخلية"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"للسماح للتطبيق بتعديل محتويات وحدة تخزين الوسائط الداخلية."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"إدارة السعة التخزينية للمستند"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"السماح للتطبيق بإدارة السعة التخزينية للمستند."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"الوصول إلى سعة التخزين الخارجية لجميع المستخدمين"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"للسماح للتطبيق بالدخول إلى سعة التخزين الخارجية لجميع المستخدمين."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"الدخول إلى نظام ملفات ذاكرة التخزين المؤقت"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"للسماح باستدعاء خدمة الحاوية الافتراضية لنسخ المحتوى. ليس للاستخدام بواسطة التطبيقات العادية."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"توجيه إخراج الوسائط"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"للسماح للتطبيق بتوجيه إخراج الوسائط إلى أجهزة خارجية أخرى."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"الدخول إلى التخزين المحمي بقفل المفاتيح"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"السماح لأحد التطبيقات بالدخول إلى التخزين المحمي بقفل المفاتيح."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"التحكم في عرض وإخفاء قفل المفاتيح"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"للسماح لأحد التطبيقات بالتحكم في قفل المفاتيح."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"المس مرتين للتحكم في التكبير/التصغير"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"تعذرت إضافة أداة."</string> <string name="ime_action_go" msgid="8320845651737369027">"تنفيذ"</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 10e3d45..5cb4c43 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Дазваляе прыкладанням запісваць на SD-карту."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"змяніць/выдаліць унутраныя носьбіты змесціва"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Дазваляе прыкладанням змяняць змесціва ўнутранай памяці."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"кіраваць сховішчам для дакументаў"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Дазваляе прыкладанню кіраваць сховішчам для дакументаў."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"доступ да знешніх захоўвання для ўсіх карыстальнікаў"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Дазваляе ўсiм карыстальнiкам прыкладання атрымлiваць доступ да знешнега сховiшча"</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"доступ да файлавай сістэмы кэша"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Дазваляе прыкладанням выклікаць службу захавання па змаўчанні для капіявання змесціва. Не выкарыстоўваецца звычайнымі прыкладаннямі."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Маршрутны мультымедыйны выхад"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Дазваляе прыкладанням маршрутызаваць мультымедыйны выхад на iншыя знешнiя прылады."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Доступ да блакіроўкі клавіятуры бяспечнага сховішча"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Дазваляе прыкладанню атрымліваць доступ да блакіроўкі клавіятуры бяспечнага сховішча."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Кiраванне адлюстраваннем і схаваннем блакiроўкi клавіятуры"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Дазваляе прыкладанню кiраваць блакiроўкай клавiятуры."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Двойчы дакраніцеся, каб змянiць маштаб"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Немагчыма дадаць віджэт."</string> <string name="ime_action_go" msgid="8320845651737369027">"Пачаць"</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 11c97c2..afa6c118 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Разрешава на приложението да записва върху SD картата."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"пром./изтр. на съдърж. на вътр. мултим. хранил."</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Разрешава на приложението да променя съдържанието на вътрешното мултимедийно хранилище."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"управл. на хранил. с документи"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Разрешава на приложението да управлява хранилището с документи."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"достъп до външ. хранилище за всички потребители"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Разрешава на приложението достъп до външното хранилище за всички потребители."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"достъп до файловата система на кеша"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Разрешава на приложението да извиква стандартната услуга на контейнера, за да се копира съдържание. Не е предназначено за нормални приложения."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Насочване на изходящата мултимедия"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Разрешава на приложението да насочва изходящата мултимедия към други външни устройства."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Достъп до надеждното хранилище, свързано с функцията за защита на клавишите"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Позволява на приложението да осъществява достъп до надеждното хранилище, свързано с функцията за защита на клавишите."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Контролиране на показването и скриването на функцията за защита на клавишите"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Разрешава на приложението да контролира функцията за защита на клавишите."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Докоснете двукратно за управление на промяната на мащаба"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Приспособлението не можа да бъде добавено."</string> <string name="ime_action_go" msgid="8320845651737369027">"Старт"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 21f4357..aaa911d 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permet a l\'aplicació escriure a la targeta SD."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Canvia/esborra emmagatz. intern"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Permet que l\'aplicació modifiqui el contingut de l\'emmagatzematge multimèdia intern."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"gestió emmagatzematge docum."</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Permet que l\'aplicació gestioni l\'emmagatzematge de documents."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"accedeix a l\'emmagatzematge extern per a tots els usuaris"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Permet que l\'aplicació accedeixi a l\'emmagatzematge extern per a tots els usuaris."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"accedir al sistema de fitxers de la memòria cau"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permet invocar el servei de contenidor predeterminat per copiar contingut. No indicat per a les aplicacions normals."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Indicació de ruta de sortida de contingut multimèdia"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permet que una aplicació indiqui la ruta de sortida de contingut multimèdia a altres dispositius externs."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Accedeix a l\'emmagatzematge protegit per contrasenya"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permet que una aplicació accedeixi a l\'emmagatzematge protegit per contrasenya."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Controla si es mostra o s\'amaga el bloqueig de les tecles."</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permet que una aplicació controli el bloqueig de les tecles."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Toca dos cops per controlar el zoom"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"No s\'ha pogut afegir el widget."</string> <string name="ime_action_go" msgid="8320845651737369027">"Vés"</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index d1d83a0..abe6dad 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Umožňuje aplikaci zapisovat na kartu SD."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Upravit/smazat interní úlož."</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Umožňuje aplikaci upravovat obsah interního úložiště médií."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"spravovat úložiště dokumentů"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Umožňuje aplikaci spravovat úložiště dokumentů."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"přístup k externímu úložišti všech uživatelů"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Umožňuje aplikaci přistupovat k externímu úložišti pro všechny uživatele."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"přistupovat do souborového systému mezipaměti"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Umožňuje aplikaci dát výchozí službě kontejneru příkaz ke zkopírování obsahu. Toto oprávnění není určeno pro běžné aplikace."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Směrování výstupu médií"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Umožňuje aplikaci směrovat výstup médií do dalších externích zařízení."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Přístup k bezpečnému úložišti keyguard"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Umožňuje aplikaci přístup k bezpečnému úložišti keyguard."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Ovládání zobrazování a skrývání zámku obrazovky"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Umožňuje aplikaci ovládat zámek obrazovky."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Dvojitým dotykem můžete ovládat přiblížení"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget nelze přidat."</string> <string name="ime_action_go" msgid="8320845651737369027">"Přejít"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 3c6818b..e00597a 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Tillader, at appen kan skrive til SD-kortet."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Rediger/slet internt medielagringsindhold"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Tillader, appen kan ændre indholdet af det interne medielager."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"administrer dokumentlagring"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Tillader, at appen kan administrere dokumentlagring."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"få adgang til alle brugeres eksterne lagre"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Tillader, at appen får adgang til eksterne lagre for alle brugere."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"få adgang til cache-filsystemet"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Tillader, at appen kan benytte standardlagertjenesten til at kopiere indhold. Anvendes ikke af almindelige apps."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Viderefør medieoutput"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Tillader, at en applikation viderefører medieoutput til andre eksterne enheder."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Få adgang nøglebeskyttet lager"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Tillader, at en applikation får adgang til et nøglebeskyttet lager."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Administrer, om nøglebeskyttelse skal vises eller skjules"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Tillader, at en applikation styrer nøglebeskyttelsen."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Tryk to gange for zoomstyring"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget kunne ikke tilføjes."</string> <string name="ime_action_go" msgid="8320845651737369027">"Gå"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 0bed825..655d5d0 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Ermöglicht der App, auf die SD-Karte zu schreiben"</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Internen Medienspeicher ändern/löschen"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Ermöglicht der App, den Inhalt des internen Medienspeichers zu ändern"</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"Dokumentenspeicher verwalten"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"App kann Dokumentenspeicher verwalten"</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"Auf externen Speicher aller Nutzer zugreifen"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Ermöglicht der App, auf externen Speicher aller Nutzer zuzugreifen."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"Auf das Cache-Dateisystem zugreifen"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Ermöglicht der App das Aufrufen des Standard-Containerdienstes zum Kopieren von Inhalten. Nicht für normale Apps vorgesehen."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Medienausgabe umleiten"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Ermöglicht einer App, die Medienausgabe auf andere externe Geräte umzuleiten."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Zugriff auf mit Keyguard geschützten Speicher"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Ermöglicht einer App den Zugriff auf mit Keyguard geschützten Speicher"</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Anzeige und Ausblenden des Keyguard steuern"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Apps können den Keyguard steuern."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Für Zoomeinstellung zweimal berühren"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget konnte nicht hinzugefügt werden."</string> <string name="ime_action_go" msgid="8320845651737369027">"Los"</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 3d27568..5135847 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Επιτρέπει στην εφαρμογή την εγγραφή στην κάρτα SD."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"τροπ./διαγ. περ. απ. εσ. μνήμ."</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Επιτρέπει στην εφαρμογή να τροποποιήσει τα περιεχόμενα των εσωτερικών μέσων αποθήκευσης."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"διαχείριση αποθ.χώρου εγγράφων"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Επιτρέπει στην εφαρμογή τη διαχείριση του αποθηκευτικού χώρου εγγράφων."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"πρόσβ.εξωτ.χωρ. αποθ. όλων των χρηστ."</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Επιτρέπει στην εφαρμογή να αποκτήσει πρόσβαση σε εξωτερικό χώρο αποθήκευσης για όλους τους χρήστες."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"πρόσβαση στο σύστημα αρχείων προσωρινής μνήμης"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Επιτρέπει στην εφαρμογή την κλήση της προεπιλεγμένης υπηρεσίας κοντέινερ για την αντιγραφή περιεχομένου. Δεν χρησιμοποιείται από συνήθεις εφαρμογές."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Διαγραφή διαδρομής δεδομένων εξόδου μέσων"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Επιτρέπει σε μια εφαρμογή τη διαγραφή διαδρομής δεδομένων εξόδου μέσων σε άλλες εξωτερικές συσκευές."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Πρόσβαση στον ασφαλή αποθηκευτικό χώρο με κλείδωμα"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Επιτρέπει σε μια εφαρμογή να αποκτήσει πρόσβαση στον ασφαλή αποθηκευτικό χώρο με κλείδωμα."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Έλεγχος εμφάνισης και απόκρυψης κλειδώματος πληκτρολογίου"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Επιτρέπει σε μια εφαρμογή τον έλεγχο του κλειδώματος πληκτρολογίου."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Αγγίξτε δύο φορές για έλεγχο εστίασης"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Δεν ήταν δυνατή η προσθήκη του γραφικού στοιχείου."</string> <string name="ime_action_go" msgid="8320845651737369027">"Μετάβαση"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 95dec80..2d5e70c 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Allows the app to write to the SD card."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modify/delete internal media storage contents"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Allows the app to modify the contents of the internal media storage."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"manage document storage"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Allows the app to manage document storage."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"access external storage of all users"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Allows the app to access external storage for all users."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"access the cache file system"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Allows the app to invoke default container service to copy content. Not for use by normal apps."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Route media output"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Allows an application to route media output to other external devices."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Access keyguard secure storage"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Allows an application to access keyguard secure storage."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Control displaying and hiding keyguard"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Allows an application to control keyguard."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Touch twice for zoom control"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Couldn\'t add widget."</string> <string name="ime_action_go" msgid="8320845651737369027">"Go"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 8fe234d..501d56f 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Admite que la aplicación escriba en la tarjeta SD."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modificar/eliminar los contenidos del almacenamientos de medios internos"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Permite que la aplicación modifique el contenido del almacenamiento de medios interno."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"Administrar almac. de documen."</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Permite que la aplicación administre el almacenamiento de documentos."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"acceder almacenamiento externo"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Permite que la aplicación acceda al almacenamiento externo de todos los usuarios."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"Acceder al sistema de archivos caché"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permite que la aplicación ejecute el servicio de contenedor predeterminado para que copie contenido. Las aplicaciones normales no deben utilizar este permiso."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Dirigir salida de medios"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite que la aplicación dirija salidas de medios a otros dispositivos externos."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Acceder al almacenamiento seguro de bloqueos"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permite que una aplicación acceda al almacenamiento seguro de bloqueos."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Controlar cuándo se muestra y se oculta el bloqueo"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permite que una aplicación controle los bloqueos."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Toca dos veces para acceder al control de zoom."</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"No se pudo agregar el widget."</string> <string name="ime_action_go" msgid="8320845651737369027">"Ir"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 0ab7fca..0685e66 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permite que la aplicación escriba en la tarjeta SD."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modificar o eliminar el contenido del almacenamiento de medios interno"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Permite que la aplicación modifique el contenido del almacenamiento multimedia interno."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"administrar el almacenamiento de documentos"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Permite que la aplicación administre el almacenamiento de documentos."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"acceder al almacenamiento externo de todos los usuarios"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Permite que la aplicación acceda al almacenamiento externo de todos los usuarios."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"acceder al sistema de archivos almacenado en caché"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permite que la aplicación ejecute el servicio de contenedor predeterminado para copiar contenido. Las aplicaciones normales no deben usar este permiso."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Dirigir salida de medio"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite que la aplicación dirija salidas de medios a otros dispositivos externos."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Acceder al almacenamiento seguro de bloqueos"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permite que una aplicación acceda al almacenamiento seguro de bloqueos."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Controlar cuándo se muestra y se oculta el bloqueo"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permite que una aplicación controle los bloqueos."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Toca dos veces para acceder al control de zoom."</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"No se ha podido añadir el widget."</string> <string name="ime_action_go" msgid="8320845651737369027">"Ir"</string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 013a2eb..b1997d1 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Võimaldab rakendusel kirjutada SD-kaardile."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"sisemälu sisu muutm./kustut."</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Võimaldab rakendusel muuta sisemise andmekandja sisu."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"dokumendi talletuse haldamine"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Lubab rakendusel hallata dokumendi talletamist."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"juurdepääs välismäluseadmele (kõikidele kasutajatele)"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Võimaldab rakenduse kõikidel kasutajatel pöörduda välismäluseadme poole."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"juurdepääs vahemälu failisüsteemile"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Võimaldab rakendusel võtta sisu kopeerimiseks appi vaikekonteinerteenuse. Mitte kasutada tavarakenduste puhul."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Meediaväljundi teekonna koostamine"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Võimaldab rakendusel koostada teekonna meediaväljundist teistesse välistesse seadmetesse."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Juurdepääs võtmekaitsega turvalisele talletusruumile"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Lubab rakendusel hankida juurdepääsu võtmekaitsega turvalisele talletusruumile."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Võtmekaitse kuvamise ja peitmise juhtimine"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Lubab rakendusel võtmekaitset juhtida."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Suumi juhtimiseks puudutage kaks korda"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Vidinat ei saanud lisada."</string> <string name="ime_action_go" msgid="8320845651737369027">"Mine"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 97b430e..b47bf9f 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"به برنامه اجازه میدهد تا در کارت SD بنویسد."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"تغییر/حذف محتواهای حافظه رسانه داخلی"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"به برنامه اجازه میدهد تا محتویات حافظه رسانه داخلی را تغییر دهد."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"مدیریت فضای ذخیرهسازی اسناد"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"به برنامه اجازه میدهد فضای ذخیرهسازی اسناد را مدیریت کند."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"دسترسی به دستگاه ذخیره خارجی تمام کاربران"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"به برنامه اجازه میدهد به دستگاه ذخیره خارجی برای همه کاربران دسترسی داشته باشد."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"دسترسی به سیستم فایل حافظهٔ پنهان"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"به برنامه اجازه میدهد تا سرویس پیشفرض را فراخوانی کند و محتوا را کپی کند. برای استفاده برنامههای عادی مورد نیاز نیست."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"تعیین مسیر خروجی رسانه"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"به یک برنامه اجازه میدهد خروجی رسانه را به دستگاههای خارجی دیگر تعیین مسیر کند."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"دسترسی به فضای ذخیرهسازی ایمن محافظ کلید"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"به یک برنامه کاربردی برای دسترسی به فضای ذخیرهسازی ایمن محافظ کلید اجازه میدهد."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"کنترل نمایش و پنهان کردن محافظ کلید"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"اجازه میدهد برنامهای محافظ کلید را کنترل کند."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"دوبار لمس کنید تا بزرگنمایی کنترل شود"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"افزودن ابزارک انجام نشد."</string> <string name="ime_action_go" msgid="8320845651737369027">"برو"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 25336b0..feeed53 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Antaa sovelluksen kirjoittaa SD-kortille."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"muokkaa/poista sisäisen säilytystilan sisältöä"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Antaa sovelluksen muokata sisäisen tallennustilan sisältöä."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"hallinnoi dokum. tallennusta"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Antaa sovelluksen hallinnoida dokumenttien tallennusta."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"käyttää kaikkien käyttäjien ulk. tallennustilaa"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Sallii sovelluksen käyttää ulkoista tallennustilaa kaikille käyttäjille."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"käytä välimuistin tiedostojärjestelmää"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Antaa sovelluksen kutsua oletussäilöpalvelua sisällön kopioimiseen. Ei tavallisten sovellusten käyttöön."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Median reititys"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Antaa sovelluksen reitittää mediaa muihin ulkoisiin laitteisiin."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Salasanalla suojatun tallennustilan hallinta"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Sallii sovelluksen käyttää salasanalla suojattua tallennustilaa."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Hallinnoi näppäinvahdin näyttämistä ja piilottamista"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Antaa sovelluksen hallita näppäinvahtia."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Ohjaa zoomausta napauttamalla kahdesti"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widgetin lisääminen epäonnistui."</string> <string name="ime_action_go" msgid="8320845651737369027">"Siirry"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 88033d2..97e0a82 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permet à l\'application de modifier le contenu de la carte SD."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Modifier/Supprimer contenu mémoire interne"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Permet à l\'application de modifier le contenu de la mémoire de stockage multimédia interne."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"gérer stockage des documents"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Permet à l\'application de gérer le stockage des documents."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"Accès stock. ext. tous utilis."</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Permet à l\'application d\'accéder à la mémoire de stockage externe pour tous les utilisateurs."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"accéder au système de fichiers en cache"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permet à l\'application d\'invoquer le service de conteneur par défaut pour copier du contenu. Les applications standards ne doivent pas utiliser cette fonctionnalité."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Diriger la sortie multimédia"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permet à une application de diriger la sortie multimédia vers d\'autres appareils externes."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Accéder au stockage sécurisé keyguard"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permet à une application d\'accéder au stockage sécurisé keyguard."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Contrôler l\'affichage et le masquage de la protection des touches"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permet à une application de contrôler la protection des touches."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Appuyez deux fois pour régler le zoom."</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Impossible d\'ajouter le widget."</string> <string name="ime_action_go" msgid="8320845651737369027">"OK"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index fa09220..b135c2e 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"एप्लिकेशन को SD कार्ड पर लिखने देता है."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"आंतरिक मीडिया संग्रहण सामग्रियों को बदलें/हटाएं"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"एप्लिकेशन को आंतरिक मीडिया संग्रहण की सामग्री को संशोधित करने देता है."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"दस्तावेज़ संग्रहण प्रबंधित करें"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"एप्लिकेशन को दस्तावेज़ संग्रहण प्रबंधित करने की अनुमति दें."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"सभी उपयोगकर्ताओं के बाहरी संग्रहण तक पहुंचें"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"एप्लिकेशन को सभी उपयोगकर्ताओं के बाहरी संग्रहण तक पहुंचने दें."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"कैश फ़ाइल सिस्टम में पहंचे"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"एप्लिकेशन को सामग्री की प्रतिलिपि बनाने के लिए डिफ़ॉल्ट कंटेनर सेवा शुरू करने देता है. सामान्य एप्लिकेशन द्वारा उपयोग करने के लिए नहीं."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"मीडिया आउटपुट को रूट करें"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"एप्लिकेशन को मीडिया आउटपुट को अन्य बाहरी उपकरणों पर रूट करने देता है."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"कीगार्ड सुरक्षित संग्रहण एक्सेस करें"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"एप्लिकेशन को कीगार्ड सुरक्षित संग्रहण एक्सेस करने देती है."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"कीगार्ड दिखाना और छिपाना नियंत्रित करें"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"एप्लिकेशन को कीगार्ड नियंत्रित करने देती है."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"ज़ूम नियंत्रण के लिए दो बार स्पर्श करें"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"विजेट नहीं जोड़ा जा सका."</string> <string name="ime_action_go" msgid="8320845651737369027">"जाएं"</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index ef9b50a..f033a16 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Aplikaciji omogućuje pisanje na SD karticu."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"izmijeni/izbriši sadržaj pohranjen na internim medijima"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Aplikaciji omogućuje izmjenu sadržaja pohranjenog na internim medijima."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"upravljanje pohr. dokumenata"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Omogućuje aplikaciji upravljanje pohranom dokumenata."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"pristup vanjskoj pohrani svima"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Omogućuje aplikaciji pristup vanjskoj pohrani za sve korisnike."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"pristup sustavu datoteka predmemorije"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Omogućuje aplikaciji dozivanje usluge zadanog spremnika radi kopiranja sadržaja. Nije namijenjena uobičajenim aplikacijama."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Usmjeravanje medijskog izlaza"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Aplikaciji omogućuje usmjeravanje medijskog izlaza na druge vanjske uređaje."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Pristup zaključanoj sigurnoj pohrani"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Omogućuje aplikaciji pristupanje zaključanoj sigurnoj pohrani."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Upravljanje prikazivanjem i skrivanjem zaključavanja tipkovnice"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Omogućuje aplikaciji upravljanje zaključavanjem tipkovnice."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Dodirnite dvaput za upravljanje zumiranjem"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget nije moguće dodati."</string> <string name="ime_action_go" msgid="8320845651737369027">"Idi"</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 4c87604..516241f 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Lehetővé teszi az alkalmazás számára, hogy írjon az SD-kártyára."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"belső tár tartalmának módosítása/törlése"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Lehetővé teszi az alkalmazás számára, hogy módosítsa a belső háttértár tartalmát."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"dokumentumtárhely kezelése"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Lehetővé teszi az alkalmazás számára a dokumentumtárhely kezelését."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"hozzáf. minden felh. külső tár"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Minden felhasználó számára lehetővé teszi, hogy az alkalmazás hozzáférjen külső tárolókhoz."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"hozzáférés a gyorsítótár fájlrendszeréhez"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Lehetővé teszi az alkalmazás számára az alapértelmezett tárolószolgáltatás használatát tartalom másolásához. Normál alkalmazások nem használhatják."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Médiafájlok kimenetének irányítása"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Lehetővé teszi az alkalmazás számára, hogy más külső eszközökre irányítsa a médiafájlok lejátszását."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Hozzáférés a kóddal védett tárhelyhez"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Lehetővé teszi egy alkalmazás számára, hogy hozzáférjen a kóddal védett tárhelyhez."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Billentyűzár megjelenítésének és elrejtésének vezérlése"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Lehetővé teszi egy alkalmazás számára a billentyűzár vezérlését."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Érintse meg kétszer a nagyítás beállításához"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Nem sikerült hozzáadni a modult."</string> <string name="ime_action_go" msgid="8320845651737369027">"Ugrás"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 39106ad..812d016 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Memungkinkan apl menulis ke kartu SD."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"ubah/hapus konten penyimpanan media internal"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Mengizinkan apl memodifikasi konten penyimpanan media internal."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"kelola penyimpanan dokumen"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Mengizinkan aplikasi mengelola penyimpanan dokumen."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"akses penyimpanan eksternal"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Izinkan aplikasi mengakses penyimpanan eksternal untuk semua pengguna."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"akses sistem file cache."</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Mengizinkan apl menjalankan layanan kontainer default untuk menyalin konten. Tidak untuk digunakan oleh apl normal."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Menentukan rute keluaran media"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Memungkinkan aplikasi menentukan rute keluaran media ke perangkat eksternal lainnya."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Mengakses pengaman penyimpanan aman"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Mengizinkan aplikasi mengakses pengaman penyimpanan aman."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Kontrol untuk menampilkan dan menyembunyikan pengaman"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Izinkan aplikasi untuk mengontrol pengaman."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Sentuh dua kali untuk mengontrol perbesar/perkecil"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Tidak dapat menambahkan widget."</string> <string name="ime_action_go" msgid="8320845651737369027">"Buka"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 14e346f..05bed06 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Consente all\'applicazione di scrivere sulla scheda SD."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modifica/eliminaz. contenuti archivio media int."</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Consente all\'applicazione di modificare i contenuti dell\'archivio media interno."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"gestione della memorizzazione dei documenti"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Consente all\'app di gestire la memorizzazione dei documenti."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"accesso memoria esterna utenti"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Consente all\'applicazione di accedere alla memoria esterna di tutti gli utenti."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"accesso al filesystem nella cache"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Consente all\'applicazione di richiamare il servizio container predefinito per la copia di contenuti. Da non usare per normali applicazioni."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Indirizzamento uscita media"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Consente a un\'applicazione di indirizzare l\'uscita di media verso altri dispositivi esterni."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Accesso all\'archivio sicuro keyguard"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Consente a un\'applicazione di accedere all\'archivio sicuro keguard."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Controllo della visualizzazione e dell\'occultamento di keyguard"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Consente a un\'applicazione di controllare keguard."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Tocca due volte per il comando dello zoom"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Aggiunta del widget non riuscita."</string> <string name="ime_action_go" msgid="8320845651737369027">"Vai"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index cc70005..1e0e204 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"מאפשר ליישום לכתוב לכרטיס ה-SD."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"שנה/מחק תוכן של אחסון מדיה פנימי"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"מאפשר ליישום לשנות את התוכן של אמצעי האחסון הפנימי למדיה."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"ניהול של אחסון מסמכים"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"מאפשר ליישום לנהל אחסון מסמכים."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"גישה לאחסון חיצוני, כל המשתמשים"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"מאפשר ליישום לגשת לאחסון חיצוני עבור כל המשתמשים."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"גישה למערכת הקבצים בקובץ השמור"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"מאפשר ליישום להפעיל שירות גורם מכיל המוגדר כברירת מחדל להעתקת תוכן. לא מיועד לשימוש על ידי יישומים רגילים."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"ניתוב פלט מדיה"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"מאפשר ליישום לנתב פלט מדיה למכשירים חיצוניים אחרים."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"גישה לאחסון המוגן באמצעות מפתח"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"מאפשר ליישום לגשת לאחסון המוגן באמצעות מפתח."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"שלוט בהצגה והסתרה של מגן המקלדת"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"מאפשר ליישום לשלוט במגן המקלדת."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"גע פעמיים לבקרת מרחק מתצוגה"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"לא ניתן להוסיף widget."</string> <string name="ime_action_go" msgid="8320845651737369027">"התחל"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 99778a0..3241159 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"SDカードへの書き込みをアプリに許可します。"</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"内部メディアストレージの内容の変更/削除"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"内部メディアストレージの内容を変更することをアプリに許可します。"</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"ドキュメントストレージの管理"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"ドキュメントストレージの管理をアプリに許可します。"</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"全ユーザー外部ストレージへのアクセス"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"すべてのユーザーの外部ストレージへのアクセスをアプリに許可します。"</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"キャッシュファイルシステムにアクセス"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"デフォルトのコンテナサービスを呼び出してコンテンツをコピーすることをアプリに許可します。通常のアプリでは使用しません。"</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"メディア出力のルーティング"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"メディア出力を他の外部デバイスにルーティングすることをアプリに許可します。"</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"キーガードセキュアストレージへのアクセス"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"キーガードセキュアストレージへのアクセスをアプリに許可する"</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"キーガードの表示/非表示の制御"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"キーガードの制御をアプリに許可します。"</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"ダブルタップでズームコントロール"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"ウィジェットを追加できませんでした。"</string> <string name="ime_action_go" msgid="8320845651737369027">"移動"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index a97bf9b..b6e07c8 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"앱이 SD 카드에 쓸 수 있도록 허용합니다."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"내부 미디어 저장소 콘텐츠 수정/삭제"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"앱이 내부 미디어 저장소의 콘텐츠를 수정할 수 있도록 허용합니다."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"문서 저장공간 관리"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"앱이 문서 저장공간을 관리할 수 있도록 허용합니다."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"모든 사용자의 외부 저장소에 액세스"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"앱이 모든 사용자의 외부 저장소에 액세스하도록 허용합니다."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"캐시 파일시스템 액세스"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"기본 컨테이너 서비스를 호출하여 콘텐츠를 복사할 수 있도록 허용합니다. 일반 앱에서는 사용하지 않습니다."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"미디어 출력 연결"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"앱이 미디어 출력을 기타 외부 기기에 연결할 수 있도록 허용합니다."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"키가드 보안 저장소 액세스"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"애플리케이션에서 키가드 보안 저장소에 액세스하도록 허용합니다."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"키가드 표시 및 숨기기 설정"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"애플리케이션에서 키가드를 제어하도록 허용합니다."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"확대/축소하려면 두 번 터치하세요."</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"위젯을 추가할 수 없습니다."</string> <string name="ime_action_go" msgid="8320845651737369027">"이동"</string> diff --git a/core/res/res/values-land/arrays.xml b/core/res/res/values-land/arrays.xml index 240b9e4..5602a1c 100644 --- a/core/res/res/values-land/arrays.xml +++ b/core/res/res/values-land/arrays.xml @@ -19,54 +19,4 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- Resources for GlowPadView in LockScreen --> - <array name="lockscreen_targets_when_silent"> - <item>@null</item>" - <item>@drawable/ic_action_assist_generic</item> - <item>@drawable/ic_lockscreen_soundon</item> - <item>@drawable/ic_lockscreen_unlock</item> - </array> - - <array name="lockscreen_target_descriptions_when_silent"> - <item>@null</item> - <item>@string/description_target_search</item> - <item>@string/description_target_soundon</item> - <item>@string/description_target_unlock</item> - </array> - - <array name="lockscreen_direction_descriptions"> - <item>@null</item> - <item>@string/description_direction_up</item> - <item>@string/description_direction_left</item> - <item>@string/description_direction_down</item> - </array> - - <array name="lockscreen_targets_when_soundon"> - <item>@null</item> - <item>@drawable/ic_action_assist_generic</item> - <item>@drawable/ic_lockscreen_silent</item> - <item>@drawable/ic_lockscreen_unlock</item> - </array> - - <array name="lockscreen_target_descriptions_when_soundon"> - <item>@null</item> - <item>@string/description_target_search</item> - <item>@string/description_target_silent</item> - <item>@string/description_target_unlock</item> - </array> - - <array name="lockscreen_targets_with_camera"> - <item>@null</item> - <item>@drawable/ic_action_assist_generic</item> - <item>@drawable/ic_lockscreen_camera</item> - <item>@drawable/ic_lockscreen_unlock</item> - </array> - - <array name="lockscreen_target_descriptions_with_camera"> - <item>@null</item> - <item>@string/description_target_search</item> - <item>@string/description_target_camera</item> - <item>@string/description_target_unlock</item> - </array> - </resources> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 2bde748..2ad0598 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Leidžiama programai rašyti į SD kortelę."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"keisti / ištr. vid. med. atm. tur."</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Leidžiama programai keisti vidinės medijos saugyklos turinį."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"tvarkyti dokumentų saugyklą"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Leidžiama programai tvarkyti dokumentų saugyklą."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"pasiekti visų naud. išor. atm."</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Leidžiama programai pasiekti visų naudotojų išorinę atmintinę."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"pasiekti talpyklos failų sistemą"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Leidžiama programai iškviesti numatytąją sudėtinio rodinio paslaugą, kad būtų kopijuojamas turinys. Neskirta naudoti įprastoms programoms."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Medijos išvesties nukreipimas"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Leidžiama programai nukreipti medijos išvestį į kitus išorinius įrenginius."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Pasiekti „KeyGuard“ saugyklą"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Programai leidžiama pasiekti „KeyGuard“ saugyklą."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Valdyti „KeyGuard“ rodymą ir slėpimą"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Programai leidžiama valdyti „KeyGuard“."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Dukart palieskite, kad valdytumėte mastelio keitimą"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Nepavyko pridėti."</string> <string name="ime_action_go" msgid="8320845651737369027">"Pradėti"</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 4cca123..de30037 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Ļauj lietotnei rakstīt SD kartē."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"pārv./dz.datu n.iekš.atm.sat."</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Ļauj lietotnei modificēt datu nesēja iekšējās atmiņas saturu."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"Dokumentu krātuves pārvaldība"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Ļauj lietotnei pārvaldīt dokumentu krātuvi."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"piekļ. visu liet. ārējai krāt."</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Ļauj lietotnei piekļūt visu lietotāju ārējai krātuvei."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"piekļūt kešatmiņas failu sistēmai"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Ļauj lietotnei izsaukt noklusējuma konteinera pakalpojumu, lai kopētu saturu. Atļauja neattiecas uz parastām lietotnēm."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Multivides datu izejas maršrutēšana"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Ļauj lietojumprogrammai maršrutēt multivides datu izeju uz citām ārējām ierīcēm."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Piekļūt krātuvei, kas aizsargāta ar atslēgu"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Ļauj lietojumprogrammai piekļūt krātuvei, kas aizsargāta ar atslēgu."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Pārvaldīt krātuves rādīšanu un paslēpšanu."</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Ļauj lietojumprogrammai pārvaldīt krātuvi."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Pieskarieties divreiz, lai kontrolētu tālummaiņu."</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Nevarēja pievienot logrīku."</string> <string name="ime_action_go" msgid="8320845651737369027">"Doties uz"</string> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 06548c6..b518ea9 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Membenarkan apl menulis ke kad SD."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"ubh suai/pdm kdg strn mdia dlm"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Membenarkan apl mengubah suai kandungan storan media dalaman."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"urus storan dokumen"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Membenarkan apl mengurus storan dokumen."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"mengakses storan luaran untuk semua pengguna"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Membenarkan apl untuk mengakses storan luaran untuk semua pengguna."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"akses sistem fail cache"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Membenarkan apl untuk menggunakan perkhidmatan bekas lalai untuk menyalin kandungan. Bukan untuk digunakan oleh apl biasa."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Buat laluan output media"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Membenarkan apl untuk membuat laluan output media ke peranti luaran lain."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Akses storan selamat pengawal kekunci"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Membenarkan aplikasi mengakses storan selamat pengawal kekunci."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Kawal paparkan dan sembunyikan pengawal kekunci"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Membenarkan aplikasi untuk mengawal pengawal kekunci."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Sentuh dua kali untuk mendapatkan kawalan zum"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Tidak dapat menambahkan widget."</string> <string name="ime_action_go" msgid="8320845651737369027">"Pergi"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index b339738..080a05c 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Lar appen skrive til SD-kortet."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"endre eller slette innhold på interne medier"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Lar appen endre innholdet i det interne lagringsmediet."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"administrere dokumentlagring"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Lar appen administrere dokumentlagring."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"åpne eksternlagring for alle brukere"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Tillater appen å åpne eksternlagring for alle brukere."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"tilgang til bufrede filer"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Lar appen påkalle standard meldingsbeholdertjeneste for kopiering av innhold. Ikke beregnet på vanlige apper."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Videresending av medieutdata"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Lar en app videresende medieutdata til andre eksterne enheter."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Bruk av sikker lagring via keyguard."</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Lar en app bruke sikker lagring via keyguard."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Kontrollér om tastelåsen er skjult eller vist"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Tillater at en app kontrollerer tastelåsen."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Trykk to ganger for zoomkontroll"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Kunne ikke legge til modulen."</string> <string name="ime_action_go" msgid="8320845651737369027">"Utfør"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 358dfe3..299658e 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Hiermee kan de app schrijven naar de SD-kaart."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"inh. mediaopsl. wijz./verw."</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Hiermee kan de app de inhoud van de interne mediaopslag aanpassen."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"documentopslag beheren"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Hiermee kan de app documentopslag beheren."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"toegang tot externe opslag van alle gebruikers"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Hiermee krijgt de app toegang tot externe opslag van alle gebruikers."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"het cachebestandssysteem openen"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Hiermee kan de app de standaard containerservice aanroepen om inhoud te kopiëren. Niet voor gebruik door normale apps."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Media-uitvoer aansturen"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Hiermee kan een app media-uitvoer naar andere externe apparaten doorsturen."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Toegang tot opslag met toetsbeveiliging"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Hiermee krijgt een app toegang tot opslag met toetsbeveiliging."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Weergeven en verbergen van toetsbeveiliging beheren"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Staat toe dat een app de toetsbeveiliging beheert."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Raak twee keer aan voor zoomregeling"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Kan widget niet toevoegen."</string> <string name="ime_action_go" msgid="8320845651737369027">"Ga"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index d3b340b..7897763 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Pozwala aplikacji na zapis na karcie SD."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modyfikowanie/usuwanie zawartości pamięci wew."</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Pozwala aplikacji na modyfikowanie zawartości pamięci wewnętrznej."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"zarządzaj przechowywaniem dokumentów"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Pozwala aplikacji zarządzać przechowywaniem dokumentów."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"dostęp do zewnętrznej pamięci wszystkich"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Pozwala aplikacji na dostęp do zewnętrznej pamięci masowej dla wszystkich użytkowników."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"dostęp do systemu plików pamięci podręcznej"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Pozwala aplikacji na wywoływanie domyślnej usługi kontenera w celu skopiowania zawartości. Nieprzeznaczone dla zwykłych aplikacji."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Kierowanie wyjścia multimediów"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Pozwala aplikacji na kierowanie wyjściowych danych multimedialnych do innych urządzeń zewnętrznych."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Dostęp do bezpiecznego magazynu kluczy"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Zezwala aplikacji na dostęp do bezpiecznego magazynu kluczy."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Kontroluj wyświetlanie i ukrywanie zabezpieczenia kluczami"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Umożliwia aplikacji kontrolowanie zabezpieczenia kluczami."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Dotknij dwukrotnie, aby sterować powiększeniem."</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Nie można dodać widżetu."</string> <string name="ime_action_go" msgid="8320845651737369027">"OK"</string> diff --git a/core/res/res/values-port/alias.xml b/core/res/res/values-port/alias.xml deleted file mode 100644 index bf3eecb..0000000 --- a/core/res/res/values-port/alias.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* //device/apps/common/assets/res/any/colors.xml -** -** Copyright 2012, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> -<resources> - <!-- Alias used to reference one of two possible layouts in keyguard. --> - <item type="layout" name="keyguard_eca">@android:layout/keyguard_emergency_carrier_area</item> -</resources> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 32d3692..6d76248 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permite que a aplicação escreva no cartão SD."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modif./elim. armaz. interno"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Permite que a aplicação modifique o conteúdo de armazenamento de suportes internos."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"gerir o armaz. de documentos"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Permite que a aplicação faça a gestão do armazenamento de documentos."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"aceder ao armazenamento externo de todos os utilizadores"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Permite que a aplicação aceda ao armazenamento externo para todos os utilizadores."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"aceder ao sistema de ficheiros da cache"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permite à aplicação invocar o serviço de contentor predefinido para copiar conteúdo. Não se destina a ser utilizado por aplicações normais."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Encaminhar saída de som multimédia"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite que a aplicação encaminhe a saída de som multimédia para outros dispositivos externos."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Aceder ao armazenamento seguro de proteção de teclado"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permite a uma aplicação aceder ao armazenamento seguro de proteção de teclado."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Controlar apresentação e ocultação de proteção de teclado"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permite que uma aplicação controle a proteção de teclado."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Toque duas vezes para controlar o zoom"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Não foi possível adicionar widget."</string> <string name="ime_action_go" msgid="8320845651737369027">"Ir"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index fb9154f..8730604 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permite que o aplicativo grave em seu cartão SD."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modificar/excluir conteúdos de armazenamento de mídia internos"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Permite que o aplicativo modifique o conteúdo da mídia de armazenamento interno."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"gerenciar armaz. de documentos"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Permitir que o aplicativo gerencie o armazenamento de documentos."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"acessar arm. ext. dos usuários"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Permite que o aplicativo acesse o armazenamento externo para todos os usuários."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"acessar o sistema de arquivos de cache"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permite que o aplicativo invoque serviços contêiner padrão para copiar conteúdo. Não deve ser usado em aplicativos normais."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Rotear saída de mídia"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite que um aplicativo faça o roteamento de saída de mídia para outros dispositivos externos."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Acessar o armazenamento seguro do bloqueio de teclado"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permite que o aplicativo acesse o armazenamento seguro do bloqueio de teclado."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Controlar a exibição e ocultação do bloqueio de tela"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permite que o aplicativo controle o bloqueio de teclado."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Toque duas vezes para controlar o zoom"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Não foi possível adicionar widget."</string> <string name="ime_action_go" msgid="8320845651737369027">"Ir"</string> diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml index 361b18a..4404d87 100644 --- a/core/res/res/values-rm/strings.xml +++ b/core/res/res/values-rm/strings.xml @@ -1025,6 +1025,10 @@ <skip /> <!-- no translation found for permdesc_mediaStorageWrite (8189160597698529185) --> <skip /> + <!-- no translation found for permlab_manageDocs (5778318598448849829) --> + <skip /> + <!-- no translation found for permdesc_manageDocs (8704323176914121484) --> + <skip /> <!-- no translation found for permlab_sdcardAccessAll (8150613823900460576) --> <skip /> <!-- no translation found for permdesc_sdcardAccessAll (3215208357415891320) --> @@ -1981,6 +1985,14 @@ <skip /> <!-- no translation found for permdesc_route_media_output (4932818749547244346) --> <skip /> + <!-- no translation found for permlab_access_keyguard_secure_storage (7565552237977815047) --> + <skip /> + <!-- no translation found for permdesc_access_keyguard_secure_storage (5866245484303285762) --> + <skip /> + <!-- no translation found for permlab_control_keyguard (172195184207828387) --> + <skip /> + <!-- no translation found for permdesc_control_keyguard (3043732290518629061) --> + <skip /> <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4070433208160063538) --> <skip /> <!-- no translation found for gadget_host_error_inflating (4882004314906466162) --> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 4694e15..4267fe1 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permite aplicaţiei să scrie pe cardul SD."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modif./şterg. conţinutul media stocat intern"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Permite aplicaţiei să modifice conţinutul stocării media interne."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"gestionare stocare documente"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Permite aplicației să gestioneze stocarea documentelor."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"acces. stoc. ext. pt. toţi utilizat."</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Permite aplicaţiei să acceseze stocarea externă pentru toţi utilizatorii."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"accesare sistem de fişiere cache"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permite aplicaţiei să invoce serviciul containerului prestabilit pentru a copia conţinutul. Nu se utilizează de aplicaţiile obişnuite."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Direcţionează rezultatele media"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite unei aplicaţii să direcţioneze rezultate media către alte dispozitive externe."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Accesează stocarea securizată când tastatura este blocată"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permite unei aplicații să acceseze stocarea securizată când tastatura este blocată."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Stabilește afișarea și ascunderea blocării tastaturii"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permite unei aplicații să controleze blocarea tastaturii."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Atingeţi de două ori pentru a mări/micşora"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Nu s-a putut adăuga widgetul."</string> <string name="ime_action_go" msgid="8320845651737369027">"Accesaţi"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 1b9b750..b05bef7 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Приложение сможет записывать данные на SD-карту."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Доступ к данным мультимедиа"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Приложение сможет изменять контент внутреннего хранилища мультимедиа."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"управлять хранением документов"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Приложение сможет управлять хранением документов."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"Доступ к внешним накопителям из всех аккаунтов"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Приложение сможет обращаться к внешним накопителям из всех аккаунтов."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"Доступ к файловой системе кэша"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Приложение сможет вызывать службу контейнеров по умолчанию для копирования данных. Это разрешение не используется обычными приложениями."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Перенаправление мультимедийных данных"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Приложение сможет направлять поток мультимедиа на другие внешние устройства."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Доступ к хранилищу ключей"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Приложение сможет получить доступ к хранилищу ключей."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Управлять отображением хранилища ключей"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Приложение сможет управлять хранилищем ключей."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Нажмите дважды для изменения масштаба"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Не удалось добавить виджет."</string> <string name="ime_action_go" msgid="8320845651737369027">"Выбрать"</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 03e18be..96b44f7 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Umožňuje aplikácii zápis na kartu SD."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"úprava alebo odstránenie obsahu interného ukladacieho priestoru média"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Umožňuje aplikácii zmeniť obsah interného ukladacieho priestoru média."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"správa ukladacieho priestoru dokumentov"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Umožňuje aplikácii spravovať ukladací priestor dokumentov."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"pristupovať k externému ukladaciemu priestoru pre všetkých používateľov"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Umožňuje aplikácii pristupovať k externému ukladaciemu priestoru pre všetkých používateľov."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"pristupovať do súborového systému vyrovnávacej pamäte"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Umožňuje volať predvolenú službu kontajnera na skopírovanie obsahu. Bežné aplikácie toto nastavenie nepoužívajú."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Smerovanie výstupu médií"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Umožňuje aplikácii smerovať výstup médií do ďalších externých zariadení."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Prístup k ukladaciemu priestoru zabezpečenému technológiou keyguard"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Umožňuje aplikácii získať prístup k ukladaciemu priestoru zabezpečenému technológiou keyguard."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Ovládanie zobrazenia alebo skrytia technológie keyguard"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Umožňuje aplikácii ovládať technológiu keyguard."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Ovládacie prvky lupy zobrazíte dvojitým dotknutím"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Miniaplikáciu sa nepodarilo pridať."</string> <string name="ime_action_go" msgid="8320845651737369027">"Hľadať"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 80cb710..5280b06 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Programu omogoča pisanje na kartico SD."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"spreminjanje/brisanje vsebine notranje shrambe nosilca podatkov"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Programu omogoča spreminjanje vsebine notranje shrambe nosilca podatkov."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"upravljanje shranjevanja dokumentov"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Aplikaciji omogoči upravljanje shranjevanja dokumentov."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"dostop do zunanje naprave za shranjevanje za vse uporabnike"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Aplikaciji omogoča dostop do zunanje naprave za shranjevanje za vse uporabnike."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"dostop do datotečnega sistema predpomnilnika"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Programu omogoča pozivanje privzete storitve vsebnika, da kopira vsebino. Ni za uporabo z navadnimi programi."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Preusmeritev predstavnosti"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Aplikaciji omogoča preusmerjanje predstavnosti v druge zunanje naprave."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Dostop do varne shrambe Keyguard."</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Aplikaciji omogoča dostop do varne shrambe Keyguard."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Nadzira prikaz in skrivanje zaklepanja tipkovnice"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Aplikaciji omogoča nadzor zaklepanja tipkovnice."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Dvakrat se dotaknite za nadzor povečave/pomanjšave"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Pripomočka ni bilo mogoče dodati."</string> <string name="ime_action_go" msgid="8320845651737369027">"Pojdi"</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 0965b46..79a3d87 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Дозвољава апликацији да уписује податке на SD картицу."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"измена/брисање интерне меморије медија"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Дозвољава апликацији да мења садржај интерне меморије медијума."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"управ. складиштењем докумената"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Дозвољава апликацији да управља складиштењем докумената."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"приступ спољној меморији свих корисника"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Дозвољава апликацији да приступа спољној меморији за све кориснике."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"приступ систему датотека кеша"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Дозвољава апликацији да од подразумеване услуге контејнера захтева да копира садржај. Не користе је уобичајене апликације."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Усмеравање излаза медија"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Дозвољава апликацији да усмерава излаз медија на друге спољне уређаје."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Приступај безбедној меморији заштићеној шифром"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Дозвољава апликацији да приступа безбедној меморији заштићеној шифром."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Контролиши приказивање и скривање заштите шифром"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Дозвољава апликацији да контролише заштиту шифром."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Додирните двапут да бисте контролисали зум"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Није могуће додати виџет."</string> <string name="ime_action_go" msgid="8320845651737369027">"Иди"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 0df55b9..0775d0a 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Tillåter att appen skriver till SD-kortet."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"ändra/ta bort innehåll"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Tillåter att appen ändrar innehållet på den interna lagringsenheten."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"hantera dokumentlagring"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Tillåter att appen hanterar dokumentlagring."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"åtkomst till lagringsutrymme"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Tillåter att appen får åtkomst till en extern lagringsenhet för alla användare."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"åtkomst till cachefilsystemet"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Tillåter att appen kopierar innehåll genom att standardbehållartjänsten startas. Används inte av vanliga appar."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Omdirigera medieuppspelning"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Tillåter att appen omdirigerar medieuppspelningar till andra externa enheter."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Åtkomst till säkert keyguard-lagringsutrymme"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Tillåter att en app får åtkomst till säkert keyguard-lagringsutrymme."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Kontrollera hur knapplåset visas och döljs"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Tillåter att en app kontrollerar knapplåsfunktionen."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Tryck två gånger för zoomkontroll"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Det gick inte att lägga till widgeten."</string> <string name="ime_action_go" msgid="8320845651737369027">"Kör"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index c2d7dec..450e6a3 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Inaruhusu programu kuandikia kadi ya SD."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"badilisha/futa maudhui ya hifadhi ya media ya ndani."</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Inaruhusu programu kurekebisha maudhui ya hifadhi ya ndani vyombo vya habari."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"dhibiti hifadhi ya hati"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Huruhusu programu kudhibiti hifadhi ya hati."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"Fikia hifadhi ya nje ya watumiaji wote"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Inaruhusu programu kufikia hifadhi ya nje kwa watumiaji wote."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"fikia faili za mfumo za kache"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Inaruhusu programu kuomba huduma ya chombo chaguo-msingi kunakili maudhui. Si ya matumizi na programu za kawiada."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Fuatalia utoaji wa habari"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Inaruhusu programu kufuatilia utoaji wa habari kwa vifaa vingine vya nje."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Kufikia hifadhi salama ya ufunguo wa ulinzi"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Inaruhusu programu kufikia hifadhi salama ya ufunguo wa ulinzi."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Dhibiti uonyeshaji na ufichaji wa kilinda-funguo"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Huruhusu programu kudhibiti kilinda-funguo."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Gusa mara mbili kwa udhibiti cha kuza"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Haikuweza kuongeza wijeti."</string> <string name="ime_action_go" msgid="8320845651737369027">"Nenda"</string> diff --git a/core/res/res/values-sw600dp-land/arrays.xml b/core/res/res/values-sw600dp-land/arrays.xml index 5550216..5602a1c 100644 --- a/core/res/res/values-sw600dp-land/arrays.xml +++ b/core/res/res/values-sw600dp-land/arrays.xml @@ -19,54 +19,4 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- Resources for GlowPadView in LockScreen --> - <array name="lockscreen_targets_when_silent"> - <item>@drawable/ic_lockscreen_unlock</item> - <item>@null</item> - <item>@drawable/ic_lockscreen_soundon</item> - <item>@null</item> - </array> - - <array name="lockscreen_target_descriptions_when_silent"> - <item>@string/description_target_unlock</item> - <item>@null</item> - <item>@string/description_target_soundon</item> - <item>@null</item> - </array> - - <array name="lockscreen_direction_descriptions"> - <item>@string/description_direction_right</item> - <item>@null</item> - <item>@string/description_direction_left</item> - <item>@null</item> - </array> - - <array name="lockscreen_targets_when_soundon"> - <item>@drawable/ic_lockscreen_unlock</item> - <item>@null</item> - <item>@drawable/ic_lockscreen_silent</item> - <item>@null</item> - </array> - - <array name="lockscreen_target_descriptions_when_soundon"> - <item>@string/description_target_unlock</item> - <item>@null</item> - <item>@string/description_target_silent</item> - <item>@null</item> - </array> - - <array name="lockscreen_targets_with_camera"> - <item>@drawable/ic_lockscreen_unlock</item> - <item>@drawable/ic_action_assist_generic</item> - <item>@drawable/ic_lockscreen_camera</item> - <item>@null</item> - </array> - - <array name="lockscreen_target_descriptions_with_camera"> - <item>@string/description_target_unlock</item> - <item>@string/description_target_search</item> - <item>@string/description_target_camera</item> - <item>@null</item> - </array> - </resources> diff --git a/core/res/res/values-sw600dp/alias.xml b/core/res/res/values-sw600dp/alias.xml deleted file mode 100644 index bf3eecb..0000000 --- a/core/res/res/values-sw600dp/alias.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* //device/apps/common/assets/res/any/colors.xml -** -** Copyright 2012, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> -<resources> - <!-- Alias used to reference one of two possible layouts in keyguard. --> - <item type="layout" name="keyguard_eca">@android:layout/keyguard_emergency_carrier_area</item> -</resources> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 3010f0d..fd3ab94 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"อนุญาตให้แอปพลิเคชันเขียนลงบนการ์ด SD"</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"แก้/ลบเนื้อหาข้อมูลสื่อภายใน"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"อนุญาตให้แอปพลิเคชันแก้ไขเนื้อหาของที่เก็บข้อมูลสื่อภายใน"</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"จัดการที่เก็บเอกสาร"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"อนุญาตให้แอปจัดการที่เก็บเอกสาร"</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"เข้าถึงที่จัดเก็บภายนอกของทุกคน"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"อนุญาตให้แอปพลิเคชันเข้าถึงที่จัดเก็บข้อมูลภายนอกสำหรับผู้ใช้ทั้งหมด"</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"เข้าถึงระบบไฟล์แคช"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"อนุญาตให้แอปพลิเคชันเรียกใช้บริการที่เก็บค่าเริ่มต้นเพื่อคัดลอกเนื้อหา ไม่ใช้สำหรับแอปพลิเคชันทั่วไป"</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"กำหนดเส้นทางเอาต์พุตของสื่อ"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"อนุญาตให้แอปพลิเคชันกำหนดเส้นทางเอาต์พุตของสื่อไปยังอุปกรณ์ภายนอกอื่นๆ"</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"เข้าถึงพื้นที่จัดเก็บที่รักษาความปลอดภัยด้วยคีย์การ์ด"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"อนุญาตให้แอปพลิเคชันเข้าถึงพื้นที่จัดเก็บที่รักษาความปลอดภัยด้วยคีย์การ์ด"</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"ควบคุมการแสดงผลและการซ่อนตัวล็อกปุ่มกด"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"อนุญาตให้แอปพลิเคชันควบคุมตัวล็อกปุ่มกด"</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"แตะสองครั้งเพื่อควบคุมการซูม"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"ไม่สามารถเพิ่มวิดเจ็ต"</string> <string name="ime_action_go" msgid="8320845651737369027">"ไป"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index c64de9a..ce46219 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Pinapayagan ang app na magsulat sa SD card."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"baguhin/tanggalin ang mga nilalaman ng panloob na imbakan ng media"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Pinapayagan ang app na baguhin ang mga nilalaman ng panloob na media storage."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"pamahalaan document storage"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Pinapayagan ang app na pamahalaan ang storage ng dokumento."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"i-access panlabas na storage ng user"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Pinapayagan ang app na mag-access ng panlabas na storage para sa lahat ng user."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"i-access ang cache filesystem"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Pinapayagan ang app na i-apela ang default na serbisyo ng container upang kopyahin ang nilalaman. Hindi para sa paggamit ng normal na apps."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"I-route ang output ng media"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Pinapayagan ang application na mag-route ng output ng media sa iba pang mga panlabas na device."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"I-access ang secure na storage ng keyguard"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Nagbibigay-daan sa isang application na i-access ang secure na storage ng keyguard."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Kontrolin ang pagpapakita at pagtago sa keyguard"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Pinapayagan ang isang application na kontrolin ang keyguard."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Pindutin nang dalawang beses para sa pagkontrol ng zoom"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Hindi maidagdag ang widget."</string> <string name="ime_action_go" msgid="8320845651737369027">"Pumunta"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 8a3d85a..c6e8519 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Uygulamaya, SD karta yazma izni verir."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"dahili medya depolama birimi içeriğini değiştir/sil"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Uygulamaya, dahili medya depolama içeriğini değiştirme izni verir."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"doküman deposunu yönet"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Uygulamaya, doküman deposunu yönetme izni verir."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"tüm kullanıcılar için harici depolama eriş"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Uygulamaya tüm kullanıcılar için harici depolamaya erişim izni verir."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"önbellek dosya sistemine eriş"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Uygulamaya, içerik kopyalamak için varsayılan kapsayıcı hizmetini çağırma izni verir. Normal uygulamaların kullanımına yönelik değildir."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Medya çıktısını yönlendir"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Uygulamaya medya çıktısını başka harici cihazlara yönlendirme izni verir."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Tuş kilitli güvenli depolamaya erişim"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Bir uygulamanın tuş kilitli güvenli depolamaya erişimine izin verir."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Tuş koruyucuyu görüntülemeyi ve gizlemeyi kontrol et"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Bir uygulamaya tuş koruyucuyu denetleme izni verir."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Yakınlaştırma denetimi için iki kez dokunun"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget eklenemedi."</string> <string name="ime_action_go" msgid="8320845651737369027">"Git"</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 8a89a20..216a9b1 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Дозволяє програмі записувати на карту SD."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"змінювати/видаляти вміст внутр. сховища даних"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Дозволяє програмі змінювати вміст внутрішнього сховища даних."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"керувати зберіганням"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Дозволяє програмі керувати зберіганням документів."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"доступ до зовн. пам’яті всіх корист."</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Дозволяє програмі отримувати доступ до зовнішньої пам’яті всіх користувачів."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"отр. дост. до файл. сист. кешу"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Дозволяє програмі викликати службу контейнерів за умовчанням для копіювання вмісту. Не для використання звичайними програмами."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Скеровувати вивід медіа-даних"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Дозволяє програмі скеровувати вивід медіа-даних на інші зовнішні пристрої."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Отримувати доступ до безпечного сховища через клавіатуру"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Дозволяє програмі отримувати доступ до безпечного сховища через клавіатуру."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Керувати відображенням і хованням клавіатури"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Дозволяє програмі керувати клавіатурою."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Двічі торкніться, щоб керувати масштабом"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Не вдалося додати віджет."</string> <string name="ime_action_go" msgid="8320845651737369027">"Йти"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 57fe95a..7f076b9 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Cho phép ứng dụng ghi vào thẻ SD."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"sửa đổi/xóa nội dung trên bộ nhớ phương tiện cục bộ"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Cho phép ứng dụng sửa đổi nội dung của bộ lưu trữ phương tiện nội bộ."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"quản lý bộ nhớ tài liệu"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Cho phép ứng dụng quản lý bộ nhớ tài liệu."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"truy cập bộ nhớ ngoài của tất cả người dùng"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Cho phép ứng dụng truy cập bộ nhớ ngoài của tất cả người dùng."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"truy cập hệ thống tệp bộ nhớ cache"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Cho phép ứng dụng gọi ra dịch vụ bộ chứa mặc định để sao chép nội dung. Không dành cho ứng dụng thông thường."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Định tuyến thiết bị ra phương tiện"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Cho phép ứng dụng định tuyến thiết bị ra phương tiện đến các thiết bị bên ngoài khác."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Truy cập bộ nhớ an toàn khóa bàn phím"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Cho phép ứng dụng truy cập bộ nhớ an toàn khóa"</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Kiểm soát việc hiển thị và ẩn tính năng bảo vệ phím"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Cho phép ứng dụng kiểm soát tính năng bảo vệ phím."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Chạm hai lần để kiểm soát thu phóng"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Không thể thêm tiện ích."</string> <string name="ime_action_go" msgid="8320845651737369027">"Đến"</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index b131962..2e93751 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"允许应用写入 SD 卡。"</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"修改/删除内部媒体存储设备的内容"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"允许应用修改内部媒体存储设备的内容。"</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"管理文档存储空间"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"允许应用管理文档存储空间。"</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"访问所有用户的外部存储设备"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"允许应用访问所有用户的外部存储设备。"</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"访问缓存文件系统"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"允许应用调用默认的容器服务,以便复制内容。普通应用不应使用此权限。"</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"更改媒体输出线路"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"允许该应用将媒体输出线路更改到其他外部设备。"</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"访问密钥保护安全存储空间"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"允许应用访问密钥保护安全存储空间。"</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"控制是显示还是隐藏锁屏"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"允许应用控制锁屏。"</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"触摸两次可进行缩放控制"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"无法添加小部件。"</string> <string name="ime_action_go" msgid="8320845651737369027">"开始"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 6c3991a..5d55678 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"允許應用程式寫入 SD 卡。"</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"修改/刪除內部媒體儲存裝置內容"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"允許應用程式修改內部媒體儲存空間的內容。"</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"管理文件儲存空間"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"允許應用程式管理文件儲存空間。"</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"存取外部儲存空間 (所有使用者)"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"允許應用程式存取外部儲存空間 (所有使用者)。"</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"存取快取檔案系統"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"允許觸發預設容器服務,以便複製內容 (不建議一般應用程式使用)。"</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"轉送媒體輸出"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"允許應用程式將媒體輸出轉送至其他外部裝置。"</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"存取 Keyguard 安全儲存空間"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"允許應用程式存取 Keyguard 安全儲存空間。"</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"控制鍵盤鎖的顯示和隱藏"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"允許應用程式控制鍵盤鎖。"</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"輕觸兩下即可控制縮放"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"無法新增小工具。"</string> <string name="ime_action_go" msgid="8320845651737369027">"開始"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index f2e6d5e..df86b74 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -613,6 +613,8 @@ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Ivumela insiza ukuthi ibhalele ekhadini le-SD."</string> <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"guqula/susa okuqukethwe kwisitoreji semidiya yangaphakathi"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Ivumela insiza ukuthi iguqule okuqukethwe kokulondoloza imidiya yangaphakathi."</string> + <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"phatha isitoreji sedokhumenti"</string> + <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Ivumela uhlelo lokusebenza ukuthi luphathe isitoreji sedokhumenti."</string> <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"ukufinyelela isilondolozi sangaphandle sabo bonke abasebenzisi"</string> <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Vumela uhlelo lokusebenza ukufinyelela isilondolozi sangaphandle kubo bonke abasebenzisi."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"finyelela kunqolobane yesistimu yefayela"</string> @@ -1255,6 +1257,10 @@ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Ivumela insiza ukuthi inqabe okutholakala kukhona ukukopisha okuqukethwe. Akusetshenziswa izinsiza ezijwayelekile."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Yenza umzila wemidiya wokukhiphayo"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Ivumela uhlelo lokusebenza ukwenza umzila wokukhiphayo wemidiya kuya kumadivayisi angaphandle."</string> + <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Finyelela kusitoreji esiqashwa ngesikhiya esiphephile"</string> + <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Ivumela uhlelo lokusebenza ukuthi lufinyelele kusitoreji esiqashwa ngesikhiya esiphephile."</string> + <string name="permlab_control_keyguard" msgid="172195184207828387">"Lawula ukubonisa nokufihla ukhiye wokuqapha"</string> + <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Ivumela uhlelo lokusebenza ukuthi lulawule ukhiye wokuqapha."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Thinta kabili ukulawula ukusondeza"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Yehlulekile ukwengeza i-widget."</string> <string name="ime_action_go" msgid="8320845651737369027">"Iya"</string> diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml index 146607e..ef30b98 100644 --- a/core/res/res/values/arrays.xml +++ b/core/res/res/values/arrays.xml @@ -346,75 +346,4 @@ <item>中文 (繁體)</item> </string-array> - <!-- Resources for GlowPadView in LockScreen --> - <array name="lockscreen_targets_when_silent"> - <item>@drawable/ic_lockscreen_unlock</item> - <item>@drawable/ic_action_assist_generic</item> - <item>@drawable/ic_lockscreen_soundon</item> - <item>@null</item> - </array> - - <array name="lockscreen_target_descriptions_when_silent"> - <item>@string/description_target_unlock</item> - <item>@string/description_target_search</item> - <item>@string/description_target_soundon</item> - <item>@null</item> - </array> - - <array name="lockscreen_direction_descriptions"> - <item>@string/description_direction_right</item> - <item>@string/description_direction_up</item> - <item>@string/description_direction_left</item> - <item>@null</item> - </array> - - <array name="lockscreen_targets_when_soundon"> - <item>@drawable/ic_lockscreen_unlock</item> - <item>@drawable/ic_action_assist_generic</item> - <item>@drawable/ic_lockscreen_silent</item> - <item>@null</item> - </array> - - <array name="lockscreen_target_descriptions_when_soundon"> - <item>@string/description_target_unlock</item> - <item>@string/description_target_search</item> - <item>@string/description_target_silent</item> - <item>@null</item> - </array> - - <array name="lockscreen_targets_with_camera"> - <item>@drawable/ic_lockscreen_unlock</item> - <item>@drawable/ic_action_assist_generic</item> - <item>@drawable/ic_lockscreen_camera</item> - <item>@null</item> - </array> - - <array name="lockscreen_target_descriptions_with_camera"> - <item>@string/description_target_unlock</item> - <item>@string/description_target_search</item> - <item>@string/description_target_camera</item> - <item>@null</item> - </array> - - <array name="lockscreen_targets_unlock_only"> - <item>@*android:drawable/ic_lockscreen_unlock</item> - </array> - - <array name="lockscreen_target_descriptions_unlock_only"> - <item>@*android:string/description_target_unlock</item> - </array> - - <!-- list of 3- or 4-letter mnemonics for a 10-key numeric keypad --> - <string-array translatable="false" name="lockscreen_num_pad_klondike"> - <item></item><!-- 0 --> - <item></item><!-- 1 --> - <item>ABC</item><!-- 2 --> - <item>DEF</item><!-- 3 --> - <item>GHI</item><!-- 4 --> - <item>JKL</item><!-- 5 --> - <item>MNO</item><!-- 6 --> - <item>PQRS</item><!-- 7 --> - <item>TUV</item><!-- 8 --> - <item>WXYZ</item><!-- 9 --> - </string-array> </resources> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 4dcbaec..459a634 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -4057,10 +4057,6 @@ <attr name="drawable" /> </declare-styleable> - <declare-styleable name="MipmapDrawableItem"> - <attr name="drawable" /> - </declare-styleable> - <!-- Drawable used to rotate another drawable. --> <declare-styleable name="RotateDrawable"> <attr name="visible" /> @@ -4408,6 +4404,28 @@ </declare-styleable> <!-- ========================== --> + <!-- State class attributes --> + <!-- ========================== --> + <eat-comment /> + + <declare-styleable name="Scene"> + <attr name="layout" /> + </declare-styleable> + + <declare-styleable name="Transition"> + <attr name="duration" /> + <attr name="startOffset" /> + <attr name="interpolator" /> + <attr name="targetID" format="reference" /> + </declare-styleable> + + <declare-styleable name="TransitionManager"> + <attr name="transition" format="reference" /> + <attr name="fromScene" format="reference" /> + <attr name="toScene" format="reference" /> + </declare-styleable> + + <!-- ========================== --> <!-- ValueAnimator class attributes --> <!-- ========================== --> <eat-comment /> diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index e7f6c53..0aaa5b7 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -1781,4 +1781,12 @@ <!-- Concrete value to put for this named extra data. --> <attr name="value" /> </declare-styleable> + + <attr name="keyset" /> + <declare-styleable name="PublicKey"> + <attr name="value" /> + </declare-styleable> + <declare-styleable name="KeySet"> + <attr name="name" /> + </declare-styleable> </resources> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 2d97138..089a859 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2052,4 +2052,15 @@ <public type="style" name="Theme.DeviceDefault.NoActionBar.Overscan" id="0x010301df" /> <public type="style" name="Theme.DeviceDefault.Light.NoActionBar.Overscan" id="0x010301e0" /> +<!-- =============================================================== + Resources added in version 19 of the platform + =============================================================== --> + <eat-comment /> + + <public type="attr" name="keyset" /> + <public type="attr" name="targetID" /> + <public type="attr" name="fromScene" /> + <public type="attr" name="toScene" /> + <public type="attr" name="transition" /> + </resources> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index b595d6e..d40eb64 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1797,6 +1797,11 @@ <string name="permdesc_mediaStorageWrite" product="default">Allows the app to modify the contents of the internal media storage.</string> <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=30] --> + <string name="permlab_manageDocs" product="default">manage document storage</string> + <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE] --> + <string name="permdesc_manageDocs" product="default">Allows the app to manage document storage.</string> + + <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=30] --> <string name="permlab_sdcardAccessAll">access external storage of all users</string> <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permdesc_sdcardAccessAll">Allows the app to access external storage for all users.</string> @@ -3469,6 +3474,16 @@ <!-- Description of an application permission that lets an application route media output. --> <string name="permdesc_route_media_output">Allows an application to route media output to other external devices.</string> + <!-- Title of an application permission that lets an application access keyguard secure storage. --> + <string name="permlab_access_keyguard_secure_storage">Access keyguard secure storage</string> + <!-- Description of an application permission that lets an application access keyguard secure storage. --> + <string name="permdesc_access_keyguard_secure_storage">Allows an application to access keguard secure storage.</string> + + <!-- Title of an application permission that lets it control keyguard. --> + <string name="permlab_control_keyguard">Control displaying and hiding keyguard</string> + <!-- Description of an application permission that lets it control keyguard. --> + <string name="permdesc_control_keyguard">Allows an application to control keguard.</string> + <!-- Shown in the tutorial for tap twice for zoom control. --> <string name="tutorial_double_tap_to_zoom_message_short">Touch twice for zoom control</string> @@ -4108,7 +4123,7 @@ <!-- Error message title [CHAR LIMIT=35] --> <string name="error_message_title">Error</string> <!-- Message informing user that app is not permitted to access accounts. [CHAR LIMIT=none] --> - <string name="app_no_restricted_accounts">This application does not support accounts for restricted profiles</string> + <string name="app_no_restricted_accounts">This app doesn\'t support accounts for restricted profiles</string> <!-- Message informing user that the requested activity could not be found [CHAR LIMIT=none] --> <string name="app_not_found">No application found to handle this action</string> <string name="revoke">Revoke</string> diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index f494d8c..bd82f35 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -138,6 +138,12 @@ please see styles_device_defaults.xml. <item name="windowExitAnimation">@anim/submenu_exit</item> </style> + <!-- {@hide} --> + <style name="Animation.ToastBar"> + <item name="windowEnterAnimation">@anim/toast_bar_enter</item> + <item name="windowExitAnimation">@anim/toast_bar_exit</item> + </style> + <style name="Animation.TypingFilter"> <item name="windowEnterAnimation">@anim/grow_fade_in_center</item> <item name="windowExitAnimation">@anim/shrink_fade_out_center</item> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 3ecdc0c..3718220 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -38,16 +38,12 @@ <java-symbol type="id" name="action_menu_presenter" /> <java-symbol type="id" name="action_mode_close_button" /> <java-symbol type="id" name="activity_chooser_view_content" /> - <java-symbol type="id" name="albumart" /> <java-symbol type="id" name="alertTitle" /> <java-symbol type="id" name="allow_button" /> <java-symbol type="id" name="alwaysUse" /> <java-symbol type="id" name="amPm" /> <java-symbol type="id" name="authtoken_type" /> <java-symbol type="id" name="back_button" /> - <java-symbol type="id" name="btn_next" /> - <java-symbol type="id" name="btn_play" /> - <java-symbol type="id" name="btn_prev" /> <java-symbol type="id" name="button_bar" /> <java-symbol type="id" name="buttonPanel" /> <java-symbol type="id" name="by_common" /> @@ -572,26 +568,6 @@ <java-symbol type="string" name="keyboardview_keycode_enter" /> <java-symbol type="string" name="keyboardview_keycode_mode_change" /> <java-symbol type="string" name="keyboardview_keycode_shift" /> - <java-symbol type="string" name="keyguard_accessibility_add_widget" /> - <java-symbol type="string" name="keyguard_accessibility_camera" /> - <java-symbol type="string" name="keyguard_accessibility_expand_lock_area" /> - <java-symbol type="string" name="keyguard_accessibility_face_unlock" /> - <java-symbol type="string" name="keygaurd_accessibility_media_controls" /> - <java-symbol type="string" name="keyguard_accessibility_pattern_area" /> - <java-symbol type="string" name="keyguard_accessibility_pattern_unlock" /> - <java-symbol type="string" name="keyguard_accessibility_password_unlock" /> - <java-symbol type="string" name="keyguard_accessibility_pin_unlock" /> - <java-symbol type="string" name="keyguard_accessibility_slide_area" /> - <java-symbol type="string" name="keyguard_accessibility_slide_unlock" /> - <java-symbol type="string" name="keyguard_accessibility_status" /> - <java-symbol type="string" name="keyguard_accessibility_user_selector" /> - <java-symbol type="string" name="keyguard_accessibility_widget" /> - <java-symbol type="string" name="keyguard_accessibility_widget_deleted" /> - <java-symbol type="string" name="keyguard_accessibility_widget_empty_slot" /> - <java-symbol type="string" name="keyguard_accessibility_widget_reorder_start" /> - <java-symbol type="string" name="keyguard_accessibility_widget_reorder_end" /> - <java-symbol type="string" name="keyguard_accessibility_unlock_area_collapsed" /> - <java-symbol type="string" name="keyguard_accessibility_unlock_area_expanded" /> <java-symbol type="string" name="kilobyteShort" /> <java-symbol type="string" name="last_month" /> <java-symbol type="string" name="launchBrowserDefault" /> @@ -601,9 +577,6 @@ <java-symbol type="string" name="lockscreen_access_pattern_start" /> <java-symbol type="string" name="lockscreen_emergency_call" /> <java-symbol type="string" name="lockscreen_return_to_call" /> - <java-symbol type="string" name="lockscreen_transport_pause_description" /> - <java-symbol type="string" name="lockscreen_transport_play_description" /> - <java-symbol type="string" name="lockscreen_transport_stop_description" /> <java-symbol type="string" name="low_memory" /> <java-symbol type="string" name="media_bad_removal" /> <java-symbol type="string" name="media_checking" /> @@ -1018,21 +991,17 @@ <java-symbol type="drawable" name="text_select_handle_left" /> <java-symbol type="drawable" name="text_select_handle_middle" /> <java-symbol type="drawable" name="text_select_handle_right" /> + <java-symbol type="drawable" name="toast_bar_bg" /> <java-symbol type="drawable" name="unknown_image" /> <java-symbol type="drawable" name="unlock_default" /> <java-symbol type="drawable" name="unlock_halo" /> <java-symbol type="drawable" name="unlock_ring" /> <java-symbol type="drawable" name="unlock_wave" /> - <java-symbol type="drawable" name="ic_lockscreen_camera" /> - <java-symbol type="drawable" name="ic_lockscreen_silent" /> - <java-symbol type="drawable" name="ic_lockscreen_unlock" /> <java-symbol type="drawable" name="ic_action_assist_generic" /> - <java-symbol type="drawable" name="ic_lockscreen_alarm" /> <java-symbol type="drawable" name="notification_bg" /> <java-symbol type="drawable" name="notification_bg_low" /> <java-symbol type="drawable" name="notification_template_icon_bg" /> <java-symbol type="drawable" name="notification_template_icon_low_bg" /> - <java-symbol type="drawable" name="ic_lockscreen_unlock_phantom" /> <java-symbol type="drawable" name="ic_media_route_on_holo_dark" /> <java-symbol type="drawable" name="ic_media_route_disabled_holo_dark" /> @@ -1111,6 +1080,7 @@ <java-symbol type="layout" name="textview_hint" /> <java-symbol type="layout" name="time_picker" /> <java-symbol type="layout" name="time_picker_dialog" /> + <java-symbol type="layout" name="toast_bar" /> <java-symbol type="layout" name="transient_notification" /> <java-symbol type="layout" name="volume_adjust" /> <java-symbol type="layout" name="volume_adjust_item" /> @@ -1132,10 +1102,7 @@ <java-symbol type="layout" name="notification_template_part_time" /> <java-symbol type="layout" name="notification_template_part_chronometer" /> <java-symbol type="layout" name="notification_template_inbox" /> - <java-symbol type="layout" name="keyguard_multi_user_avatar" /> - <java-symbol type="layout" name="keyguard_multi_user_selector_widget" /> <java-symbol type="layout" name="sms_short_code_confirmation_dialog" /> - <java-symbol type="layout" name="keyguard_add_widget" /> <java-symbol type="layout" name="action_bar_up_container" /> <java-symbol type="layout" name="app_not_authorized" /> @@ -1153,7 +1120,6 @@ <java-symbol type="xml" name="password_kbd_qwerty_shifted" /> <java-symbol type="xml" name="password_kbd_symbols" /> <java-symbol type="xml" name="password_kbd_symbols_shift" /> - <java-symbol type="xml" name="kg_password_kbd_numeric" /> <java-symbol type="xml" name="power_profile" /> <java-symbol type="xml" name="time_zones_by_country" /> <java-symbol type="xml" name="sms_short_codes" /> @@ -1168,6 +1134,7 @@ <java-symbol type="style" name="Animation.DropDownUp" /> <java-symbol type="style" name="Animation.DropDownDown" /> <java-symbol type="style" name="Animation.PopupWindow" /> + <java-symbol type="style" name="Animation.ToastBar" /> <java-symbol type="style" name="Animation.TypingFilter" /> <java-symbol type="style" name="Animation.TypingFilterRestore" /> <java-symbol type="style" name="Animation.Dream" /> @@ -1207,8 +1174,6 @@ <!-- From android.policy --> <java-symbol type="anim" name="app_starting_exit" /> - <java-symbol type="anim" name="lock_screen_behind_enter" /> - <java-symbol type="anim" name="lock_screen_wallpaper_behind_enter" /> <java-symbol type="anim" name="dock_top_enter" /> <java-symbol type="anim" name="dock_top_exit" /> <java-symbol type="anim" name="dock_bottom_enter" /> @@ -1217,22 +1182,12 @@ <java-symbol type="anim" name="dock_left_exit" /> <java-symbol type="anim" name="dock_right_enter" /> <java-symbol type="anim" name="dock_right_exit" /> - <java-symbol type="anim" name="keyguard_security_animate_in" /> - <java-symbol type="anim" name="keyguard_security_animate_out" /> - <java-symbol type="anim" name="keyguard_security_fade_in" /> - <java-symbol type="anim" name="keyguard_security_fade_out" /> - <java-symbol type="anim" name="keyguard_action_assist_exit" /> - <java-symbol type="anim" name="keyguard_action_assist_enter" /> <java-symbol type="array" name="config_keyboardTapVibePattern" /> <java-symbol type="array" name="config_longPressVibePattern" /> <java-symbol type="array" name="config_safeModeDisabledVibePattern" /> <java-symbol type="array" name="config_safeModeEnabledVibePattern" /> <java-symbol type="array" name="config_virtualKeyVibePattern" /> - <java-symbol type="array" name="lockscreen_targets_when_silent" /> - <java-symbol type="array" name="lockscreen_targets_when_soundon" /> - <java-symbol type="array" name="lockscreen_targets_with_camera" /> - <java-symbol type="array" name="lockscreen_num_pad_klondike" /> <java-symbol type="attr" name="actionModePopupWindowStyle" /> <java-symbol type="attr" name="dialogCustomTitleDecorLayout" /> <java-symbol type="attr" name="dialogTitleDecorLayout" /> @@ -1247,33 +1202,11 @@ <java-symbol type="bool" name="config_lidControlsSleep" /> <java-symbol type="bool" name="config_reverseDefaultRotation" /> <java-symbol type="bool" name="config_showNavigationBar" /> - <java-symbol type="bool" name="kg_enable_camera_default_widget" /> - <java-symbol type="bool" name="kg_share_status_area" /> - <java-symbol type="bool" name="kg_sim_puk_account_full_screen" /> - <java-symbol type="bool" name="kg_top_align_page_shrink_on_bouncer_visible" /> <java-symbol type="bool" name="target_honeycomb_needs_options_menu" /> - <java-symbol type="bool" name="kg_center_small_widgets_vertically" /> - <java-symbol type="bool" name="kg_show_ime_at_screen_on" /> - <java-symbol type="color" name="kg_multi_user_text_active" /> - <java-symbol type="color" name="kg_multi_user_text_inactive" /> - <java-symbol type="color" name="kg_widget_pager_gradient" /> - <java-symbol type="color" name="keyguard_avatar_frame_color" /> - <java-symbol type="color" name="keyguard_avatar_frame_pressed_color" /> - <java-symbol type="color" name="keyguard_avatar_frame_shadow_color" /> - <java-symbol type="color" name="keyguard_avatar_nick_color" /> <java-symbol type="dimen" name="navigation_bar_height" /> <java-symbol type="dimen" name="navigation_bar_height_landscape" /> <java-symbol type="dimen" name="navigation_bar_width" /> <java-symbol type="dimen" name="status_bar_height" /> - <java-symbol type="dimen" name="kg_widget_pager_horizontal_padding" /> - <java-symbol type="dimen" name="kg_widget_pager_top_padding" /> - <java-symbol type="dimen" name="kg_widget_pager_bottom_padding" /> - <java-symbol type="dimen" name="keyguard_avatar_size" /> - <java-symbol type="dimen" name="keyguard_avatar_frame_stroke_width" /> - <java-symbol type="dimen" name="keyguard_avatar_frame_shadow_radius" /> - <java-symbol type="dimen" name="kg_edge_swipe_region_size" /> - <java-symbol type="dimen" name="kg_squashed_layout_threshold" /> - <java-symbol type="dimen" name="kg_small_widget_height" /> <java-symbol type="drawable" name="ic_jog_dial_sound_off" /> <java-symbol type="drawable" name="ic_jog_dial_sound_on" /> <java-symbol type="drawable" name="ic_jog_dial_unlock" /> @@ -1292,9 +1225,7 @@ <java-symbol type="drawable" name="magnified_region_frame" /> <java-symbol type="drawable" name="menu_background" /> <java-symbol type="drawable" name="stat_sys_secure" /> - <java-symbol type="drawable" name="kg_widget_bg_padded" /> <java-symbol type="id" name="action_mode_bar_stub" /> - <java-symbol type="id" name="alarm_status" /> <java-symbol type="id" name="button0" /> <java-symbol type="id" name="button4" /> <java-symbol type="id" name="button5" /> @@ -1302,15 +1233,12 @@ <java-symbol type="id" name="button7" /> <java-symbol type="id" name="date" /> <java-symbol type="id" name="eight" /> - <java-symbol type="id" name="face_unlock_area_view" /> - <java-symbol type="id" name="face_unlock_cancel_button" /> <java-symbol type="id" name="five" /> <java-symbol type="id" name="four" /> <java-symbol type="id" name="icon_menu_presenter" /> <java-symbol type="id" name="keyboard" /> <java-symbol type="id" name="list_menu_presenter" /> <java-symbol type="id" name="lock_screen" /> - <java-symbol type="id" name="login" /> <java-symbol type="id" name="nine" /> <java-symbol type="id" name="no_applications_message" /> <java-symbol type="id" name="ok" /> @@ -1318,57 +1246,14 @@ <java-symbol type="id" name="option1" /> <java-symbol type="id" name="option2" /> <java-symbol type="id" name="option3" /> - <java-symbol type="id" name="password" /> - <java-symbol type="id" name="passwordEntry" /> - <java-symbol type="id" name="pinEntry" /> <java-symbol type="id" name="right_icon" /> <java-symbol type="id" name="seven" /> <java-symbol type="id" name="six" /> <java-symbol type="id" name="status" /> - <java-symbol type="id" name="switch_ime_button" /> <java-symbol type="id" name="three" /> <java-symbol type="id" name="title_container" /> <java-symbol type="id" name="two" /> <java-symbol type="id" name="zero" /> - <java-symbol type="id" name="keyguard_message_area" /> - <java-symbol type="id" name="keyguard_click_area" /> - <java-symbol type="id" name="keyguard_selector_view" /> - <java-symbol type="id" name="keyguard_pattern_view" /> - <java-symbol type="id" name="keyguard_password_view" /> - <java-symbol type="id" name="keyguard_pin_view" /> - <java-symbol type="id" name="keyguard_face_unlock_view" /> - <java-symbol type="id" name="keyguard_sim_pin_view" /> - <java-symbol type="id" name="keyguard_sim_puk_view" /> - <java-symbol type="id" name="keyguard_account_view" /> - <java-symbol type="id" name="keyguard_selector_fade_container" /> - <java-symbol type="id" name="keyguard_widget_pager_delete_target" /> - <java-symbol type="id" name="keyguard_bouncer_frame" /> - <java-symbol type="id" name="app_widget_container" /> - <java-symbol type="id" name="view_flipper" /> - <java-symbol type="id" name="carrier_text" /> - <java-symbol type="id" name="emergency_call_button" /> - <java-symbol type="id" name="keyguard_host_view" /> - <java-symbol type="id" name="delete_button" /> - <java-symbol type="id" name="lockPatternView" /> - <java-symbol type="id" name="forgot_password_button" /> - <java-symbol type="id" name="glow_pad_view" /> - <java-symbol type="id" name="delete_button" /> - <java-symbol type="id" name="keyguard_user_avatar" /> - <java-symbol type="id" name="keyguard_user_name" /> - <java-symbol type="id" name="keyguard_transport_control" /> - <java-symbol type="id" name="keyguard_status_view" /> - <java-symbol type="id" name="keyguard_status_view_face_palm" /> - <java-symbol type="id" name="keyguard_users_grid" /> - <java-symbol type="id" name="clock_text" /> - <java-symbol type="id" name="clock_view" /> - <java-symbol type="id" name="keyguard_multi_user_selector" /> - <java-symbol type="id" name="sliding_layout" /> - <java-symbol type="id" name="keyguard_add_widget" /> - <java-symbol type="id" name="keyguard_add_widget_view" /> - <java-symbol type="id" name="multi_pane_challenge" /> - <java-symbol type="id" name="keyguard_user_selector" /> - <java-symbol type="id" name="key_enter" /> - <java-symbol type="id" name="keyguard_selector_view_frame" /> <java-symbol type="integer" name="config_carDockRotation" /> <java-symbol type="integer" name="config_defaultUiModeType" /> <java-symbol type="integer" name="config_deskDockRotation" /> @@ -1377,18 +1262,8 @@ <java-symbol type="integer" name="config_lidNavigationAccessibility" /> <java-symbol type="integer" name="config_lidOpenRotation" /> <java-symbol type="integer" name="config_longPressOnHomeBehavior" /> - <java-symbol type="integer" name="kg_security_flip_duration" /> - <java-symbol type="integer" name="kg_carousel_angle" /> <java-symbol type="layout" name="global_actions_item" /> <java-symbol type="layout" name="global_actions_silent_mode" /> - <java-symbol type="layout" name="keyguard_selector_view" /> - <java-symbol type="layout" name="keyguard_pattern_view" /> - <java-symbol type="layout" name="keyguard_password_view" /> - <java-symbol type="layout" name="keyguard_pin_view" /> - <java-symbol type="layout" name="keyguard_face_unlock_view" /> - <java-symbol type="layout" name="keyguard_sim_pin_view" /> - <java-symbol type="layout" name="keyguard_sim_puk_view" /> - <java-symbol type="layout" name="keyguard_account_view" /> <java-symbol type="layout" name="recent_apps_dialog" /> <java-symbol type="layout" name="screen_action_bar" /> <java-symbol type="layout" name="screen_custom_title" /> @@ -1397,9 +1272,6 @@ <java-symbol type="layout" name="screen_simple_overlay_action_mode" /> <java-symbol type="layout" name="screen_title" /> <java-symbol type="layout" name="screen_title_icons" /> - <java-symbol type="layout" name="keyguard_host_view" /> - <java-symbol type="layout" name="keyguard_transport_control_view" /> - <java-symbol type="layout" name="keyguard_status_view" /> <java-symbol type="string" name="abbrev_wday_month_day_no_year" /> <java-symbol type="string" name="system_ui_date_pattern" /> <java-symbol type="string" name="android_upgrading_title" /> @@ -1415,41 +1287,7 @@ <java-symbol type="string" name="global_action_silent_mode_on_status" /> <java-symbol type="string" name="global_action_toggle_silent_mode" /> <java-symbol type="string" name="invalidPuk" /> - <java-symbol type="string" name="keyguard_password_enter_pin_code" /> - <java-symbol type="string" name="keyguard_password_enter_puk_code" /> - <java-symbol type="string" name="keyguard_password_wrong_pin_code" /> <java-symbol type="string" name="lockscreen_carrier_default" /> - <java-symbol type="string" name="lockscreen_charged" /> - <java-symbol type="string" name="lockscreen_failed_attempts_almost_at_wipe" /> - <java-symbol type="string" name="lockscreen_failed_attempts_almost_glogin" /> - <java-symbol type="string" name="lockscreen_failed_attempts_now_wiping" /> - <java-symbol type="string" name="lockscreen_forgot_pattern_button_text" /> - <java-symbol type="string" name="lockscreen_glogin_checking_password" /> - <java-symbol type="string" name="lockscreen_glogin_forgot_pattern" /> - <java-symbol type="string" name="lockscreen_glogin_invalid_input" /> - <java-symbol type="string" name="lockscreen_glogin_too_many_attempts" /> - <java-symbol type="string" name="lockscreen_instructions_when_pattern_disabled" /> - <java-symbol type="string" name="lockscreen_low_battery" /> - <java-symbol type="string" name="lockscreen_missing_sim_instructions" /> - <java-symbol type="string" name="lockscreen_missing_sim_instructions_long" /> - <java-symbol type="string" name="lockscreen_missing_sim_message_short" /> - <java-symbol type="string" name="lockscreen_network_locked_message" /> - <java-symbol type="string" name="lockscreen_password_wrong" /> - <java-symbol type="string" name="lockscreen_pattern_instructions" /> - <java-symbol type="string" name="lockscreen_pattern_wrong" /> - <java-symbol type="string" name="lockscreen_permanent_disabled_sim_message_short" /> - <java-symbol type="string" name="lockscreen_permanent_disabled_sim_instructions" /> - <java-symbol type="string" name="lockscreen_plugged_in" /> - <java-symbol type="string" name="lockscreen_sim_locked_message" /> - <java-symbol type="string" name="lockscreen_sim_puk_locked_message" /> - <java-symbol type="string" name="lockscreen_sim_unlock_progress_dialog_message" /> - <java-symbol type="string" name="lockscreen_sound_off_label" /> - <java-symbol type="string" name="lockscreen_sound_on_label" /> - <java-symbol type="string" name="lockscreen_too_many_failed_attempts_countdown" /> - <java-symbol type="string" name="lockscreen_too_many_failed_attempts_dialog_message" /> - <java-symbol type="string" name="lockscreen_too_many_failed_password_attempts_dialog_message" /> - <java-symbol type="string" name="lockscreen_too_many_failed_pin_attempts_dialog_message" /> - <java-symbol type="string" name="lockscreen_unlock_label" /> <java-symbol type="string" name="status_bar_device_locked" /> <java-symbol type="style" name="Animation.LockScreen" /> <java-symbol type="style" name="Theme.Dialog.RecentApplications" /> @@ -1457,40 +1295,6 @@ <java-symbol type="style" name="Widget.Button.NumPadKey" /> <java-symbol type="style" name="TextAppearance.NumPadKey" /> <java-symbol type="style" name="TextAppearance.NumPadKey.Klondike" /> - <java-symbol type="string" name="kg_emergency_call_label" /> - <java-symbol type="string" name="kg_forgot_pattern_button_text" /> - <java-symbol type="string" name="kg_wrong_pattern" /> - <java-symbol type="string" name="kg_wrong_password" /> - <java-symbol type="string" name="kg_wrong_pin" /> - <java-symbol type="string" name="kg_too_many_failed_attempts_countdown" /> - <java-symbol type="string" name="kg_pattern_instructions" /> - <java-symbol type="string" name="kg_sim_pin_instructions" /> - <java-symbol type="string" name="kg_pin_instructions" /> - <java-symbol type="string" name="kg_password_instructions" /> - <java-symbol type="string" name="kg_puk_enter_puk_hint" /> - <java-symbol type="string" name="kg_puk_enter_pin_hint" /> - <java-symbol type="string" name="kg_sim_unlock_progress_dialog_message" /> - <java-symbol type="string" name="kg_password_wrong_pin_code" /> - <java-symbol type="string" name="kg_invalid_sim_pin_hint" /> - <java-symbol type="string" name="kg_invalid_sim_puk_hint" /> - <java-symbol type="string" name="kg_invalid_puk" /> - <java-symbol type="string" name="kg_login_too_many_attempts" /> - <java-symbol type="string" name="kg_login_instructions" /> - <java-symbol type="string" name="kg_login_username_hint" /> - <java-symbol type="string" name="kg_login_password_hint" /> - <java-symbol type="string" name="kg_login_submit_button" /> - <java-symbol type="string" name="kg_login_invalid_input" /> - <java-symbol type="string" name="kg_login_account_recovery_hint" /> - <java-symbol type="string" name="kg_login_checking_password" /> - <java-symbol type="string" name="kg_too_many_failed_pin_attempts_dialog_message" /> - <java-symbol type="string" name="kg_too_many_failed_pattern_attempts_dialog_message" /> - <java-symbol type="string" name="kg_too_many_failed_password_attempts_dialog_message" /> - <java-symbol type="string" name="kg_failed_attempts_almost_at_wipe" /> - <java-symbol type="string" name="kg_failed_attempts_now_wiping" /> - <java-symbol type="string" name="kg_failed_attempts_almost_at_login" /> - <java-symbol type="string" name="kg_enter_confirm_pin_hint" /> - <java-symbol type="string" name="kg_invalid_confirm_pin_hint" /> - <java-symbol type="string" name="kg_text_message_separator" /> <!-- From services --> <java-symbol type="anim" name="screen_rotate_0_enter" /> @@ -1717,6 +1521,9 @@ <java-symbol type="anim" name="push_down_out" /> <java-symbol type="anim" name="push_up_in" /> <java-symbol type="anim" name="push_up_out" /> + <java-symbol type="anim" name="lock_screen_wallpaper_behind_enter" /> + <java-symbol type="anim" name="lock_screen_behind_enter" /> + <java-symbol type="bool" name="config_alwaysUseCdmaRssi" /> <java-symbol type="dimen" name="status_bar_icon_size" /> <java-symbol type="dimen" name="system_bar_icon_size" /> |