diff options
Diffstat (limited to 'core')
146 files changed, 3618 insertions, 2175 deletions
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java index a4d28b0..7a9f285 100644 --- a/core/java/android/accounts/AccountManagerService.java +++ b/core/java/android/accounts/AccountManagerService.java @@ -369,7 +369,7 @@ public class AccountManagerService } private void onUserRemoved(Intent intent) { - int userId = intent.getIntExtra(Intent.EXTRA_USERID, -1); + int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); if (userId < 1) return; UserAccounts accounts; @@ -900,7 +900,7 @@ public class AccountManagerService private void sendAccountsChangedBroadcast(int userId) { Log.i(TAG, "the accounts changed, sending broadcast of " + ACCOUNTS_CHANGED_INTENT.getAction()); - mContext.sendBroadcastToUser(ACCOUNTS_CHANGED_INTENT, userId); + mContext.sendBroadcastAsUser(ACCOUNTS_CHANGED_INTENT, new UserHandle(userId)); } public void clearPassword(Account account) { diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java index 107e980..f874d56 100755 --- a/core/java/android/animation/ValueAnimator.java +++ b/core/java/android/animation/ValueAnimator.java @@ -536,6 +536,9 @@ public class ValueAnimator extends Animator { // The per-thread list of all active animations private final ArrayList<ValueAnimator> mAnimations = new ArrayList<ValueAnimator>(); + // Used in doAnimationFrame() to avoid concurrent modifications of mAnimations + private final ArrayList<ValueAnimator> mTmpAnimations = new ArrayList<ValueAnimator>(); + // The per-thread set of animations to be started on the next animation frame private final ArrayList<ValueAnimator> mPendingAnimations = new ArrayList<ValueAnimator>(); @@ -605,28 +608,18 @@ public class ValueAnimator extends Animator { // Now process all active animations. The return value from animationFrame() // tells the handler whether it should now be ended int numAnims = mAnimations.size(); - int i = 0; - while (i < numAnims) { - ValueAnimator anim = mAnimations.get(i); - if (anim.doAnimationFrame(frameTime)) { + for (int i = 0; i < numAnims; ++i) { + mTmpAnimations.add(mAnimations.get(i)); + } + for (int i = 0; i < numAnims; ++i) { + ValueAnimator anim = mTmpAnimations.get(i); + if (mAnimations.contains(anim) && anim.doAnimationFrame(frameTime)) { mEndingAnims.add(anim); } - if (mAnimations.size() == numAnims) { - ++i; - } else { - // An animation might be canceled or ended by client code - // during the animation frame. Check to see if this happened by - // seeing whether the current index is the same as it was before - // calling animationFrame(). Another approach would be to copy - // animations to a temporary list and process that list instead, - // but that entails garbage and processing overhead that would - // be nice to avoid. - --numAnims; - mEndingAnims.remove(anim); - } } + mTmpAnimations.clear(); if (mEndingAnims.size() > 0) { - for (i = 0; i < mEndingAnims.size(); ++i) { + for (int i = 0; i < mEndingAnims.size(); ++i) { mEndingAnims.get(i).endAnimation(this); } mEndingAnims.clear(); diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 809acac..395a79c 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -74,7 +74,7 @@ import android.view.ViewGroup.LayoutParams; import android.view.ViewManager; import android.view.Window; import android.view.WindowManager; -import android.view.WindowManagerImpl; +import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityEvent; import android.widget.AdapterView; @@ -4733,6 +4733,29 @@ public class Activity extends ContextThemeWrapper mLoaderManager.dump(prefix + " ", fd, writer, args); } mFragments.dump(prefix, fd, writer, args); + writer.print(prefix); writer.println("View Hierarchy:"); + dumpViewHierarchy(prefix + " ", writer, getWindow().getDecorView()); + } + + private void dumpViewHierarchy(String prefix, PrintWriter writer, View view) { + writer.print(prefix); + if (view == null) { + writer.println("null"); + return; + } + writer.println(view.toString()); + if (!(view instanceof ViewGroup)) { + return; + } + ViewGroup grp = (ViewGroup)view; + final int N = grp.getChildCount(); + if (N <= 0) { + return; + } + prefix = prefix + " "; + for (int i=0; i<N; i++) { + dumpViewHierarchy(prefix, writer, grp.getChildAt(i)); + } } /** @@ -4995,7 +5018,9 @@ public class Activity extends ContextThemeWrapper mEmbeddedID = id; mLastNonConfigurationInstances = lastNonConfigurationInstances; - mWindow.setWindowManager(null, mToken, mComponent.flattenToString(), + mWindow.setWindowManager( + (WindowManager)context.getSystemService(Context.WINDOW_SERVICE), + mToken, mComponent.flattenToString(), (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0); if (mParent != null) { mWindow.setContainer(mParent.getWindow()); @@ -5042,7 +5067,7 @@ public class Activity extends ContextThemeWrapper if (mStopped) { mStopped = false; if (mToken != null && mParent == null) { - WindowManagerImpl.getDefault().setStoppedState(mToken, false); + WindowManagerGlobal.getInstance().setStoppedState(mToken, false); } synchronized (mManagedCursors) { @@ -5142,7 +5167,7 @@ public class Activity extends ContextThemeWrapper } if (mToken != null && mParent == null) { - WindowManagerImpl.getDefault().setStoppedState(mToken, true); + WindowManagerGlobal.getInstance().setStoppedState(mToken, true); } mFragments.dispatchStop(); diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 2c6d5d9..e644db4 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -30,6 +30,7 @@ import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Point; +import android.hardware.display.DisplayManager; import android.os.Binder; import android.os.Bundle; import android.os.Debug; @@ -366,7 +367,7 @@ public class ActivityManager { * (which tends to consume a lot more RAM). * @hide */ - static public boolean isHighEndGfx(Display display) { + static public boolean isHighEndGfx() { MemInfoReader reader = new MemInfoReader(); reader.readMemInfo(); if (reader.getTotalSize() >= (512*1024*1024)) { @@ -374,6 +375,8 @@ public class ActivityManager { // we can afford the overhead of graphics acceleration. return true; } + + Display display = DisplayManager.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY); Point p = new Point(); display.getRealSize(p); int pixels = p.x * p.y; @@ -1375,6 +1378,13 @@ public class ActivityManager { public static final int FLAG_PERSISTENT = 1<<1; /** + * Constant for {@link #flags}: this process is associated with a + * persistent system app. + * @hide + */ + public static final int FLAG_HAS_ACTIVITIES = 1<<2; + + /** * Flags of information. May be any of * {@link #FLAG_CANT_SAVE_STATE}. * @hide diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index 4edfdfb..87b1e24 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -97,9 +97,9 @@ public class ActivityOptions { /** @hide */ public static final int ANIM_SCALE_UP = 2; /** @hide */ - public static final int ANIM_THUMBNAIL = 3; + public static final int ANIM_THUMBNAIL_SCALE_UP = 3; /** @hide */ - public static final int ANIM_THUMBNAIL_DELAYED = 4; + public static final int ANIM_THUMBNAIL_SCALE_DOWN = 4; private String mPackageName; private int mAnimationType = ANIM_NONE; @@ -262,20 +262,19 @@ public class ActivityOptions { */ public static ActivityOptions makeThumbnailScaleUpAnimation(View source, Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) { - return makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY, listener, false); + return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, true); } /** - * Create an ActivityOptions specifying an animation where a thumbnail - * is scaled from a given position to the new activity window that is - * being started. Before the animation, there is a short delay. + * Create an ActivityOptions specifying an animation where an activity window + * is scaled from a given position to a thumbnail at a specified location. * - * @param source The View that this thumbnail is animating from. This + * @param source The View that this thumbnail is animating to. This * defines the coordinate space for <var>startX</var> and <var>startY</var>. - * @param thumbnail The bitmap that will be shown as the initial thumbnail + * @param thumbnail The bitmap that will be shown as the final thumbnail * of the animation. - * @param startX The x starting location of the bitmap, relative to <var>source</var>. - * @param startY The y starting location of the bitmap, relative to <var>source</var>. + * @param startX The x end location of the bitmap, relative to <var>source</var>. + * @param startY The y end location of the bitmap, relative to <var>source</var>. * @param listener Optional OnAnimationStartedListener to find out when the * requested animation has started running. If for some reason the animation * is not executed, the callback will happen immediately. @@ -283,17 +282,17 @@ public class ActivityOptions { * supply these options as the options Bundle when starting an activity. * @hide */ - public static ActivityOptions makeDelayedThumbnailScaleUpAnimation(View source, + public static ActivityOptions makeThumbnailScaleDownAnimation(View source, Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) { - return makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY, listener, true); + return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, false); } - private static ActivityOptions makeThumbnailScaleUpAnimation(View source, + private static ActivityOptions makeThumbnailAnimation(View source, Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener, - boolean delayed) { + boolean scaleUp) { ActivityOptions opts = new ActivityOptions(); opts.mPackageName = source.getContext().getPackageName(); - opts.mAnimationType = delayed ? ANIM_THUMBNAIL_DELAYED : ANIM_THUMBNAIL; + opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_SCALE_UP : ANIM_THUMBNAIL_SCALE_DOWN; opts.mThumbnail = thumbnail; int[] pts = new int[2]; source.getLocationOnScreen(pts); @@ -320,8 +319,8 @@ public class ActivityOptions { mStartY = opts.getInt(KEY_ANIM_START_Y, 0); mStartWidth = opts.getInt(KEY_ANIM_START_WIDTH, 0); mStartHeight = opts.getInt(KEY_ANIM_START_HEIGHT, 0); - } else if (mAnimationType == ANIM_THUMBNAIL || - mAnimationType == ANIM_THUMBNAIL_DELAYED) { + } else if (mAnimationType == ANIM_THUMBNAIL_SCALE_UP || + mAnimationType == ANIM_THUMBNAIL_SCALE_DOWN) { mThumbnail = (Bitmap)opts.getParcelable(KEY_ANIM_THUMBNAIL); mStartX = opts.getInt(KEY_ANIM_START_X, 0); mStartY = opts.getInt(KEY_ANIM_START_Y, 0); @@ -434,8 +433,8 @@ public class ActivityOptions { } mAnimationStartedListener = null; break; - case ANIM_THUMBNAIL: - case ANIM_THUMBNAIL_DELAYED: + case ANIM_THUMBNAIL_SCALE_UP: + case ANIM_THUMBNAIL_SCALE_DOWN: mAnimationType = otherOptions.mAnimationType; mThumbnail = otherOptions.mThumbnail; mStartX = otherOptions.mStartX; @@ -479,8 +478,8 @@ public class ActivityOptions { b.putInt(KEY_ANIM_START_WIDTH, mStartWidth); b.putInt(KEY_ANIM_START_HEIGHT, mStartHeight); break; - case ANIM_THUMBNAIL: - case ANIM_THUMBNAIL_DELAYED: + case ANIM_THUMBNAIL_SCALE_UP: + case ANIM_THUMBNAIL_SCALE_DOWN: b.putInt(KEY_ANIM_TYPE, mAnimationType); b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail); b.putInt(KEY_ANIM_START_X, mStartX); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 7eb86f4..28c5abd 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -42,6 +42,7 @@ import android.database.sqlite.SQLiteDebug; import android.database.sqlite.SQLiteDebug.DbStats; import android.graphics.Bitmap; import android.graphics.Canvas; +import android.hardware.display.DisplayManager; import android.net.IConnectivityManager; import android.net.Proxy; import android.net.ProxyProperties; @@ -79,8 +80,9 @@ import android.view.ViewManager; import android.view.ViewRootImpl; import android.view.Window; import android.view.WindowManager; -import android.view.WindowManagerImpl; +import android.view.WindowManagerGlobal; import android.renderscript.RenderScript; +import android.security.AndroidKeyStoreProvider; import com.android.internal.os.BinderInternal; import com.android.internal.os.RuntimeInit; @@ -95,6 +97,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.net.InetAddress; +import java.security.Security; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -1055,7 +1058,7 @@ public final class ActivityThread { @Override public void dumpGfxInfo(FileDescriptor fd, String[] args) { dumpGraphicsInfo(fd); - WindowManagerImpl.getDefault().dumpGfxInfo(fd); + WindowManagerGlobal.getInstance().dumpGfxInfo(fd); } @Override @@ -1553,13 +1556,23 @@ public final class ActivityThread { if (dm != null && !forceUpdate) { return dm; } + + DisplayManager displayManager = DisplayManager.getInstance(); + if (displayManager == null) { + // may be null early in system startup + dm = new DisplayMetrics(); + dm.setToDefaults(); + return dm; + } + if (dm == null) { dm = new DisplayMetrics(); mDisplayMetrics.put(ci, dm); } + CompatibilityInfoHolder cih = new CompatibilityInfoHolder(); cih.set(ci); - Display d = WindowManagerImpl.getDefault().makeCompatible(cih).getDefaultDisplay(); + Display d = displayManager.getCompatibleDisplay(Display.DEFAULT_DISPLAY, cih); d.getMetrics(dm); //Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h=" // + metrics.heightPixels + " den=" + metrics.density @@ -2631,7 +2644,7 @@ public final class ActivityThread { r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow); IBinder wtoken = r.mPendingRemoveWindow.getWindowToken(); if (wtoken != null) { - WindowManagerImpl.getDefault().closeAll(wtoken, + WindowManagerGlobal.getInstance().closeAll(wtoken, r.activity.getClass().getName(), "Activity"); } } @@ -3166,7 +3179,7 @@ public final class ActivityThread { apk.mCompatibilityInfo.set(data.info); } handleConfigurationChanged(mConfiguration, data.info); - WindowManagerImpl.getDefault().reportNewConfiguration(mConfiguration); + WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration); } private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) { @@ -3355,7 +3368,7 @@ public final class ActivityThread { } } if (wtoken != null && r.mPendingRemoveWindow == null) { - WindowManagerImpl.getDefault().closeAll(wtoken, + WindowManagerGlobal.getInstance().closeAll(wtoken, r.activity.getClass().getName(), "Activity"); } r.activity.mDecor = null; @@ -3367,7 +3380,7 @@ public final class ActivityThread { // by the app will leak. Well we try to warning them a lot // about leaking windows, because that is a bug, so if they are // using this recreate facility then they get to live with leaks. - WindowManagerImpl.getDefault().closeAll(token, + WindowManagerGlobal.getInstance().closeAll(token, r.activity.getClass().getName(), "Activity"); } @@ -3795,7 +3808,7 @@ public final class ActivityThread { } // Cleanup hardware accelerated stuff - WindowManagerImpl.getDefault().trimLocalMemory(); + WindowManagerGlobal.getInstance().trimLocalMemory(); freeTextLayoutCachesIfNeeded(configDiff); @@ -3935,7 +3948,7 @@ public final class ActivityThread { final void handleTrimMemory(int level) { if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level); - final WindowManagerImpl windowManager = WindowManagerImpl.getDefault(); + final WindowManagerGlobal windowManager = WindowManagerGlobal.getInstance(); windowManager.startTrimMemory(level); ArrayList<ComponentCallbacks2> callbacks; @@ -3948,7 +3961,7 @@ public final class ActivityThread { callbacks.get(i).onTrimMemory(level); } - windowManager.endTrimMemory(); + windowManager.endTrimMemory(); } private void setupGraphicsSupport(LoadedApk info, File cacheDir) { @@ -4001,8 +4014,7 @@ public final class ActivityThread { // Persistent processes on low-memory devices do not get to // use hardware accelerated drawing, since this can add too much // overhead to the process. - final Display display = WindowManagerImpl.getDefault().getDefaultDisplay(); - if (!ActivityManager.isHighEndGfx(display)) { + if (!ActivityManager.isHighEndGfx()) { HardwareRenderer.disable(false); } } @@ -4055,13 +4067,14 @@ public final class ActivityThread { final ContextImpl appContext = new ContextImpl(); appContext.init(data.info, null, this); - final File cacheDir = appContext.getCacheDir(); - - // Provide a usable directory for temporary files - System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath()); + if (!Process.isIsolated()) { + final File cacheDir = appContext.getCacheDir(); - setupGraphicsSupport(data.info, cacheDir); + // Provide a usable directory for temporary files + System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath()); + setupGraphicsSupport(data.info, cacheDir); + } /** * For system applications on userdebug/eng builds, log stack * traces of disk and network access to dropbox for analysis. @@ -4799,16 +4812,19 @@ public final class ActivityThread { // StrictMode) on debug builds, but using DropBox, not logs. CloseGuard.setEnabled(false); + Security.addProvider(new AndroidKeyStoreProvider()); + Process.setArgV0("<pre-initialized>"); Looper.prepareMainLooper(); - if (sMainThreadHandler == null) { - sMainThreadHandler = new Handler(); - } ActivityThread thread = new ActivityThread(); thread.attach(false); + if (sMainThreadHandler == null) { + sMainThreadHandler = thread.getHandler(); + } + AsyncTask.init(); if (false) { diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 115c867..86ee8a0 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -43,6 +43,7 @@ import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.pm.ManifestDigest; import android.content.pm.UserInfo; +import android.content.pm.VerificationParams; import android.content.pm.VerifierDeviceIdentity; import android.content.res.Resources; import android.content.res.XmlResourceParser; @@ -984,6 +985,18 @@ final class ApplicationPackageManager extends PackageManager { } @Override + public void installPackageWithVerificationAndEncryption(Uri packageURI, + IPackageInstallObserver observer, int flags, String installerPackageName, + VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) { + try { + mPM.installPackageWithVerificationAndEncryption(packageURI, observer, flags, + installerPackageName, verificationParams, encryptionParams); + } catch (RemoteException e) { + // Should never happen! + } + } + + @Override public void verifyPendingInstall(int id, int response) { try { mPM.verifyPendingInstall(id, response); @@ -1066,10 +1079,10 @@ final class ApplicationPackageManager extends PackageManager { } @Override - public void getPackageSizeInfo(String packageName, - IPackageStatsObserver observer) { + public void getPackageSizeInfo(String packageName, int userHandle, + IPackageStatsObserver observer) { try { - mPM.getPackageSizeInfo(packageName, observer); + mPM.getPackageSizeInfo(packageName, userHandle, observer); } catch (RemoteException e) { // Should never happen! } @@ -1106,7 +1119,17 @@ final class ApplicationPackageManager extends PackageManager { public void addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity) { try { - mPM.addPreferredActivity(filter, match, set, activity); + mPM.addPreferredActivity(filter, match, set, activity, UserHandle.myUserId()); + } catch (RemoteException e) { + // Should never happen! + } + } + + @Override + public void addPreferredActivity(IntentFilter filter, int match, + ComponentName[] set, ComponentName activity, int userId) { + try { + mPM.addPreferredActivity(filter, match, set, activity, userId); } catch (RemoteException e) { // Should never happen! } diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index ed4f0a7..0543f05 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -95,7 +95,9 @@ import android.telephony.TelephonyManager; import android.content.ClipboardManager; import android.util.AndroidRuntimeException; import android.util.Log; +import android.view.CompatibilityInfoHolder; import android.view.ContextThemeWrapper; +import android.view.Display; import android.view.WindowManagerImpl; import android.view.accessibility.AccessibilityManager; import android.view.inputmethod.InputMethodManager; @@ -499,8 +501,8 @@ class ContextImpl extends Context { registerService(WINDOW_SERVICE, new ServiceFetcher() { public Object getService(ContextImpl ctx) { - return WindowManagerImpl.getDefault().makeCompatible( - ctx.mPackageInfo.mCompatibilityInfo); + return new WindowManagerImpl(ctx.getOuterContext(), + Display.DEFAULT_DISPLAY); }}); registerService(USER_SERVICE, new ServiceFetcher() { @@ -906,12 +908,13 @@ class ContextImpl extends Context { /** @hide */ @Override - public void startActivityAsUser(Intent intent, int userId) { + public void startActivityAsUser(Intent intent, UserHandle user) { try { ActivityManagerNative.getDefault().startActivityAsUser( mMainThread.getApplicationThread(), intent, intent.resolveTypeIfNeeded(getContentResolver()), - null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null, null, userId); + null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null, null, + user.getIdentifier()); } catch (RemoteException re) { } } @@ -931,12 +934,13 @@ class ContextImpl extends Context { /** @hide */ @Override - public void startActivityAsUser(Intent intent, Bundle options, int userId) { + public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) { try { ActivityManagerNative.getDefault().startActivityAsUser( mMainThread.getApplicationThread(), intent, intent.resolveTypeIfNeeded(getContentResolver()), - null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null, options, userId); + null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null, options, + user.getIdentifier()); } catch (RemoteException re) { } } @@ -1062,19 +1066,19 @@ class ContextImpl extends Context { } @Override - public void sendBroadcastToUser(Intent intent, int userHandle) { + public void sendBroadcastAsUser(Intent intent, UserHandle user) { String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); try { intent.setAllowFds(false); ActivityManagerNative.getDefault().broadcastIntent(mMainThread.getApplicationThread(), intent, resolvedType, null, Activity.RESULT_OK, null, null, null, false, false, - userHandle); + user.getIdentifier()); } catch (RemoteException e) { } } @Override - public void sendOrderedBroadcastToUser(Intent intent, int userHandle, + public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { IIntentReceiver rd = null; @@ -1100,7 +1104,7 @@ class ContextImpl extends Context { ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, rd, initialCode, initialData, initialExtras, null, - true, false, userHandle); + true, false, user.getIdentifier()); } catch (RemoteException e) { } } @@ -1607,6 +1611,11 @@ class ContextImpl extends Context { return mRestricted; } + @Override + public CompatibilityInfoHolder getCompatibilityInfo() { + return mPackageInfo.mCompatibilityInfo; + } + private File getDataDirFile() { if (mPackageInfo != null) { return mPackageInfo.getDataDirFile(); diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java index c1e11bb..52a6557 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -428,92 +428,26 @@ final class FragmentManagerImpl extends FragmentManager { } }; - private void logViewHierarchy(String prefix, View view) { - StringBuilder builder = new StringBuilder(128); - builder.append(prefix); - DebugUtils.buildShortClassTag(view, builder); - int id = view.getId(); - if (id != -1) { - builder.append(" #"); - builder.append(Integer.toHexString(id)); - if (id != 0 && id != -1) { - try { - String pkgname; - switch (id&0xff000000) { - case 0x7f000000: - pkgname="app"; - break; - case 0x01000000: - pkgname="android"; - break; - default: - pkgname = view.getResources().getResourcePackageName(id); - break; - } - String typename = view.getResources().getResourceTypeName(id); - String entryname = view.getResources().getResourceEntryName(id); - builder.append(" ("); - builder.append(pkgname); - builder.append(":"); - builder.append(typename); - builder.append("/"); - builder.append(entryname); - builder.append(")"); - } catch (Resources.NotFoundException e) { - } - } - } - Object tag = view.getTag(); - if (tag != null) { - builder.append(" "); - builder.append(tag); - } - builder.append("}"); - Log.e(TAG, builder.toString()); - - if (!(view instanceof ViewGroup)) { - return; - } - ViewGroup grp = (ViewGroup)view; - final int N = grp.getChildCount(); - if (N <= 0) { - return; - } - prefix = prefix + " "; - for (int i=0; i<N; i++) { - logViewHierarchy(prefix, grp.getChildAt(i)); - } - } - - private void throwNoViewFound(Fragment f) { - String msg = "No view found for id 0x" - + Integer.toHexString(f.mContainerId) + " (" - + f.getResources().getResourceName(f.mContainerId) - + ") for fragment " + f; - Log.e(TAG, msg); - Log.e(TAG, "Activity state:"); - if (f.getActivity() != null) { + private void throwException(RuntimeException ex) { + Log.e(TAG, ex.getMessage()); + LogWriter logw = new LogWriter(Log.ERROR, TAG); + PrintWriter pw = new PrintWriter(logw); + if (mActivity != null) { + Log.e(TAG, "Activity state:"); try { - LogWriter logw = new LogWriter(Log.ERROR, TAG); - PrintWriter pw = new PrintWriter(logw); - f.getActivity().dump(" ", null, pw, new String[] { }); + mActivity.dump(" ", null, pw, new String[] { }); } catch (Exception e) { Log.e(TAG, "Failed dumping state", e); } } else { - Log.e(TAG, " NULL ACTIVITY!"); - } - Log.e(TAG, "View hierarchy:"); - if (f.getActivity() != null) { + Log.e(TAG, "Fragment manager state:"); try { - logViewHierarchy(" ", f.getActivity().getWindow().getDecorView()); + dump(" ", null, pw, new String[] { }); } catch (Exception e) { - Log.e(TAG, "Failed dumping view hierarchy", e); + Log.e(TAG, "Failed dumping state", e); } - } else { - Log.e(TAG, " NULL ACTIVITY!"); } - throw new IllegalArgumentException(msg); + throw ex; } @Override @@ -608,8 +542,8 @@ final class FragmentManagerImpl extends FragmentManager { @Override public void putFragment(Bundle bundle, String key, Fragment fragment) { if (fragment.mIndex < 0) { - throw new IllegalStateException("Fragment " + fragment - + " is not currently in the FragmentManager"); + throwException(new IllegalStateException("Fragment " + fragment + + " is not currently in the FragmentManager")); } bundle.putInt(key, fragment.mIndex); } @@ -621,13 +555,13 @@ final class FragmentManagerImpl extends FragmentManager { return null; } if (index >= mActive.size()) { - throw new IllegalStateException("Fragement no longer exists for key " - + key + ": index " + index); + throwException(new IllegalStateException("Fragement no longer exists for key " + + key + ": index " + index)); } Fragment f = mActive.get(index); if (f == null) { - throw new IllegalStateException("Fragement no longer exists for key " - + key + ": index " + index); + throwException(new IllegalStateException("Fragement no longer exists for key " + + key + ": index " + index)); } return f; } @@ -635,8 +569,8 @@ final class FragmentManagerImpl extends FragmentManager { @Override public Fragment.SavedState saveFragmentInstanceState(Fragment fragment) { if (fragment.mIndex < 0) { - throw new IllegalStateException("Fragment " + fragment - + " is not currently in the FragmentManager"); + throwException(new IllegalStateException("Fragment " + fragment + + " is not currently in the FragmentManager")); } if (fragment.mState > Fragment.INITIALIZING) { Bundle result = saveFragmentBasicState(fragment); @@ -913,7 +847,11 @@ final class FragmentManagerImpl extends FragmentManager { if (f.mContainerId != 0) { container = (ViewGroup)mActivity.findViewById(f.mContainerId); if (container == null && !f.mRestored) { - throwNoViewFound(f); + throwException(new IllegalArgumentException( + "No view found for id 0x" + + Integer.toHexString(f.mContainerId) + " (" + + f.getResources().getResourceName(f.mContainerId) + + ") for fragment " + f)); } } f.mContainer = container; @@ -1674,12 +1612,9 @@ final class FragmentManagerImpl extends FragmentManager { Fragment f = mActive.get(i); if (f != null) { if (f.mIndex < 0) { - String msg = "Failure saving state: active " + f - + " has cleared index: " + f.mIndex; - Slog.e(TAG, msg); - dump(" ", null, new PrintWriter(new LogWriter( - Log.ERROR, TAG, Log.LOG_ID_SYSTEM)), new String[] { }); - throw new IllegalStateException(msg); + throwException(new IllegalStateException( + "Failure saving state: active " + f + + " has cleared index: " + f.mIndex)); } haveFragments = true; @@ -1692,12 +1627,9 @@ final class FragmentManagerImpl extends FragmentManager { if (f.mTarget != null) { if (f.mTarget.mIndex < 0) { - String msg = "Failure saving state: " + f - + " has target not in fragment manager: " + f.mTarget; - Slog.e(TAG, msg); - dump(" ", null, new PrintWriter(new LogWriter( - Log.ERROR, TAG, Log.LOG_ID_SYSTEM)), new String[] { }); - throw new IllegalStateException(msg); + throwException(new IllegalStateException( + "Failure saving state: " + f + + " has target not in fragment manager: " + f.mTarget)); } if (fs.mSavedFragmentState == null) { fs.mSavedFragmentState = new Bundle(); @@ -1736,12 +1668,9 @@ final class FragmentManagerImpl extends FragmentManager { for (int i=0; i<N; i++) { added[i] = mAdded.get(i).mIndex; if (added[i] < 0) { - String msg = "Failure saving state: active " + mAdded.get(i) - + " has cleared index: " + added[i]; - Slog.e(TAG, msg); - dump(" ", null, new PrintWriter(new LogWriter( - Log.ERROR, TAG, Log.LOG_ID_SYSTEM)), new String[] { }); - throw new IllegalStateException(msg); + throwException(new IllegalStateException( + "Failure saving state: active " + mAdded.get(i) + + " has cleared index: " + added[i])); } if (DEBUG) Log.v(TAG, "saveAllState: adding fragment #" + i + ": " + mAdded.get(i)); @@ -1846,8 +1775,8 @@ final class FragmentManagerImpl extends FragmentManager { for (int i=0; i<fms.mAdded.length; i++) { Fragment f = mActive.get(fms.mAdded[i]); if (f == null) { - throw new IllegalStateException( - "No instantiated fragment for index #" + fms.mAdded[i]); + throwException(new IllegalStateException( + "No instantiated fragment for index #" + fms.mAdded[i])); } f.mAdded = true; if (DEBUG) Log.v(TAG, "restoreAllState: making added #" + i + ": " + f); @@ -1875,7 +1804,7 @@ final class FragmentManagerImpl extends FragmentManager { } public void attachActivity(Activity activity) { - if (mActivity != null) throw new IllegalStateException(); + if (mActivity != null) throw new IllegalStateException("Already attached"); mActivity = activity; } diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java index ef61af7..22a21cd 100644 --- a/core/java/android/app/KeyguardManager.java +++ b/core/java/android/app/KeyguardManager.java @@ -16,13 +16,12 @@ package android.app; -import android.content.Context; import android.os.Binder; import android.os.RemoteException; import android.os.IBinder; -import android.os.ServiceManager; import android.view.IWindowManager; import android.view.IOnKeyguardExitResult; +import android.view.WindowManagerGlobal; /** * Class that can be used to lock and unlock the keyboard. Get an instance of this @@ -111,7 +110,7 @@ public class KeyguardManager { KeyguardManager() { - mWM = IWindowManager.Stub.asInterface(ServiceManager.getService(Context.WINDOW_SERVICE)); + mWM = WindowManagerGlobal.getWindowManagerService(); } /** diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java index f638f7e..a57c516 100644 --- a/core/java/android/app/PendingIntent.java +++ b/core/java/android/app/PendingIntent.java @@ -639,22 +639,22 @@ public final class PendingIntent implements Parcelable { /** * Return the user handle of the application that created this * PendingIntent, that is the user under which you will actually be - * sending the Intent. The returned integer is supplied by the system, so + * sending the Intent. The returned UserHandle is supplied by the system, so * that an application can not spoof its user. See * {@link android.os.Process#myUserHandle() Process.myUserHandle()} for * more explanation of user handles. * - * @return The user handle of the PendingIntent, or -1 if there is + * @return The user handle of the PendingIntent, or null if there is * none associated with it. */ - public int getTargetUserHandle() { + public UserHandle getTargetUserHandle() { try { int uid = ActivityManagerNative.getDefault() .getUidForIntentSender(mTarget); - return uid > 0 ? UserHandle.getUserId(uid) : -1; + return uid > 0 ? new UserHandle(UserHandle.getUserId(uid)) : null; } catch (RemoteException e) { // Should never happen. - return -1; + return null; } } diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java index 615e8ce..201d7b2 100644 --- a/core/java/android/app/SharedPreferencesImpl.java +++ b/core/java/android/app/SharedPreferencesImpl.java @@ -17,7 +17,6 @@ package android.app; import android.content.SharedPreferences; -import android.os.FileUtils.FileStatus; import android.os.FileUtils; import android.os.Looper; import android.util.Log; @@ -45,6 +44,11 @@ import java.util.WeakHashMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; +import libcore.io.ErrnoException; +import libcore.io.IoUtils; +import libcore.io.Libcore; +import libcore.io.StructStat; + final class SharedPreferencesImpl implements SharedPreferences { private static final String TAG = "SharedPreferencesImpl"; private static final boolean DEBUG = false; @@ -105,26 +109,32 @@ final class SharedPreferencesImpl implements SharedPreferences { } Map map = null; - FileStatus stat = new FileStatus(); - if (FileUtils.getFileStatus(mFile.getPath(), stat) && mFile.canRead()) { - try { - BufferedInputStream str = new BufferedInputStream( - new FileInputStream(mFile), 16*1024); - map = XmlUtils.readMapXml(str); - str.close(); - } catch (XmlPullParserException e) { - Log.w(TAG, "getSharedPreferences", e); - } catch (FileNotFoundException e) { - Log.w(TAG, "getSharedPreferences", e); - } catch (IOException e) { - Log.w(TAG, "getSharedPreferences", e); + StructStat stat = null; + try { + stat = Libcore.os.stat(mFile.getPath()); + if (mFile.canRead()) { + BufferedInputStream str = null; + try { + str = new BufferedInputStream( + new FileInputStream(mFile), 16*1024); + map = XmlUtils.readMapXml(str); + } catch (XmlPullParserException e) { + Log.w(TAG, "getSharedPreferences", e); + } catch (FileNotFoundException e) { + Log.w(TAG, "getSharedPreferences", e); + } catch (IOException e) { + Log.w(TAG, "getSharedPreferences", e); + } finally { + IoUtils.closeQuietly(str); + } } + } catch (ErrnoException e) { } mLoaded = true; if (map != null) { mMap = map; - mStatTimestamp = stat.mtime; - mStatSize = stat.size; + mStatTimestamp = stat.st_mtime; + mStatSize = stat.st_size; } else { mMap = new HashMap<String, Object>(); } @@ -155,12 +165,21 @@ final class SharedPreferencesImpl implements SharedPreferences { return false; } } - FileStatus stat = new FileStatus(); - if (!FileUtils.getFileStatus(mFile.getPath(), stat)) { + + final StructStat stat; + try { + /* + * Metadata operations don't usually count as a block guard + * violation, but we explicitly want this one. + */ + BlockGuard.getThreadPolicy().onReadFromDisk(); + stat = Libcore.os.stat(mFile.getPath()); + } catch (ErrnoException e) { return true; } + synchronized (this) { - return mStatTimestamp != stat.mtime || mStatSize != stat.size; + return mStatTimestamp != stat.st_mtime || mStatSize != stat.st_size; } } @@ -577,12 +596,14 @@ final class SharedPreferencesImpl implements SharedPreferences { FileUtils.sync(str); str.close(); ContextImpl.setFilePermissionsFromMode(mFile.getPath(), mMode, 0); - FileStatus stat = new FileStatus(); - if (FileUtils.getFileStatus(mFile.getPath(), stat)) { + try { + final StructStat stat = Libcore.os.stat(mFile.getPath()); synchronized (this) { - mStatTimestamp = stat.mtime; - mStatSize = stat.size; + mStatTimestamp = stat.st_mtime; + mStatSize = stat.st_size; } + } catch (ErrnoException e) { + // Do nothing } // Writing was successful, delete the backup file if there is one. mBackupFile.delete(); diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index 27843ac..1ad2e6d 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -43,6 +43,7 @@ import android.util.DisplayMetrics; import android.util.Log; import android.view.ViewRootImpl; import android.view.WindowManager; +import android.view.WindowManagerGlobal; import java.io.FileOutputStream; import java.io.IOException; @@ -689,7 +690,7 @@ public class WallpaperManager { public void setWallpaperOffsets(IBinder windowToken, float xOffset, float yOffset) { try { //Log.v(TAG, "Sending new wallpaper offsets from app..."); - ViewRootImpl.getWindowSession(mContext.getMainLooper()).setWallpaperPosition( + WindowManagerGlobal.getWindowSession(mContext.getMainLooper()).setWallpaperPosition( windowToken, xOffset, yOffset, mWallpaperXStep, mWallpaperYStep); //Log.v(TAG, "...app returning after sending offsets!"); } catch (RemoteException e) { @@ -727,7 +728,7 @@ public class WallpaperManager { int x, int y, int z, Bundle extras) { try { //Log.v(TAG, "Sending new wallpaper offsets from app..."); - ViewRootImpl.getWindowSession(mContext.getMainLooper()).sendWallpaperCommand( + WindowManagerGlobal.getWindowSession(mContext.getMainLooper()).sendWallpaperCommand( windowToken, action, x, y, z, extras, false); //Log.v(TAG, "...app returning after sending offsets!"); } catch (RemoteException e) { @@ -747,7 +748,7 @@ public class WallpaperManager { */ public void clearWallpaperOffsets(IBinder windowToken) { try { - ViewRootImpl.getWindowSession(mContext.getMainLooper()).setWallpaperPosition( + WindowManagerGlobal.getWindowSession(mContext.getMainLooper()).setWallpaperPosition( windowToken, -1, -1, -1, -1); } catch (RemoteException e) { // Ignore. diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java index 2c19c0c..c76bf91 100644 --- a/core/java/android/appwidget/AppWidgetHost.java +++ b/core/java/android/appwidget/AppWidgetHost.java @@ -29,6 +29,7 @@ import android.os.ServiceManager; import android.util.DisplayMetrics; import android.util.TypedValue; import android.widget.RemoteViews; +import android.widget.RemoteViews.OnClickHandler; import com.android.internal.appwidget.IAppWidgetHost; import com.android.internal.appwidget.IAppWidgetService; @@ -83,7 +84,7 @@ public class AppWidgetHost { public UpdateHandler(Looper looper) { super(looper); } - + public void handleMessage(Message msg) { switch (msg.what) { case HANDLE_UPDATE: { @@ -105,16 +106,25 @@ public class AppWidgetHost { } } } - + Handler mHandler; int mHostId; Callbacks mCallbacks = new Callbacks(); final HashMap<Integer,AppWidgetHostView> mViews = new HashMap<Integer, AppWidgetHostView>(); + private OnClickHandler mOnClickHandler; public AppWidgetHost(Context context, int hostId) { + this(context, hostId, null); + } + + /** + * @hide + */ + public AppWidgetHost(Context context, int hostId, OnClickHandler handler) { mContext = context; mHostId = hostId; + mOnClickHandler = handler; mHandler = new UpdateHandler(context.getMainLooper()); mDisplayMetrics = context.getResources().getDisplayMetrics(); synchronized (sServiceLock) { @@ -132,7 +142,7 @@ public class AppWidgetHost { public void startListening() { int[] updatedIds; ArrayList<RemoteViews> updatedViews = new ArrayList<RemoteViews>(); - + try { if (mPackageName == null) { mPackageName = mContext.getPackageName(); @@ -180,7 +190,7 @@ public class AppWidgetHost { } /** - * Stop listening to changes for this AppWidget. + * Stop listening to changes for this AppWidget. */ public void deleteAppWidgetId(int appWidgetId) { synchronized (mViews) { @@ -235,6 +245,7 @@ public class AppWidgetHost { public final AppWidgetHostView createView(Context context, int appWidgetId, AppWidgetProviderInfo appWidget) { AppWidgetHostView view = onCreateView(context, appWidgetId, appWidget); + view.setOnClickHandler(mOnClickHandler); view.setAppWidget(appWidgetId, appWidget); synchronized (mViews) { mViews.put(appWidgetId, view); @@ -246,6 +257,7 @@ public class AppWidgetHost { throw new RuntimeException("system server dead?", e); } view.updateAppWidget(views); + return view; } @@ -255,7 +267,7 @@ public class AppWidgetHost { */ protected AppWidgetHostView onCreateView(Context context, int appWidgetId, AppWidgetProviderInfo appWidget) { - return new AppWidgetHostView(context); + return new AppWidgetHostView(context, mOnClickHandler); } /** @@ -265,7 +277,7 @@ public class AppWidgetHost { AppWidgetHostView v; // Convert complex to dp -- we are getting the AppWidgetProviderInfo from the - // AppWidgetService, which doesn't have our context, hence we need to do the + // AppWidgetService, which doesn't have our context, hence we need to do the // conversion here. appWidget.minWidth = TypedValue.complexToDimensionPixelSize(appWidget.minWidth, mDisplayMetrics); diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java index ed95ae5..603ceb7 100644 --- a/core/java/android/appwidget/AppWidgetHostView.java +++ b/core/java/android/appwidget/AppWidgetHostView.java @@ -44,6 +44,7 @@ import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.FrameLayout; import android.widget.RemoteViews; +import android.widget.RemoteViews.OnClickHandler; import android.widget.RemoteViewsAdapter.RemoteAdapterConnectionCallback; import android.widget.TextView; @@ -83,7 +84,8 @@ public class AppWidgetHostView extends FrameLayout { long mFadeStartTime = -1; Bitmap mOld; Paint mOldPaint = new Paint(); - + private OnClickHandler mOnClickHandler; + /** * Create a host view. Uses default fade animations. */ @@ -92,9 +94,17 @@ public class AppWidgetHostView extends FrameLayout { } /** + * @hide + */ + public AppWidgetHostView(Context context, OnClickHandler handler) { + this(context, android.R.anim.fade_in, android.R.anim.fade_out); + mOnClickHandler = handler; + } + + /** * Create a host view. Uses specified animations when pushing * {@link #updateAppWidget(RemoteViews)}. - * + * * @param animationIn Resource ID of in animation to use * @param animationOut Resource ID of out animation to use */ @@ -109,6 +119,17 @@ public class AppWidgetHostView extends FrameLayout { } /** + * Pass the given handler to RemoteViews when updating this widget. Unless this + * is done immediatly after construction, a call to {@link #updateAppWidget(RemoteViews)} + * should be made. + * @param handler + * @hide + */ + public void setOnClickHandler(OnClickHandler handler) { + mOnClickHandler = handler; + } + + /** * Set the AppWidget that will be displayed by this view. This method also adds default padding * to widgets, as described in {@link #getDefaultPaddingForWidget(Context, ComponentName, Rect)} * and can be overridden in order to add custom padding. @@ -177,7 +198,7 @@ public class AppWidgetHostView extends FrameLayout { public int getAppWidgetId() { return mAppWidgetId; } - + public AppWidgetProviderInfo getAppWidgetInfo() { return mInfo; } @@ -281,12 +302,13 @@ public class AppWidgetHostView extends FrameLayout { * AppWidget provider. Will animate into these new views as needed */ public void updateAppWidget(RemoteViews remoteViews) { + if (LOGD) Log.d(TAG, "updateAppWidget called mOld=" + mOld); boolean recycled = false; View content = null; Exception exception = null; - + // Capture the old view into a bitmap so we can do the crossfade. if (CROSSFADE) { if (mFadeStartTime < 0) { @@ -305,7 +327,7 @@ public class AppWidgetHostView extends FrameLayout { } } } - + if (remoteViews == null) { if (mViewMode == VIEW_MODE_DEFAULT) { // We've already done this -- nothing to do. @@ -324,7 +346,7 @@ public class AppWidgetHostView extends FrameLayout { // layout matches, try recycling it if (content == null && layoutId == mLayoutId) { try { - remoteViews.reapply(mContext, mView); + remoteViews.reapply(mContext, mView, mOnClickHandler); content = mView; recycled = true; if (LOGD) Log.d(TAG, "was able to recycled existing layout"); @@ -332,11 +354,11 @@ public class AppWidgetHostView extends FrameLayout { exception = e; } } - + // Try normal RemoteView inflation if (content == null) { try { - content = remoteViews.apply(mContext, this); + content = remoteViews.apply(mContext, this, mOnClickHandler); if (LOGD) Log.d(TAG, "had to inflate new layout"); } catch (RuntimeException e) { exception = e; @@ -346,7 +368,7 @@ public class AppWidgetHostView extends FrameLayout { mLayoutId = layoutId; mViewMode = VIEW_MODE_CONTENT; } - + if (content == null) { if (mViewMode == VIEW_MODE_ERROR) { // We've already done this -- nothing to do. @@ -356,7 +378,7 @@ public class AppWidgetHostView extends FrameLayout { content = getErrorView(); mViewMode = VIEW_MODE_ERROR; } - + if (!recycled) { prepareView(content); addView(content); @@ -455,7 +477,7 @@ public class AppWidgetHostView extends FrameLayout { return super.drawChild(canvas, child, drawingTime); } } - + /** * Prepare the given view to be shown. This might include adjusting * {@link FrameLayout.LayoutParams} before inserting. @@ -471,7 +493,7 @@ public class AppWidgetHostView extends FrameLayout { requested.gravity = Gravity.CENTER; view.setLayoutParams(requested); } - + /** * Inflate and return the default layout requested by AppWidget provider. */ @@ -481,7 +503,7 @@ public class AppWidgetHostView extends FrameLayout { } View defaultView = null; Exception exception = null; - + try { if (mInfo != null) { Context theirContext = mContext.createPackageContext( @@ -500,19 +522,19 @@ public class AppWidgetHostView extends FrameLayout { } catch (RuntimeException e) { exception = e; } - + if (exception != null) { Log.w(TAG, "Error inflating AppWidget " + mInfo + ": " + exception.toString()); } - + if (defaultView == null) { if (LOGD) Log.d(TAG, "getDefaultView couldn't find any view, so inflating error"); defaultView = getErrorView(); } - + return defaultView; } - + /** * Inflate and return a view that represents an error state. */ diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index 8a69c3a..23d8f46 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -279,7 +279,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { final int uid = Binder.getCallingUid(); String missingPerm = null; - if (uid == mMyUid) { + if (UserHandle.isSameApp(uid, mMyUid)) { return; } @@ -340,7 +340,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { final int uid = Binder.getCallingUid(); String missingPerm = null; - if (uid == mMyUid) { + if (UserHandle.isSameApp(uid, mMyUid)) { return; } diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index a90142a..1460bf5 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -32,7 +32,9 @@ import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Looper; +import android.os.UserHandle; import android.util.AttributeSet; +import android.view.CompatibilityInfoHolder; import java.io.File; import java.io.FileInputStream; @@ -855,11 +857,11 @@ public abstract class Context { * Same as {@link #startActivity(Intent)}, but for a specific user. It requires holding * the {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permission. * @param intent The description of the activity to start. - * @param userId The user id of the user to start this activity for. + * @param user The UserHandle of the user to start this activity for. * @throws ActivityNotFoundException * @hide */ - public void startActivityAsUser(Intent intent, int userId) { + public void startActivityAsUser(Intent intent, UserHandle user) { throw new RuntimeException("Not implemented. Must override in a subclass."); } @@ -898,11 +900,11 @@ public abstract class Context { * May be null if there are no options. See {@link android.app.ActivityOptions} * for how to build the Bundle supplied here; there are no supported definitions * for building it manually. - * @param userId The user id of the user to start this activity for. + * @param user The UserHandle of the user to start this activity for. * @throws ActivityNotFoundException * @hide */ - public void startActivityAsUser(Intent intent, Bundle options, int userId) { + public void startActivityAsUser(Intent intent, Bundle options, UserHandle userId) { throw new RuntimeException("Not implemented. Must override in a subclass."); } @@ -1119,10 +1121,10 @@ public abstract class Context { * requires holding the {@link android.Manifest.permission#INTERACT_ACROSS_USERS} * permission. * @param intent The intent to broadcast - * @param userHandle User to send the intent to. + * @param user UserHandle to send the intent to. * @see #sendBroadcast(Intent) */ - public abstract void sendBroadcastToUser(Intent intent, int userHandle); + public abstract void sendBroadcastAsUser(Intent intent, UserHandle user); /** * Same as @@ -1136,7 +1138,7 @@ public abstract class Context { * * @param intent The Intent to broadcast; all receivers matching this * Intent will receive the broadcast. - * @param userHandle User to send the intent to. + * @param user UserHandle to send the intent to. * @param resultReceiver Your own BroadcastReceiver to treat as the final * receiver of the broadcast. * @param scheduler A custom Handler with which to schedule the @@ -1151,7 +1153,7 @@ public abstract class Context { * * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle) */ - public abstract void sendOrderedBroadcastToUser(Intent intent, int userHandle, + public abstract void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras); @@ -2463,6 +2465,16 @@ public abstract class Context { public abstract Context createConfigurationContext(Configuration overrideConfiguration); /** + * Gets the compatibility info holder for this context. This information + * is provided on a per-application basis and is used to simulate lower density + * display metrics for legacy applications. + * + * @return The compatibility info holder, or null if not required by the application. + * @hide + */ + public abstract CompatibilityInfoHolder getCompatibilityInfo(); + + /** * Indicates whether this Context is restricted. * * @return True if this Context is restricted, false otherwise. diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index fdf60ab..3a13725 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -30,6 +30,8 @@ import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Looper; +import android.os.UserHandle; +import android.view.CompatibilityInfoHolder; import java.io.File; import java.io.FileInputStream; @@ -279,8 +281,8 @@ public class ContextWrapper extends Context { /** @hide */ @Override - public void startActivityAsUser(Intent intent, int userId) { - mBase.startActivityAsUser(intent, userId); + public void startActivityAsUser(Intent intent, UserHandle user) { + mBase.startActivityAsUser(intent, user); } @Override @@ -290,8 +292,8 @@ public class ContextWrapper extends Context { /** @hide */ @Override - public void startActivityAsUser(Intent intent, Bundle options, int userId) { - mBase.startActivityAsUser(intent, options, userId); + public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) { + mBase.startActivityAsUser(intent, options, user); } @Override @@ -347,15 +349,15 @@ public class ContextWrapper extends Context { } @Override - public void sendBroadcastToUser(Intent intent, int userHandle) { - mBase.sendBroadcastToUser(intent, userHandle); + public void sendBroadcastAsUser(Intent intent, UserHandle user) { + mBase.sendBroadcastAsUser(intent, user); } @Override - public void sendOrderedBroadcastToUser(Intent intent, int userHandle, + public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { - mBase.sendOrderedBroadcastToUser(intent, userHandle, resultReceiver, + mBase.sendOrderedBroadcastAsUser(intent, user, resultReceiver, scheduler, initialCode, initialData, initialExtras); } @@ -542,4 +544,10 @@ public class ContextWrapper extends Context { public boolean isRestricted() { return mBase.isRestricted(); } + + /** @hide */ + @Override + public CompatibilityInfoHolder getCompatibilityInfo() { + return mBase.getCompatibilityInfo(); + } } diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index d325186..06edf32 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -571,7 +571,7 @@ import java.util.Set; * <li> {@link #EXTRA_INITIAL_INTENTS} * <li> {@link #EXTRA_INTENT} * <li> {@link #EXTRA_KEY_EVENT} - * <li> {@link #EXTRA_ORIGINATING_URL} + * <li> {@link #EXTRA_ORIGINATING_URI} * <li> {@link #EXTRA_PHONE_NUMBER} * <li> {@link #EXTRA_REFERRER} * <li> {@link #EXTRA_REMOTE_INTENT_TOKEN} @@ -1288,17 +1288,17 @@ public class Intent implements Parcelable, Cloneable { = "android.intent.extra.NOT_UNKNOWN_SOURCE"; /** - * Used as a string extra field with {@link #ACTION_INSTALL_PACKAGE} and - * {@link #ACTION_VIEW} to indicate the URL from which the local APK in the Intent + * Used as a URI extra field with {@link #ACTION_INSTALL_PACKAGE} and + * {@link #ACTION_VIEW} to indicate the URI from which the local APK in the Intent * data field originated from. */ - public static final String EXTRA_ORIGINATING_URL - = "android.intent.extra.ORIGINATING_URL"; + public static final String EXTRA_ORIGINATING_URI + = "android.intent.extra.ORIGINATING_URI"; /** - * Used as a string extra field with {@link #ACTION_INSTALL_PACKAGE} and - * {@link #ACTION_VIEW} to indicate the HTTP referrer associated with the Intent - * data field or {@link #EXTRA_ORIGINATING_URL}. + * Used as a URI extra field with {@link #ACTION_INSTALL_PACKAGE} and + * {@link #ACTION_VIEW} to indicate the HTTP referrer URI associated with the Intent + * data field or {@link #EXTRA_ORIGINATING_URI}. */ public static final String EXTRA_REFERRER = "android.intent.extra.REFERRER"; @@ -2279,24 +2279,24 @@ public class Intent implements Parcelable, Cloneable { "android.intent.action.PRE_BOOT_COMPLETED"; /** - * Broadcast sent to the system when a user is added. Carries an extra EXTRA_USERID that has the - * userid of the new user. + * Broadcast sent to the system when a user is added. Carries an extra EXTRA_USER_HANDLE that has the + * userHandle of the new user. * @hide */ public static final String ACTION_USER_ADDED = "android.intent.action.USER_ADDED"; /** - * Broadcast sent to the system when a user is removed. Carries an extra EXTRA_USERID that has - * the userid of the user. + * Broadcast sent to the system when a user is removed. Carries an extra EXTRA_USER_HANDLE that has + * the userHandle of the user. * @hide */ public static final String ACTION_USER_REMOVED = "android.intent.action.USER_REMOVED"; /** - * Broadcast sent to the system when the user switches. Carries an extra EXTRA_USERID that has - * the userid of the user to become the current one. + * Broadcast sent to the system when the user switches. Carries an extra EXTRA_USER_HANDLE that has + * the userHandle of the user to become the current one. * @hide */ public static final String ACTION_USER_SWITCHED = @@ -2852,12 +2852,12 @@ public class Intent implements Parcelable, Cloneable { "android.intent.extra.LOCAL_ONLY"; /** - * The userid carried with broadcast intents related to addition, removal and switching of users + * The userHandle carried with broadcast intents related to addition, removal and switching of users * - {@link #ACTION_USER_ADDED}, {@link #ACTION_USER_REMOVED} and {@link #ACTION_USER_SWITCHED}. * @hide */ - public static final String EXTRA_USERID = - "android.intent.extra.user_id"; + public static final String EXTRA_USER_HANDLE = + "android.intent.extra.user_handle"; // --------------------------------------------------------------------- // --------------------------------------------------------------------- diff --git a/core/java/android/content/IntentSender.java b/core/java/android/content/IntentSender.java index 1801488..079241a 100644 --- a/core/java/android/content/IntentSender.java +++ b/core/java/android/content/IntentSender.java @@ -245,22 +245,22 @@ public class IntentSender implements Parcelable { /** * Return the user handle of the application that created this * PendingIntent, that is the user under which you will actually be - * sending the Intent. The returned integer is supplied by the system, so + * sending the Intent. The returned UserHandle is supplied by the system, so * that an application can not spoof its user. See * {@link android.os.Process#myUserHandle() Process.myUserHandle()} for * more explanation of user handles. * - * @return The user handle of the PendingIntent, or -1 if there is + * @return The user handle of the PendingIntent, or null if there is * none associated with it. */ - public int getTargetUserHandle() { + public UserHandle getTargetUserHandle() { try { int uid = ActivityManagerNative.getDefault() .getUidForIntentSender(mTarget); - return uid > 0 ? UserHandle.getUserId(uid) : -1; + return uid > 0 ? new UserHandle(UserHandle.getUserId(uid)) : null; } catch (RemoteException e) { // Should never happen. - return -1; + return null; } } diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java index 3d3ff51..ee075b4 100644 --- a/core/java/android/content/SyncManager.java +++ b/core/java/android/content/SyncManager.java @@ -895,7 +895,7 @@ public class SyncManager implements OnAccountsUpdateListener { } private void onUserRemoved(Intent intent) { - int userId = intent.getIntExtra(Intent.EXTRA_USERID, -1); + int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); if (userId == -1) return; // Clean up the storage engine database diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 22807a4..3f4b994 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -39,6 +39,7 @@ import android.content.pm.PermissionInfo; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.pm.UserInfo; +import android.content.pm.VerificationParams; import android.content.pm.VerifierDeviceIdentity; import android.net.Uri; import android.os.ParcelFileDescriptor; @@ -200,7 +201,7 @@ interface IPackageManager { List<PackageInfo> getPreferredPackages(int flags); void addPreferredActivity(in IntentFilter filter, int match, - in ComponentName[] set, in ComponentName activity); + in ComponentName[] set, in ComponentName activity, int userId); void replacePreferredActivity(in IntentFilter filter, int match, in ComponentName[] set, in ComponentName activity); @@ -304,10 +305,11 @@ interface IPackageManager { * Get package statistics including the code, data and cache size for * an already installed package * @param packageName The package name of the application + * @param userHandle Which user the size should be retrieved for * @param observer a callback to use to notify when the asynchronous * retrieval of information is complete. */ - void getPackageSizeInfo(in String packageName, IPackageStatsObserver observer); + void getPackageSizeInfo(in String packageName, int userHandle, IPackageStatsObserver observer); /** * Get a list of shared libraries that are available on the @@ -362,6 +364,11 @@ interface IPackageManager { int flags, in String installerPackageName, in Uri verificationURI, in ManifestDigest manifestDigest, in ContainerEncryptionParams encryptionParams); + void installPackageWithVerificationAndEncryption(in Uri packageURI, + in IPackageInstallObserver observer, int flags, in String installerPackageName, + in VerificationParams verificationParams, + in ContainerEncryptionParams encryptionParams); + void verifyPendingInstall(int id, int verificationCode); VerifierDeviceIdentity getVerifierDeviceIdentity(); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index f287ca5..0461dd1 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -28,6 +28,7 @@ import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Environment; +import android.os.UserHandle; import android.util.AndroidException; import android.util.DisplayMetrics; @@ -2227,6 +2228,37 @@ public abstract class PackageManager { ContainerEncryptionParams encryptionParams); /** + * Similar to + * {@link #installPackage(Uri, IPackageInstallObserver, int, String)} but + * with an extra verification information provided. + * + * @param packageURI The location of the package file to install. This can + * be a 'file:' or a 'content:' URI. + * @param observer An observer callback to get notified when the package + * installation is complete. + * {@link IPackageInstallObserver#packageInstalled(String, int)} + * will be called when that happens. observer may be null to + * indicate that no callback is desired. + * @param flags - possible values: {@link #INSTALL_FORWARD_LOCK}, + * {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST} + * . + * @param installerPackageName Optional package name of the application that + * is performing the installation. This identifies which market + * the package came from. + * @param verificationParams an object that holds signal information to + * assist verification. May be {@code null}. + * @param encryptionParams if the package to be installed is encrypted, + * these parameters describing the encryption and authentication + * used. May be {@code null}. + * + * @hide + */ + public abstract void installPackageWithVerificationAndEncryption(Uri packageURI, + IPackageInstallObserver observer, int flags, String installerPackageName, + VerificationParams verificationParams, + ContainerEncryptionParams encryptionParams); + + /** * Allows a package listening to the * {@link Intent#ACTION_PACKAGE_NEEDS_VERIFICATION package verification * broadcast} to respond to the package manager. The response must include @@ -2376,6 +2408,7 @@ public abstract class PackageManager { * should have the {@link android.Manifest.permission#GET_PACKAGE_SIZE} permission. * * @param packageName The name of the package whose size information is to be retrieved + * @param userHandle The user whose size information should be retrieved. * @param observer An observer callback to get notified when the operation * is complete. * {@link android.content.pm.IPackageStatsObserver#onGetStatsCompleted(PackageStats, boolean)} @@ -2386,10 +2419,20 @@ public abstract class PackageManager { * * @hide */ - public abstract void getPackageSizeInfo(String packageName, + public abstract void getPackageSizeInfo(String packageName, int userHandle, IPackageStatsObserver observer); /** + * Like {@link #getPackageSizeInfo(String, int, IPackageStatsObserver)}, but + * returns the size for the calling user. + * + * @hide + */ + public void getPackageSizeInfo(String packageName, IPackageStatsObserver observer) { + getPackageSizeInfo(packageName, UserHandle.myUserId(), observer); + } + + /** * @deprecated This function no longer does anything; it was an old * approach to managing preferred activities, which has been superceeded * (and conflicts with) the modern activity-based preferences. @@ -2460,6 +2503,17 @@ public abstract class PackageManager { ComponentName[] set, ComponentName activity); /** + * Same as {@link #addPreferredActivity(IntentFilter, int, + ComponentName[], ComponentName)}, but with a specific userId to apply the preference + to. + * @hide + */ + public void addPreferredActivity(IntentFilter filter, int match, + ComponentName[] set, ComponentName activity, int userId) { + throw new RuntimeException("Not implemented. Must override in a subclass."); + } + + /** * @deprecated This is a protected API that should not have been available * to third party applications. It is the platform's responsibility for * assigning preferred activities and this can not be directly modified. diff --git a/core/java/android/content/pm/PackageStats.java b/core/java/android/content/pm/PackageStats.java index 1205da7..cb9039b 100644 --- a/core/java/android/content/pm/PackageStats.java +++ b/core/java/android/content/pm/PackageStats.java @@ -18,6 +18,7 @@ package android.content.pm; import android.os.Parcel; import android.os.Parcelable; +import android.os.UserHandle; /** * implementation of PackageStats associated with a @@ -27,6 +28,9 @@ public class PackageStats implements Parcelable { /** Name of the package to which this stats applies. */ public String packageName; + /** @hide */ + public int userHandle; + /** Size of the code (e.g., APK) */ public long codeSize; @@ -78,33 +82,58 @@ public class PackageStats implements Parcelable { public String toString() { final StringBuilder sb = new StringBuilder("PackageStats{"); sb.append(Integer.toHexString(System.identityHashCode(this))); - sb.append(" packageName="); + sb.append(" "); sb.append(packageName); - sb.append(",codeSize="); - sb.append(codeSize); - sb.append(",dataSize="); - sb.append(dataSize); - sb.append(",cacheSize="); - sb.append(cacheSize); - sb.append(",externalCodeSize="); - sb.append(externalCodeSize); - sb.append(",externalDataSize="); - sb.append(externalDataSize); - sb.append(",externalCacheSize="); - sb.append(externalCacheSize); - sb.append(",externalMediaSize="); - sb.append(externalMediaSize); - sb.append(",externalObbSize="); - sb.append(externalObbSize); + if (codeSize != 0) { + sb.append(" code="); + sb.append(codeSize); + } + if (dataSize != 0) { + sb.append(" data="); + sb.append(dataSize); + } + if (cacheSize != 0) { + sb.append(" cache="); + sb.append(cacheSize); + } + if (externalCodeSize != 0) { + sb.append(" extCode="); + sb.append(externalCodeSize); + } + if (externalDataSize != 0) { + sb.append(" extData="); + sb.append(externalDataSize); + } + if (externalCacheSize != 0) { + sb.append(" extCache="); + sb.append(externalCacheSize); + } + if (externalMediaSize != 0) { + sb.append(" media="); + sb.append(externalMediaSize); + } + if (externalObbSize != 0) { + sb.append(" obb="); + sb.append(externalObbSize); + } + sb.append("}"); return sb.toString(); } public PackageStats(String pkgName) { packageName = pkgName; + userHandle = UserHandle.myUserId(); + } + + /** @hide */ + public PackageStats(String pkgName, int userHandle) { + this.packageName = pkgName; + this.userHandle = userHandle; } public PackageStats(Parcel source) { packageName = source.readString(); + userHandle = source.readInt(); codeSize = source.readLong(); dataSize = source.readLong(); cacheSize = source.readLong(); @@ -117,6 +146,7 @@ public class PackageStats implements Parcelable { public PackageStats(PackageStats pStats) { packageName = pStats.packageName; + userHandle = pStats.userHandle; codeSize = pStats.codeSize; dataSize = pStats.dataSize; cacheSize = pStats.cacheSize; @@ -133,6 +163,7 @@ public class PackageStats implements Parcelable { public void writeToParcel(Parcel dest, int parcelableFlags){ dest.writeString(packageName); + dest.writeInt(userHandle); dest.writeLong(codeSize); dest.writeLong(dataSize); dest.writeLong(cacheSize); diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java index 638e273..060a235 100644 --- a/core/java/android/content/pm/UserInfo.java +++ b/core/java/android/content/pm/UserInfo.java @@ -53,6 +53,7 @@ public class UserInfo implements Parcelable { public static final int FLAG_RESTRICTED = 0x00000008; public int id; + public int serialNumber; public String name; public String iconPath; public int flags; @@ -88,6 +89,7 @@ public class UserInfo implements Parcelable { iconPath = orig.iconPath; id = orig.id; flags = orig.flags; + serialNumber = orig.serialNumber; } @Override @@ -104,6 +106,7 @@ public class UserInfo implements Parcelable { dest.writeString(name); dest.writeString(iconPath); dest.writeInt(flags); + dest.writeInt(serialNumber); } public static final Parcelable.Creator<UserInfo> CREATOR @@ -121,5 +124,6 @@ public class UserInfo implements Parcelable { name = source.readString(); iconPath = source.readString(); flags = source.readInt(); + serialNumber = source.readInt(); } } diff --git a/core/java/android/content/pm/VerificationParams.aidl b/core/java/android/content/pm/VerificationParams.aidl new file mode 100644 index 0000000..5bb7f69 --- /dev/null +++ b/core/java/android/content/pm/VerificationParams.aidl @@ -0,0 +1,19 @@ +/* + * 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. + */ + +package android.content.pm; + +parcelable VerificationParams; diff --git a/core/java/android/content/pm/VerificationParams.java b/core/java/android/content/pm/VerificationParams.java new file mode 100644 index 0000000..9bec87e --- /dev/null +++ b/core/java/android/content/pm/VerificationParams.java @@ -0,0 +1,187 @@ +/* + * 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.content.pm.ManifestDigest; +import android.net.Uri; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Represents verification parameters used to verify packages to be installed. + * + * @hide + */ +public class VerificationParams implements Parcelable { + /** What we print out first when toString() is called. */ + private static final String TO_STRING_PREFIX = "VerificationParams{"; + + /** The location of the supplementary verification file. */ + private final Uri mVerificationURI; + + /** URI referencing where the package was downloaded from. */ + private final Uri mOriginatingURI; + + /** HTTP referrer URI associated with the originatingURI. */ + private final Uri mReferrer; + + /** + * An object that holds the digest of the package which can be used to + * verify ownership. + */ + private final ManifestDigest mManifestDigest; + + /** + * Creates verification specifications for installing with application verification. + * + * @param verificationURI The location of the supplementary verification + * file. This can be a 'file:' or a 'content:' URI. May be {@code null}. + * @param originatingURI URI referencing where the package was downloaded + * from. May be {@code null}. + * @param referrer HTTP referrer URI associated with the originatingURI. + * May be {@code null}. + * @param manifestDigest an object that holds the digest of the package + * which can be used to verify ownership. May be {@code null}. + */ + public VerificationParams(Uri verificationURI, Uri originatingURI, Uri referrer, + ManifestDigest manifestDigest) { + mVerificationURI = verificationURI; + mOriginatingURI = originatingURI; + mReferrer = referrer; + mManifestDigest = manifestDigest; + } + + public Uri getVerificationURI() { + return mVerificationURI; + } + + public Uri getOriginatingURI() { + return mOriginatingURI; + } + + public Uri getReferrer() { + return mReferrer; + } + + public ManifestDigest getManifestDigest() { + return mManifestDigest; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (!(o instanceof VerificationParams)) { + return false; + } + + final VerificationParams other = (VerificationParams) o; + + if (mVerificationURI == null && other.mVerificationURI != null) { + return false; + } + if (!mVerificationURI.equals(other.mVerificationURI)) { + return false; + } + + if (mOriginatingURI == null && other.mOriginatingURI != null) { + return false; + } + if (!mOriginatingURI.equals(other.mOriginatingURI)) { + return false; + } + + if (mReferrer == null && other.mReferrer != null) { + return false; + } + if (!mReferrer.equals(other.mReferrer)) { + return false; + } + + if (mManifestDigest == null && other.mManifestDigest != null) { + return false; + } + if (mManifestDigest != null && !mManifestDigest.equals(other.mManifestDigest)) { + return false; + } + + return true; + } + + @Override + public int hashCode() { + int hash = 3; + + hash += 5 * (mVerificationURI==null?1:mVerificationURI.hashCode()); + hash += 7 * (mOriginatingURI==null?1:mOriginatingURI.hashCode()); + hash += 11 * (mReferrer==null?1:mReferrer.hashCode()); + hash += 13 * (mManifestDigest==null?1:mManifestDigest.hashCode()); + + return hash; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(TO_STRING_PREFIX); + + sb.append("mVerificationURI="); + sb.append(mVerificationURI.toString()); + sb.append(",mOriginatingURI="); + sb.append(mOriginatingURI.toString()); + sb.append(",mReferrer="); + sb.append(mReferrer.toString()); + sb.append(",mManifestDigest="); + sb.append(mManifestDigest.toString()); + sb.append('}'); + + return sb.toString(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeParcelable(mVerificationURI, 0); + dest.writeParcelable(mOriginatingURI, 0); + dest.writeParcelable(mReferrer, 0); + dest.writeParcelable(mManifestDigest, 0); + } + + + private VerificationParams(Parcel source) { + mVerificationURI = source.readParcelable(Uri.class.getClassLoader()); + mOriginatingURI = source.readParcelable(Uri.class.getClassLoader()); + mReferrer = source.readParcelable(Uri.class.getClassLoader()); + mManifestDigest = source.readParcelable(ManifestDigest.class.getClassLoader()); + } + + public static final Parcelable.Creator<VerificationParams> CREATOR = + new Parcelable.Creator<VerificationParams>() { + public VerificationParams createFromParcel(Parcel source) { + return new VerificationParams(source); + } + + public VerificationParams[] newArray(int size) { + return new VerificationParams[size]; + } + }; +} diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index 640044b..a73115c 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -17,12 +17,20 @@ package android.hardware.display; import android.content.Context; +import android.os.Handler; import android.os.IBinder; +import android.os.Looper; +import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.util.Log; +import android.util.SparseArray; +import android.view.CompatibilityInfoHolder; +import android.view.Display; import android.view.DisplayInfo; +import java.util.ArrayList; + /** * Manages the properties, media routing and power state of attached displays. * <p> @@ -34,25 +42,41 @@ import android.view.DisplayInfo; */ public final class DisplayManager { private static final String TAG = "DisplayManager"; + private static final boolean DEBUG = false; + + private static final int MSG_DISPLAY_ADDED = 1; + private static final int MSG_DISPLAY_REMOVED = 2; + private static final int MSG_DISPLAY_CHANGED = 3; private static DisplayManager sInstance; private final IDisplayManager mDm; + // Guarded by mDisplayLock + private final Object mDisplayLock = new Object(); + private final ArrayList<DisplayListenerDelegate> mDisplayListeners = + new ArrayList<DisplayListenerDelegate>(); + + private DisplayManager(IDisplayManager dm) { mDm = dm; } /** * Gets an instance of the display manager. - * @return The display manager instance. + * + * @return The display manager instance, may be null early in system startup + * before the display manager has been fully initialized. + * * @hide */ public static DisplayManager getInstance() { synchronized (DisplayManager.class) { if (sInstance == null) { IBinder b = ServiceManager.getService(Context.DISPLAY_SERVICE); - sInstance = new DisplayManager(IDisplayManager.Stub.asInterface(b)); + if (b != null) { + sInstance = new DisplayManager(IDisplayManager.Stub.asInterface(b)); + } } return sInstance; } @@ -74,4 +98,161 @@ public final class DisplayManager { return false; } } + + /** + * Gets information about a logical display. + * + * The display metrics may be adjusted to provide compatibility + * for legacy applications. + * + * @param displayId The logical display id. + * @param applicationContext The application context from which to obtain + * compatible metrics. + * @return The display object. + */ + public Display getDisplay(int displayId, Context applicationContext) { + if (applicationContext == null) { + throw new IllegalArgumentException("applicationContext must not be null"); + } + + CompatibilityInfoHolder cih = null; + if (displayId == Display.DEFAULT_DISPLAY) { + cih = applicationContext.getCompatibilityInfo(); + } + return getCompatibleDisplay(displayId, cih); + } + + /** + * Gets information about a logical display. + * + * The display metrics may be adjusted to provide compatibility + * for legacy applications. + * + * @param displayId The logical display id. + * @param cih The compatibility info, or null if none is required. + * @return The display object. + * + * @hide + */ + public Display getCompatibleDisplay(int displayId, CompatibilityInfoHolder cih) { + return new Display(displayId, cih); + } + + /** + * Gets information about a logical display without applying any compatibility metrics. + * + * @param displayId The logical display id. + * @return The display object. + * + * @hide + */ + public Display getRealDisplay(int displayId) { + return getCompatibleDisplay(displayId, null); + } + + /** + * Registers an display listener to receive notifications about when + * displays are added, removed or changed. + * + * @param listener The listener to register. + * @param handler The handler on which the listener should be invoked, or null + * if the listener should be invoked on the calling thread's looper. + * + * @see #unregisterDisplayListener + */ + public void registerDisplayListener(DisplayListener listener, Handler handler) { + if (listener == null) { + throw new IllegalArgumentException("listener must not be null"); + } + + synchronized (mDisplayLock) { + int index = findDisplayListenerLocked(listener); + if (index < 0) { + mDisplayListeners.add(new DisplayListenerDelegate(listener, handler)); + } + } + } + + /** + * Unregisters an input device listener. + * + * @param listener The listener to unregister. + * + * @see #registerDisplayListener + */ + public void unregisterDisplayListener(DisplayListener listener) { + if (listener == null) { + throw new IllegalArgumentException("listener must not be null"); + } + + synchronized (mDisplayLock) { + int index = findDisplayListenerLocked(listener); + if (index >= 0) { + DisplayListenerDelegate d = mDisplayListeners.get(index); + d.removeCallbacksAndMessages(null); + mDisplayListeners.remove(index); + } + } + } + + private int findDisplayListenerLocked(DisplayListener listener) { + final int numListeners = mDisplayListeners.size(); + for (int i = 0; i < numListeners; i++) { + if (mDisplayListeners.get(i).mListener == listener) { + return i; + } + } + return -1; + } + + /** + * Listens for changes in available display devices. + */ + public interface DisplayListener { + /** + * Called whenever a logical display has been added to the system. + * Use {@link DisplayManager#getDisplay} to get more information about the display. + * + * @param displayId The id of the logical display that was added. + */ + void onDisplayAdded(int displayId); + + /** + * Called whenever a logical display has been removed from the system. + * + * @param displayId The id of the logical display that was removed. + */ + void onDisplayRemoved(int displayId); + + /** + * Called whenever the properties of a logical display have changed. + * + * @param displayId The id of the logical display that changed. + */ + void onDisplayChanged(int displayId); + } + + private static final class DisplayListenerDelegate extends Handler { + public final DisplayListener mListener; + + public DisplayListenerDelegate(DisplayListener listener, Handler handler) { + super(handler != null ? handler.getLooper() : Looper.myLooper()); + mListener = listener; + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_DISPLAY_ADDED: + mListener.onDisplayAdded(msg.arg1); + break; + case MSG_DISPLAY_REMOVED: + mListener.onDisplayRemoved(msg.arg1); + break; + case MSG_DISPLAY_CHANGED: + mListener.onDisplayChanged(msg.arg1); + break; + } + } + } } diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl index 9bab797..98bd4f5 100644 --- a/core/java/android/hardware/usb/IUsbManager.aidl +++ b/core/java/android/hardware/usb/IUsbManager.aidl @@ -87,4 +87,12 @@ interface IUsbManager /* Sets the file path for USB mass storage backing file. */ void setMassStorageBackingFile(String path); + + /* Allow USB debugging from the attached host. If alwaysAllow is true, add the + * the public key to list of host keys that the user has approved. + */ + void allowUsbDebugging(boolean alwaysAllow, String publicKey); + + /* Deny USB debugging from the attached host */ + void denyUsbDebugging(); } diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index a9de289..d5b9edc 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -39,7 +39,6 @@ import android.text.method.MovementMethod; import android.util.Log; import android.util.PrintWriterPrinter; import android.util.Printer; -import android.view.Display; import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -630,7 +629,7 @@ public class InputMethodService extends AbstractInputMethodService { if (mWindow != null) { throw new IllegalStateException("Must be called before onCreate()"); } - if (ActivityManager.isHighEndGfx(new Display(Display.DEFAULT_DISPLAY, null))) { + if (ActivityManager.isHighEndGfx()) { mHardwareAccelerated = true; return true; } diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java index 00438a1..d59fa6a 100644 --- a/core/java/android/net/MobileDataStateTracker.java +++ b/core/java/android/net/MobileDataStateTracker.java @@ -184,8 +184,17 @@ public class MobileDataStateTracker implements NetworkStateTracker { if (!TextUtils.equals(apnType, mApnType)) { return; } - mNetworkInfo.setSubtype(TelephonyManager.getDefault().getNetworkType(), - TelephonyManager.getDefault().getNetworkTypeName()); + + int oldSubtype = mNetworkInfo.getSubtype(); + int newSubType = TelephonyManager.getDefault().getNetworkType(); + String subTypeName = TelephonyManager.getDefault().getNetworkTypeName(); + mNetworkInfo.setSubtype(newSubType, subTypeName); + if (newSubType != oldSubtype && mNetworkInfo.isConnected()) { + Message msg = mTarget.obtainMessage(EVENT_NETWORK_SUBTYPE_CHANGED, + oldSubtype, 0, mNetworkInfo); + msg.sendToTarget(); + } + PhoneConstants.DataState state = Enum.valueOf(PhoneConstants.DataState.class, intent.getStringExtra(PhoneConstants.STATE_KEY)); String reason = intent.getStringExtra(PhoneConstants.STATE_CHANGE_REASON_KEY); diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java index 313c174..eae89f1 100644 --- a/core/java/android/net/NetworkStateTracker.java +++ b/core/java/android/net/NetworkStateTracker.java @@ -63,6 +63,12 @@ public interface NetworkStateTracker { public static final int EVENT_RESTORE_DEFAULT_NETWORK = 6; /** + * msg.what = EVENT_NETWORK_SUBTYPE_CHANGED + * msg.obj = NetworkInfo object + */ + public static final int EVENT_NETWORK_SUBTYPE_CHANGED = 7; + + /** * ------------------------------------------------------------- * Control Interface * ------------------------------------------------------------- diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java index c62715b..7b16f4d 100644 --- a/core/java/android/os/BatteryManager.java +++ b/core/java/android/os/BatteryManager.java @@ -115,4 +115,6 @@ public class BatteryManager { public static final int BATTERY_PLUGGED_AC = 1; /** Power source is a USB port. */ public static final int BATTERY_PLUGGED_USB = 2; + /** Power source is wireless. */ + public static final int BATTERY_PLUGGED_WIRELESS = 4; } diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index fcc0ae4..54f2fe3 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -2071,6 +2071,9 @@ public abstract class BatteryStats implements Parcelable { case BatteryManager.BATTERY_PLUGGED_USB: pw.print("usb"); break; + case BatteryManager.BATTERY_PLUGGED_WIRELESS: + pw.print("wireless"); + break; default: pw.print(oldPlug); break; diff --git a/core/java/android/os/FactoryTest.java b/core/java/android/os/FactoryTest.java new file mode 100644 index 0000000..ec99697 --- /dev/null +++ b/core/java/android/os/FactoryTest.java @@ -0,0 +1,35 @@ +/* + * 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.os; + +/** + * Provides support for in-place factory test functions. + * + * This class provides a few properties that alter the normal operation of the system + * during factory testing. + * + * {@hide} + */ +public final class FactoryTest { + /** + * When true, long-press on power should immediately cause the device to + * shut down, without prompting the user. + */ + public static boolean isLongPressOnPowerOffEnabled() { + return SystemProperties.getInt("factory.long_press_power_off", 0) != 0; + } +} diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java index 6c1445d..0941d71 100644 --- a/core/java/android/os/FileUtils.java +++ b/core/java/android/os/FileUtils.java @@ -28,9 +28,6 @@ import java.util.regex.Pattern; import java.util.zip.CRC32; import java.util.zip.CheckedInputStream; -import libcore.io.Os; -import libcore.io.StructStat; - /** * Tools for managing files. Not for public consumption. * @hide @@ -50,60 +47,12 @@ public class FileUtils { public static final int S_IROTH = 00004; public static final int S_IWOTH = 00002; public static final int S_IXOTH = 00001; - - - /** - * File status information. This class maps directly to the POSIX stat structure. - * @deprecated use {@link StructStat} instead. - * @hide - */ - @Deprecated - public static final class FileStatus { - public int dev; - public int ino; - public int mode; - public int nlink; - public int uid; - public int gid; - public int rdev; - public long size; - public int blksize; - public long blocks; - public long atime; - public long mtime; - public long ctime; - } - - /** - * Get the status for the given path. This is equivalent to the POSIX stat(2) system call. - * @param path The path of the file to be stat'd. - * @param status Optional argument to fill in. It will only fill in the status if the file - * exists. - * @return true if the file exists and false if it does not exist. If you do not have - * permission to stat the file, then this method will return false. - * @deprecated use {@link Os#stat(String)} instead. - */ - @Deprecated - public static boolean getFileStatus(String path, FileStatus status) { - StrictMode.noteDiskRead(); - return getFileStatusNative(path, status); - } - - private static native boolean getFileStatusNative(String path, FileStatus status); /** Regular expression for safe filenames: no spaces or metacharacters */ private static final Pattern SAFE_FILENAME_PATTERN = Pattern.compile("[\\w%+,./=_-]+"); public static native int setPermissions(String file, int mode, int uid, int gid); - /** - * @deprecated use {@link Os#stat(String)} instead. - */ - @Deprecated - public static native int getPermissions(String file, int[] outPermissions); - - public static native int setUMask(int mask); - /** returns the FAT file system volume ID for the volume mounted * at the given mount point, or -1 for failure * @param mountPoint point for FAT volume diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl index cb1b962..c7a8493 100644 --- a/core/java/android/os/IUserManager.aidl +++ b/core/java/android/os/IUserManager.aidl @@ -33,4 +33,6 @@ interface IUserManager { void setGuestEnabled(boolean enable); boolean isGuestEnabled(); void wipeUser(int userHandle); + int getUserSerialNumber(int userHandle); + int getUserHandle(int userSerialNumber); } diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index 5118f1a..3513bdc 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -376,12 +376,13 @@ public class Process { public static final ProcessStartResult start(final String processClass, final String niceName, int uid, int gid, int[] gids, - int debugFlags, int targetSdkVersion, + int debugFlags, int mountExternal, + int targetSdkVersion, String seInfo, String[] zygoteArgs) { try { return startViaZygote(processClass, niceName, uid, gid, gids, - debugFlags, targetSdkVersion, seInfo, zygoteArgs); + debugFlags, mountExternal, targetSdkVersion, seInfo, zygoteArgs); } catch (ZygoteStartFailedEx ex) { Log.e(LOG_TAG, "Starting VM process through Zygote failed"); @@ -553,7 +554,8 @@ public class Process { final String niceName, final int uid, final int gid, final int[] gids, - int debugFlags, int targetSdkVersion, + int debugFlags, int mountExternal, + int targetSdkVersion, String seInfo, String[] extraArgs) throws ZygoteStartFailedEx { @@ -580,6 +582,11 @@ public class Process { if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) { argsForZygote.add("--enable-assert"); } + if (mountExternal == Zygote.MOUNT_EXTERNAL_SINGLEUSER) { + argsForZygote.add("--mount-external-singleuser"); + } else if (mountExternal == Zygote.MOUNT_EXTERNAL_MULTIUSER) { + argsForZygote.add("--mount-external-multiuser"); + } argsForZygote.add("--target-sdk-version=" + targetSdkVersion); //TODO optionally enable debuger @@ -648,13 +655,13 @@ public class Process { public static final native int myUid(); /** - * Returns the identifier of this process's user handle. This is the + * Returns this process's user handle. This is the * user the process is running under. It is distinct from * {@link #myUid()} in that a particular user will have multiple * distinct apps running under it each with their own uid. */ - public static final int myUserHandle() { - return UserHandle.getUserId(myUid()); + public static final UserHandle myUserHandle() { + return new UserHandle(UserHandle.getUserId(myUid())); } /** diff --git a/core/java/android/os/SELinux.java b/core/java/android/os/SELinux.java index 90cfa37..c05a974 100644 --- a/core/java/android/os/SELinux.java +++ b/core/java/android/os/SELinux.java @@ -1,5 +1,25 @@ +/* + * 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.os; +import android.util.Slog; + +import java.io.IOException; +import java.io.File; import java.io.FileDescriptor; /** @@ -9,6 +29,8 @@ import java.io.FileDescriptor; */ public class SELinux { + private static final String TAG = "SELinux"; + /** * Determine whether SELinux is disabled or enabled. * @return a boolean indicating whether SELinux is enabled. @@ -102,4 +124,53 @@ public class SELinux { * @return a boolean indicating whether permission was granted. */ public static final native boolean checkSELinuxAccess(String scon, String tcon, String tclass, String perm); + + /** + * Restores a file to its default SELinux security context. + * If the system is not compiled with SELinux, then {@code true} + * is automatically returned. + * If SELinux is compiled in, but disabled, then {@code true} is + * returned. + * + * @param pathname The pathname of the file to be relabeled. + * @return a boolean indicating whether the relabeling succeeded. + * @exception NullPointerException if the pathname is a null object. + */ + public static boolean restorecon(String pathname) throws NullPointerException { + if (pathname == null) { throw new NullPointerException(); } + return native_restorecon(pathname); + } + + /** + * Restores a file to its default SELinux security context. + * If the system is not compiled with SELinux, then {@code true} + * is automatically returned. + * If SELinux is compiled in, but disabled, then {@code true} is + * returned. + * + * @param pathname The pathname of the file to be relabeled. + * @return a boolean indicating whether the relabeling succeeded. + */ + private static native boolean native_restorecon(String pathname); + + /** + * Restores a file to its default SELinux security context. + * If the system is not compiled with SELinux, then {@code true} + * is automatically returned. + * If SELinux is compiled in, but disabled, then {@code true} is + * returned. + * + * @param file The File object representing the path to be relabeled. + * @return a boolean indicating whether the relabeling succeeded. + * @exception NullPointerException if the file is a null object. + */ + public static boolean restorecon(File file) throws NullPointerException { + try { + return native_restorecon(file.getCanonicalPath()); + } catch (IOException e) { + Slog.e(TAG, "Error getting canonical path. Restorecon failed for " + + file.getPath(), e); + return false; + } + } } diff --git a/core/java/android/os/StatFs.java b/core/java/android/os/StatFs.java index 912bfdf..ca7fdba 100644 --- a/core/java/android/os/StatFs.java +++ b/core/java/android/os/StatFs.java @@ -16,59 +16,77 @@ package android.os; +import libcore.io.ErrnoException; +import libcore.io.Libcore; +import libcore.io.StructStatFs; + /** - * Retrieve overall information about the space on a filesystem. This is a - * Wrapper for Unix statfs(). + * Retrieve overall information about the space on a filesystem. This is a + * wrapper for Unix statfs(). */ public class StatFs { + private StructStatFs mStat; + /** - * Construct a new StatFs for looking at the stats of the - * filesystem at <var>path</var>. Upon construction, the stat of - * the file system will be performed, and the values retrieved available - * from the methods on this class. - * - * @param path A path in the desired file system to state. + * Construct a new StatFs for looking at the stats of the filesystem at + * {@code path}. Upon construction, the stat of the file system will be + * performed, and the values retrieved available from the methods on this + * class. + * + * @param path path in the desired file system to stat. */ - public StatFs(String path) { native_setup(path); } - + public StatFs(String path) { + mStat = doStat(path); + } + + private static StructStatFs doStat(String path) { + try { + return Libcore.os.statfs(path); + } catch (ErrnoException e) { + throw new IllegalArgumentException("Invalid path: " + path, e); + } + } + /** - * Perform a restat of the file system referenced by this object. This - * is the same as re-constructing the object with the same file system - * path, and the new stat values are available upon return. + * Perform a restat of the file system referenced by this object. This is + * the same as re-constructing the object with the same file system path, + * and the new stat values are available upon return. */ - public void restat(String path) { native_restat(path); } - - @Override - protected void finalize() { native_finalize(); } + public void restat(String path) { + mStat = doStat(path); + } /** - * The size, in bytes, of a block on the file system. This corresponds - * to the Unix statfs.f_bsize field. + * The size, in bytes, of a block on the file system. This corresponds to + * the Unix {@code statfs.f_bsize} field. */ - public native int getBlockSize(); + public int getBlockSize() { + return (int) mStat.f_bsize; + } /** - * The total number of blocks on the file system. This corresponds - * to the Unix statfs.f_blocks field. + * The total number of blocks on the file system. This corresponds to the + * Unix {@code statfs.f_blocks} field. */ - public native int getBlockCount(); + public int getBlockCount() { + return (int) mStat.f_blocks; + } /** * The total number of blocks that are free on the file system, including - * reserved blocks (that are not available to normal applications). This - * corresponds to the Unix statfs.f_bfree field. Most applications will - * want to use {@link #getAvailableBlocks()} instead. + * reserved blocks (that are not available to normal applications). This + * corresponds to the Unix {@code statfs.f_bfree} field. Most applications + * will want to use {@link #getAvailableBlocks()} instead. */ - public native int getFreeBlocks(); + public int getFreeBlocks() { + return (int) mStat.f_bfree; + } /** * The number of blocks that are free on the file system and available to - * applications. This corresponds to the Unix statfs.f_bavail field. + * applications. This corresponds to the Unix {@code statfs.f_bavail} field. */ - public native int getAvailableBlocks(); - - private int mNativeContext; - private native void native_restat(String path); - private native void native_setup(String path); - private native void native_finalize(); + public int getAvailableBlocks() { + return (int) mStat.f_bavail; + } } diff --git a/core/java/android/os/UEventObserver.java b/core/java/android/os/UEventObserver.java index b924e84..d33382b 100644 --- a/core/java/android/os/UEventObserver.java +++ b/core/java/android/os/UEventObserver.java @@ -37,14 +37,79 @@ import java.util.HashMap; * @hide */ public abstract class UEventObserver { - private static final String TAG = UEventObserver.class.getSimpleName(); + private static UEventThread sThread; + + private static native void native_setup(); + private static native int next_event(byte[] buffer); + + public UEventObserver() { + } + + protected void finalize() throws Throwable { + try { + stopObserving(); + } finally { + super.finalize(); + } + } + + private static UEventThread getThread() { + synchronized (UEventObserver.class) { + if (sThread == null) { + sThread = new UEventThread(); + sThread.start(); + } + return sThread; + } + } + + private static UEventThread peekThread() { + synchronized (UEventObserver.class) { + return sThread; + } + } + + /** + * Begin observation of UEvent's.<p> + * This method will cause the UEvent thread to start if this is the first + * invocation of startObserving in this process.<p> + * Once called, the UEvent thread will call onUEvent() when an incoming + * UEvent matches the specified string.<p> + * This method can be called multiple times to register multiple matches. + * Only one call to stopObserving is required even with multiple registered + * matches. + * @param match A substring of the UEvent to match. Use "" to match all + * UEvent's + */ + public final void startObserving(String match) { + final UEventThread t = getThread(); + t.addObserver(match, this); + } + + /** + * End observation of UEvent's.<p> + * This process's UEvent thread will never call onUEvent() on this + * UEventObserver after this call. Repeated calls have no effect. + */ + public final void stopObserving() { + final UEventThread t = getThread(); + if (t != null) { + t.removeObserver(this); + } + } + + /** + * Subclasses of UEventObserver should override this method to handle + * UEvents. + */ + public abstract void onUEvent(UEvent event); /** * Representation of a UEvent. */ - static public class UEvent { + public static final class UEvent { // collection of key=value pairs parsed from the uevent message - public HashMap<String,String> mMap = new HashMap<String,String>(); + private final HashMap<String,String> mMap = new HashMap<String,String>(); public UEvent(String message) { int offset = 0; @@ -79,20 +144,20 @@ public abstract class UEventObserver { } } - private static UEventThread sThread; - private static boolean sThreadStarted = false; - - private static class UEventThread extends Thread { + private static final class UEventThread extends Thread { /** Many to many mapping of string match to observer. * Multimap would be better, but not available in android, so use * an ArrayList where even elements are the String match and odd * elements the corresponding UEventObserver observer */ - private ArrayList<Object> mObservers = new ArrayList<Object>(); - - UEventThread() { + private final ArrayList<Object> mKeysAndObservers = new ArrayList<Object>(); + + private final ArrayList<UEventObserver> mTempObserversToSignal = + new ArrayList<UEventObserver>(); + + public UEventThread() { super("UEventObserver"); } - + public void run() { native_setup(); @@ -101,91 +166,54 @@ public abstract class UEventObserver { while (true) { len = next_event(buffer); if (len > 0) { - String bufferStr = new String(buffer, 0, len); // easier to search a String - synchronized (mObservers) { - for (int i = 0; i < mObservers.size(); i += 2) { - if (bufferStr.indexOf((String)mObservers.get(i)) != -1) { - ((UEventObserver)mObservers.get(i+1)) - .onUEvent(new UEvent(bufferStr)); - } - } + sendEvent(new String(buffer, 0, len)); + } + } + } + + private void sendEvent(String message) { + synchronized (mKeysAndObservers) { + final int N = mKeysAndObservers.size(); + for (int i = 0; i < N; i += 2) { + final String key = (String)mKeysAndObservers.get(i); + if (message.indexOf(key) != -1) { + final UEventObserver observer = + (UEventObserver)mKeysAndObservers.get(i + 1); + mTempObserversToSignal.add(observer); } } } + + if (!mTempObserversToSignal.isEmpty()) { + final UEvent event = new UEvent(message); + final int N = mTempObserversToSignal.size(); + for (int i = 0; i < N; i++) { + final UEventObserver observer = mTempObserversToSignal.get(i); + observer.onUEvent(event); + } + mTempObserversToSignal.clear(); + } } + public void addObserver(String match, UEventObserver observer) { - synchronized(mObservers) { - mObservers.add(match); - mObservers.add(observer); + synchronized (mKeysAndObservers) { + mKeysAndObservers.add(match); + mKeysAndObservers.add(observer); } } + /** Removes every key/value pair where value=observer from mObservers */ public void removeObserver(UEventObserver observer) { - synchronized(mObservers) { - boolean found = true; - while (found) { - found = false; - for (int i = 0; i < mObservers.size(); i += 2) { - if (mObservers.get(i+1) == observer) { - mObservers.remove(i+1); - mObservers.remove(i); - found = true; - break; - } + synchronized (mKeysAndObservers) { + for (int i = 0; i < mKeysAndObservers.size(); ) { + if (mKeysAndObservers.get(i + 1) == observer) { + mKeysAndObservers.remove(i + 1); + mKeysAndObservers.remove(i); + } else { + i += 2; } } } } } - - private static native void native_setup(); - private static native int next_event(byte[] buffer); - - private static final synchronized void ensureThreadStarted() { - if (sThreadStarted == false) { - sThread = new UEventThread(); - sThread.start(); - sThreadStarted = true; - } - } - - /** - * Begin observation of UEvent's.<p> - * This method will cause the UEvent thread to start if this is the first - * invocation of startObserving in this process.<p> - * Once called, the UEvent thread will call onUEvent() when an incoming - * UEvent matches the specified string.<p> - * This method can be called multiple times to register multiple matches. - * Only one call to stopObserving is required even with multiple registered - * matches. - * @param match A substring of the UEvent to match. Use "" to match all - * UEvent's - */ - public final synchronized void startObserving(String match) { - ensureThreadStarted(); - sThread.addObserver(match, this); - } - - /** - * End observation of UEvent's.<p> - * This process's UEvent thread will never call onUEvent() on this - * UEventObserver after this call. Repeated calls have no effect. - */ - public final synchronized void stopObserving() { - sThread.removeObserver(this); - } - - /** - * Subclasses of UEventObserver should override this method to handle - * UEvents. - */ - public abstract void onUEvent(UEvent event); - - protected void finalize() throws Throwable { - try { - stopObserving(); - } finally { - super.finalize(); - } - } } diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java index 577a8c6..0843d85 100644 --- a/core/java/android/os/UserHandle.java +++ b/core/java/android/os/UserHandle.java @@ -18,31 +18,33 @@ package android.os; /** * Representation of a user on the device. - * @hide */ -public final class UserHandle { +public final class UserHandle implements Parcelable { /** - * Range of IDs allocated for a user. - * - * @hide + * @hide Range of uids allocated for a user. */ public static final int PER_USER_RANGE = 100000; - /** A user id to indicate all users on the device */ + /** @hide A user id to indicate all users on the device */ public static final int USER_ALL = -1; - /** A user id to indicate the currently active user */ + /** @hide A user id to indicate the currently active user */ public static final int USER_CURRENT = -2; - /** A user id constant to indicate the "owner" user of the device */ + /** @hide An undefined user id */ + public static final int USER_NULL = -10000; + + /** @hide A user id constant to indicate the "owner" user of the device */ public static final int USER_OWNER = 0; /** - * Enable multi-user related side effects. Set this to false if there are problems with single - * user usecases. - * */ + * @hide Enable multi-user related side effects. Set this to false if + * there are problems with single user use-cases. + */ public static final boolean MU_ENABLED = true; + final int mHandle; + /** * Checks to see if the user id is the same for the two uids, i.e., they belong to the same * user. @@ -64,11 +66,13 @@ public final class UserHandle { return getAppId(uid1) == getAppId(uid2); } + /** @hide */ public static final boolean isIsolated(int uid) { uid = getAppId(uid); return uid >= Process.FIRST_ISOLATED_UID && uid <= Process.LAST_ISOLATED_UID; } + /** @hide */ public static boolean isApp(int uid) { if (uid > 0) { uid = UserHandle.getAppId(uid); @@ -90,6 +94,7 @@ public final class UserHandle { } } + /** @hide */ public static final int getCallingUserId() { return getUserId(Binder.getCallingUid()); } @@ -117,8 +122,107 @@ public final class UserHandle { /** * Returns the user id of the current process * @return user id of the current process + * @hide */ public static final int myUserId() { return getUserId(Process.myUid()); } + + /** @hide */ + public UserHandle(int h) { + mHandle = h; + } + + /** @hide */ + public int getIdentifier() { + return mHandle; + } + + @Override + public String toString() { + return "UserHandle{" + mHandle + "}"; + } + + @Override + public boolean equals(Object obj) { + try { + if (obj != null) { + UserHandle other = (UserHandle)obj; + return mHandle == other.mHandle; + } + } catch (ClassCastException e) { + } + return false; + } + + @Override + public int hashCode() { + return mHandle; + } + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mHandle); + } + + /** + * Write a UserHandle to a Parcel, handling null pointers. Must be + * read with {@link #readFromParcel(Parcel)}. + * + * @param h The UserHandle to be written. + * @param out The Parcel in which the UserHandle will be placed. + * + * @see #readFromParcel(Parcel) + */ + public static void writeToParcel(UserHandle h, Parcel out) { + if (h != null) { + h.writeToParcel(out, 0); + } else { + out.writeInt(USER_NULL); + } + } + + /** + * Read a UserHandle from a Parcel that was previously written + * with {@link #writeToParcel(UserHandle, Parcel)}, returning either + * a null or new object as appropriate. + * + * @param in The Parcel from which to read the UserHandle + * @return Returns a new UserHandle matching the previously written + * object, or null if a null had been written. + * + * @see #writeToParcel(UserHandle, Parcel) + */ + public static UserHandle readFromParcel(Parcel in) { + int h = in.readInt(); + return h != USER_NULL ? new UserHandle(h) : null; + } + + public static final Parcelable.Creator<UserHandle> CREATOR + = new Parcelable.Creator<UserHandle>() { + public UserHandle createFromParcel(Parcel in) { + return new UserHandle(in); + } + + public UserHandle[] newArray(int size) { + return new UserHandle[size]; + } + }; + + /** + * Instantiate a new UserHandle from the data in a Parcel that was + * previously written with {@link #writeToParcel(Parcel, int)}. Note that you + * must not use this with data written by + * {@link #writeToParcel(UserHandle, Parcel)} since it is not possible + * to handle a null UserHandle here. + * + * @param in The Parcel containing the previously written UserHandle, + * positioned at the location in the buffer where it was written. + */ + public UserHandle(Parcel in) { + mHandle = in.readInt(); + } } diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 9c73392..0338ee7 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -51,7 +51,7 @@ public class UserManager { * @hide * */ public int getUserHandle() { - return Process.myUserHandle(); + return UserHandle.myUserId(); } /** @@ -209,4 +209,40 @@ public class UserManager { public int getMaxSupportedUsers() { return mContext.getResources().getInteger(R.integer.config_multiuserMaximumUsers); } + + /** + * Returns a serial number on this device for a given userHandle. User handles can be recycled + * when deleting and creating users, but serial numbers are not reused until the device is wiped. + * @param userHandle + * @return a serial number associated with that user, or -1 if the userHandle is not valid. + * @hide + */ + public int getUserSerialNumber(int userHandle) { + try { + return mService.getUserSerialNumber(userHandle); + } catch (RemoteException re) { + Log.w(TAG, "Could not get serial number for user " + userHandle); + } + return -1; + } + + /** + * Returns a userHandle on this device for a given user serial number. User handles can be + * recycled when deleting and creating users, but serial numbers are not reused until the device + * is wiped. + * @param userSerialNumber + * @return the userHandle associated with that user serial number, or -1 if the serial number + * is not valid. + * @hide + */ + public int getUserHandle(int userSerialNumber) { + try { + return mService.getUserHandle(userSerialNumber); + } catch (RemoteException re) { + Log.w(TAG, "Could not get userHandle for user " + userSerialNumber); + } + return -1; + } + + } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 6dbba46..28273f0 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -1147,6 +1147,7 @@ public final class Settings { * <li>{@code 0} to never stay on while plugged in</li> * <li>{@link BatteryManager#BATTERY_PLUGGED_AC} to stay on for AC charger</li> * <li>{@link BatteryManager#BATTERY_PLUGGED_USB} to stay on for USB charger</li> + * <li>{@link BatteryManager#BATTERY_PLUGGED_WIRELESS} to stay on for wireless charger</li> * </ul> * These values can be OR-ed together. */ diff --git a/core/java/android/service/dreams/DreamManagerService.java b/core/java/android/service/dreams/DreamManagerService.java index fc3f501..5d6b17e 100644 --- a/core/java/android/service/dreams/DreamManagerService.java +++ b/core/java/android/service/dreams/DreamManagerService.java @@ -18,6 +18,7 @@ import android.provider.Settings; import android.util.Slog; import android.view.IWindowManager; import android.view.WindowManager; +import android.view.WindowManagerGlobal; /** * @@ -44,8 +45,7 @@ public class DreamManagerService public DreamManagerService(Context context) { if (DEBUG) Slog.v(TAG, "DreamManagerService startup"); mContext = context; - mIWindowManager = IWindowManager.Stub.asInterface( - ServiceManager.getService(Context.WINDOW_SERVICE)); + mIWindowManager = WindowManagerGlobal.getWindowManagerService(); } private void checkPermission(String permission) { diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index b513915..efa8911 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -36,7 +36,6 @@ import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.PowerManager; -import android.os.Process; import android.os.RemoteException; import android.util.Log; import android.util.LogPrinter; @@ -51,9 +50,8 @@ import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.View; import android.view.ViewGroup; -import android.view.ViewRootImpl; import android.view.WindowManager; -import android.view.WindowManagerImpl; +import android.view.WindowManagerGlobal; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -674,8 +672,8 @@ public abstract class WallpaperService extends Service { } } - redrawNeeded |= creating - || (relayoutResult&WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0; + redrawNeeded |= creating || (relayoutResult + & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0; if (forceReport || creating || surfaceCreating || formatChanged || sizeChanged) { @@ -762,7 +760,7 @@ public abstract class WallpaperService extends Service { mWindowToken = wrapper.mWindowToken; mSurfaceHolder.setSizeFromLayout(); mInitializing = true; - mSession = ViewRootImpl.getWindowSession(getMainLooper()); + mSession = WindowManagerGlobal.getWindowSession(getMainLooper()); mWindow.setSession(mSession); diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java index 7a174af..5e367cb 100755 --- a/core/java/android/speech/tts/TextToSpeech.java +++ b/core/java/android/speech/tts/TextToSpeech.java @@ -1282,6 +1282,7 @@ public class TextToSpeech { } }; + @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.i(TAG, "Connected to " + name); synchronized(mStartLock) { @@ -1305,6 +1306,7 @@ public class TextToSpeech { return mCallback; } + @Override public void onServiceDisconnected(ComponentName name) { synchronized(mStartLock) { mService = null; @@ -1317,24 +1319,33 @@ public class TextToSpeech { public void disconnect() { mContext.unbindService(this); + + synchronized (mStartLock) { + mService = null; + // If this is the active connection, clear it + if (mServiceConnection == this) { + mServiceConnection = null; + } + + } } public <R> R runAction(Action<R> action, R errorResult, String method, boolean reconnect) { - try { - synchronized (mStartLock) { + synchronized (mStartLock) { + try { if (mService == null) { Log.w(TAG, method + " failed: not connected to TTS engine"); return errorResult; } return action.run(mService); + } catch (RemoteException ex) { + Log.e(TAG, method + " failed", ex); + if (reconnect) { + disconnect(); + initTts(); + } + return errorResult; } - } catch (RemoteException ex) { - Log.e(TAG, method + " failed", ex); - if (reconnect) { - disconnect(); - initTts(); - } - return errorResult; } } } diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java index 83a70f3..987062a 100644 --- a/core/java/android/text/TextUtils.java +++ b/core/java/android/text/TextUtils.java @@ -27,6 +27,7 @@ import android.text.style.CharacterStyle; import android.text.style.EasyEditSpan; import android.text.style.ForegroundColorSpan; import android.text.style.LeadingMarginSpan; +import android.text.style.LocaleSpan; import android.text.style.MetricAffectingSpan; import android.text.style.QuoteSpan; import android.text.style.RelativeSizeSpan; @@ -587,6 +588,8 @@ public class TextUtils { public static final int SUGGESTION_RANGE_SPAN = 21; /** @hide */ public static final int EASY_EDIT_SPAN = 22; + /** @hide */ + public static final int LOCALE_SPAN = 23; /** * Flatten a CharSequence and whatever styles can be copied across processes @@ -754,6 +757,10 @@ public class TextUtils { readSpan(p, sp, new EasyEditSpan()); break; + case LOCALE_SPAN: + readSpan(p, sp, new LocaleSpan(p)); + break; + default: throw new RuntimeException("bogus span encoding " + kind); } diff --git a/core/java/android/text/style/LocaleSpan.java b/core/java/android/text/style/LocaleSpan.java new file mode 100644 index 0000000..a12c42f --- /dev/null +++ b/core/java/android/text/style/LocaleSpan.java @@ -0,0 +1,84 @@ +/* + * 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.text.style; + +import android.graphics.Paint; +import android.os.Parcel; +import android.text.ParcelableSpan; +import android.text.TextPaint; +import android.text.TextUtils; +import java.util.Locale; + +/** + * Changes the {@link Locale} of the text to which the span is attached. + */ +public class LocaleSpan extends MetricAffectingSpan implements ParcelableSpan { + private final Locale mLocale; + + /** + * Creates a LocaleSpan. + * @param locale The {@link Locale} of the text to which the span is + * attached. + */ + public LocaleSpan(Locale locale) { + mLocale = locale; + } + + public LocaleSpan(Parcel src) { + mLocale = new Locale(src.readString(), src.readString(), src.readString()); + } + + @Override + public int getSpanTypeId() { + return TextUtils.LOCALE_SPAN; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(mLocale.getLanguage()); + dest.writeString(mLocale.getCountry()); + dest.writeString(mLocale.getVariant()); + } + + /** + * Returns the {@link Locale}. + * + * @return The {@link Locale} for this span. + */ + public Locale getLocale() { + return mLocale; + } + + @Override + public void updateDrawState(TextPaint ds) { + apply(ds, mLocale); + } + + @Override + public void updateMeasureState(TextPaint paint) { + apply(paint, mLocale); + } + + private static void apply(Paint paint, Locale locale) { + paint.setTextLocale(locale); + } +} diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java index 6288ce5..392d1f2 100644 --- a/core/java/android/view/Choreographer.java +++ b/core/java/android/view/Choreographer.java @@ -16,6 +16,7 @@ package android.view; +import android.hardware.display.DisplayManager; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -165,7 +166,7 @@ public final class Choreographer { mDisplayEventReceiver = USE_VSYNC ? new FrameDisplayEventReceiver(looper) : null; mLastFrameTimeNanos = Long.MIN_VALUE; - Display d = WindowManagerImpl.getDefault().getDefaultDisplay(); + Display d = DisplayManager.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY); mFrameIntervalNanos = (long)(1000000000 / d.getRefreshRate()); mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1]; diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 5409b38..6f8ca13 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -67,20 +67,16 @@ public final class Display { private int mCachedAppHeightCompat; /** - * The default Display id. + * The default Display id, which is the id of the built-in primary display + * assuming there is one. */ public static final int DEFAULT_DISPLAY = 0; /** - * Uninitialized display. - * @hide - */ - public static final int NO_DISPLAY = -1; - - /** * Internal method to create a display. * Applications should use {@link android.view.WindowManager#getDefaultDisplay()} - * to get a display object for the default display. + * or {@link android.hardware.display.DisplayManager#getDisplay} + * to get a display object. * * @hide */ @@ -114,6 +110,31 @@ public final class Display { } /** + * Gets the display's layer stack. + * + * Each display has its own independent layer stack upon which surfaces + * are placed to be managed by surface flinger. + * + * @return The layer stack number. + * @hide + */ + public int getLayerStack() { + // Note: This is the current convention but there is no requirement that + // the display id and layer stack id be the same. + return mDisplayId; + } + + /** + * Gets the compatibility info used by this display instance. + * + * @return The compatibility info holder, or null if none is required. + * @hide + */ + public CompatibilityInfoHolder getCompatibilityInfo() { + return mCompatibilityInfo; + } + + /** * Gets the size of the display, in pixels. * <p> * Note that this value should <em>not</em> be used for computing layouts, @@ -361,5 +382,16 @@ public final class Display { mLastCachedAppSizeUpdate = now; } } + + // For debugging purposes + @Override + public String toString() { + synchronized (this) { + updateDisplayInfoLocked(); + mDisplayInfo.getAppMetrics(mTempMetrics, mCompatibilityInfo); + return "Display id " + mDisplayId + ": " + mDisplayInfo + + ", " + mTempMetrics; + } + } } diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java index c65ce63..e38f245 100644 --- a/core/java/android/view/DisplayInfo.java +++ b/core/java/android/view/DisplayInfo.java @@ -223,4 +223,17 @@ public final class DisplayInfo implements Parcelable { } } } + + // For debugging purposes + @Override + public String toString() { + return "app " + appWidth + " x " + appHeight + + ", real " + logicalWidth + " x " + logicalHeight + + ", largest app " + largestNominalAppWidth + " x " + largestNominalAppHeight + + ", smallest app " + smallestNominalAppWidth + " x " + smallestNominalAppHeight + + ", " + refreshRate + " fps" + + ", rotation " + rotation + + ", density " + logicalDensityDpi + + ", " + physicalXDpi + " x " + physicalYDpi + " dpi"; + } } diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index 188fede..f906e24 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -1101,7 +1101,7 @@ public abstract class HardwareRenderer { attachInfo.mIgnoreDirtyState = true; attachInfo.mDrawingTime = SystemClock.uptimeMillis(); - view.mPrivateFlags |= View.DRAWN; + view.mPrivateFlags |= View.PFLAG_DRAWN; final int surfaceState = checkCurrent(); if (surfaceState != SURFACE_STATE_ERROR) { @@ -1135,9 +1135,9 @@ public abstract class HardwareRenderer { callbacks.onHardwarePreDraw(canvas); try { - view.mRecreateDisplayList = - (view.mPrivateFlags & View.INVALIDATED) == View.INVALIDATED; - view.mPrivateFlags &= ~View.INVALIDATED; + view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED) + == View.PFLAG_INVALIDATED; + view.mPrivateFlags &= ~View.PFLAG_INVALIDATED; long getDisplayListStartTime = 0; if (mProfileEnabled) { diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 5bccdd4..7f2de50 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -84,7 +84,7 @@ interface IWindowManager void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth, int startHeight); void overridePendingAppTransitionThumb(in Bitmap srcThumb, int startX, int startY, - IRemoteCallback startedCallback, boolean delayed); + IRemoteCallback startedCallback, boolean scaleUp); void executeAppTransition(); void setAppStartingWindow(IBinder token, String pkg, int theme, in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes, diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index e93e480..c5d9255 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -59,8 +59,8 @@ interface IWindowSession { * @param requestedWidth The width the window wants to be. * @param requestedHeight The height the window wants to be. * @param viewVisibility Window root view's visibility. - * @param flags Request flags: {@link WindowManagerImpl#RELAYOUT_INSETS_PENDING}, - * {@link WindowManagerImpl#RELAYOUT_DEFER_SURFACE_DESTROY}. + * @param flags Request flags: {@link WindowManagerGlobal#RELAYOUT_INSETS_PENDING}, + * {@link WindowManagerGlobal#RELAYOUT_DEFER_SURFACE_DESTROY}. * @param outFrame Rect in which is placed the new position/size on * screen. * @param outContentInsets Rect in which is placed the offsets from @@ -79,8 +79,8 @@ interface IWindowSession { * was last displayed. * @param outSurface Object in which is placed the new display surface. * - * @return int Result flags: {@link WindowManagerImpl#RELAYOUT_SHOW_FOCUS}, - * {@link WindowManagerImpl#RELAYOUT_FIRST_TIME}. + * @return int Result flags: {@link WindowManagerGlobal#RELAYOUT_SHOW_FOCUS}, + * {@link WindowManagerGlobal#RELAYOUT_FIRST_TIME}. */ int relayout(IWindow window, int seq, in WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 5f5d1f2..517b514 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -246,22 +246,9 @@ public class Surface implements Parcelable { native private static void nativeClassInit(); static { nativeClassInit(); } - /** create a surface @hide */ - public Surface(SurfaceSession s, - int pid, int displayId, int w, int h, int format, int flags) - throws OutOfResourcesException { - checkHeadless(); - - if (DEBUG_RELEASE) { - mCreationStack = new Exception(); - } - mCanvas = new CompatibleCanvas(); - init(s,pid,null,displayId,w,h,format,flags); - } - /** create a surface with a name @hide */ public Surface(SurfaceSession s, - int pid, String name, int displayId, int w, int h, int format, int flags) + int pid, String name, int layerStack, int w, int h, int format, int flags) throws OutOfResourcesException { checkHeadless(); @@ -269,7 +256,7 @@ public class Surface implements Parcelable { mCreationStack = new Exception(); } mCanvas = new CompatibleCanvas(); - init(s,pid,name,displayId,w,h,format,flags); + init(s, pid, name, layerStack, w, h, format, flags); mName = name; } @@ -470,7 +457,7 @@ public class Surface implements Parcelable { /** @hide */ public native void setWindowCrop(Rect crop); /** @hide */ - public native void setDisplayId(int displayId); + public native void setLayerStack(int layerStack); diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index f4d40cb..fdf1c22 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -296,7 +296,7 @@ public class SurfaceView extends View { } boolean opaque = true; - if ((mPrivateFlags & SKIP_DRAW) == 0) { + if ((mPrivateFlags & PFLAG_SKIP_DRAW) == 0) { // this view draws, remove it from the transparent region opaque = super.gatherTransparentRegion(region); } else if (region != null) { @@ -320,7 +320,7 @@ public class SurfaceView extends View { public void draw(Canvas canvas) { if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) { // draw() is not called when SKIP_DRAW is set - if ((mPrivateFlags & SKIP_DRAW) == 0) { + if ((mPrivateFlags & PFLAG_SKIP_DRAW) == 0) { // punch a whole in the view-hierarchy below us canvas.drawColor(0, PorterDuff.Mode.CLEAR); } @@ -332,7 +332,7 @@ public class SurfaceView extends View { protected void dispatchDraw(Canvas canvas) { if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) { // if SKIP_DRAW is cleared, draw() has already punched a hole - if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) { + if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) { // punch a whole in the view-hierarchy below us canvas.drawColor(0, PorterDuff.Mode.CLEAR); } @@ -480,10 +480,10 @@ public class SurfaceView extends View { relayoutResult = mSession.relayout( mWindow, mWindow.mSeq, mLayout, mWidth, mHeight, visible ? VISIBLE : GONE, - WindowManagerImpl.RELAYOUT_DEFER_SURFACE_DESTROY, + WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY, mWinFrame, mContentInsets, mVisibleInsets, mConfiguration, mNewSurface); - if ((relayoutResult&WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0) { + if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) { mReportDrawNeeded = true; } @@ -516,8 +516,8 @@ public class SurfaceView extends View { SurfaceHolder.Callback callbacks[] = null; - final boolean surfaceChanged = - (relayoutResult&WindowManagerImpl.RELAYOUT_RES_SURFACE_CHANGED) != 0; + final boolean surfaceChanged = (relayoutResult + & WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED) != 0; if (mSurfaceCreated && (surfaceChanged || (!visible && visibleChanged))) { mSurfaceCreated = false; if (mSurface.isValid()) { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 59aeffc..b1f5e9e 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -39,6 +39,7 @@ import android.graphics.Region; import android.graphics.Shader; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.hardware.display.DisplayManager; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -1568,17 +1569,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // for mPrivateFlags: /** {@hide} */ - static final int WANTS_FOCUS = 0x00000001; + static final int PFLAG_WANTS_FOCUS = 0x00000001; /** {@hide} */ - static final int FOCUSED = 0x00000002; + static final int PFLAG_FOCUSED = 0x00000002; /** {@hide} */ - static final int SELECTED = 0x00000004; + static final int PFLAG_SELECTED = 0x00000004; /** {@hide} */ - static final int IS_ROOT_NAMESPACE = 0x00000008; + static final int PFLAG_IS_ROOT_NAMESPACE = 0x00000008; /** {@hide} */ - static final int HAS_BOUNDS = 0x00000010; + static final int PFLAG_HAS_BOUNDS = 0x00000010; /** {@hide} */ - static final int DRAWN = 0x00000020; + static final int PFLAG_DRAWN = 0x00000020; /** * When this flag is set, this view is running an animation on behalf of its * children and should therefore not cancel invalidate requests, even if they @@ -1586,58 +1587,58 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * {@hide} */ - static final int DRAW_ANIMATION = 0x00000040; + static final int PFLAG_DRAW_ANIMATION = 0x00000040; /** {@hide} */ - static final int SKIP_DRAW = 0x00000080; + static final int PFLAG_SKIP_DRAW = 0x00000080; /** {@hide} */ - static final int ONLY_DRAWS_BACKGROUND = 0x00000100; + static final int PFLAG_ONLY_DRAWS_BACKGROUND = 0x00000100; /** {@hide} */ - static final int REQUEST_TRANSPARENT_REGIONS = 0x00000200; + static final int PFLAG_REQUEST_TRANSPARENT_REGIONS = 0x00000200; /** {@hide} */ - static final int DRAWABLE_STATE_DIRTY = 0x00000400; + static final int PFLAG_DRAWABLE_STATE_DIRTY = 0x00000400; /** {@hide} */ - static final int MEASURED_DIMENSION_SET = 0x00000800; + static final int PFLAG_MEASURED_DIMENSION_SET = 0x00000800; /** {@hide} */ - static final int FORCE_LAYOUT = 0x00001000; + static final int PFLAG_FORCE_LAYOUT = 0x00001000; /** {@hide} */ - static final int LAYOUT_REQUIRED = 0x00002000; + static final int PFLAG_LAYOUT_REQUIRED = 0x00002000; - private static final int PRESSED = 0x00004000; + private static final int PFLAG_PRESSED = 0x00004000; /** {@hide} */ - static final int DRAWING_CACHE_VALID = 0x00008000; + static final int PFLAG_DRAWING_CACHE_VALID = 0x00008000; /** * Flag used to indicate that this view should be drawn once more (and only once * more) after its animation has completed. * {@hide} */ - static final int ANIMATION_STARTED = 0x00010000; + static final int PFLAG_ANIMATION_STARTED = 0x00010000; - private static final int SAVE_STATE_CALLED = 0x00020000; + private static final int PFLAG_SAVE_STATE_CALLED = 0x00020000; /** * Indicates that the View returned true when onSetAlpha() was called and that * the alpha must be restored. * {@hide} */ - static final int ALPHA_SET = 0x00040000; + static final int PFLAG_ALPHA_SET = 0x00040000; /** * Set by {@link #setScrollContainer(boolean)}. */ - static final int SCROLL_CONTAINER = 0x00080000; + static final int PFLAG_SCROLL_CONTAINER = 0x00080000; /** * Set by {@link #setScrollContainer(boolean)}. */ - static final int SCROLL_CONTAINER_ADDED = 0x00100000; + static final int PFLAG_SCROLL_CONTAINER_ADDED = 0x00100000; /** * View flag indicating whether this view was invalidated (fully or partially.) * * @hide */ - static final int DIRTY = 0x00200000; + static final int PFLAG_DIRTY = 0x00200000; /** * View flag indicating whether this view was invalidated by an opaque @@ -1645,35 +1646,35 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * @hide */ - static final int DIRTY_OPAQUE = 0x00400000; + static final int PFLAG_DIRTY_OPAQUE = 0x00400000; /** - * Mask for {@link #DIRTY} and {@link #DIRTY_OPAQUE}. + * Mask for {@link #PFLAG_DIRTY} and {@link #PFLAG_DIRTY_OPAQUE}. * * @hide */ - static final int DIRTY_MASK = 0x00600000; + static final int PFLAG_DIRTY_MASK = 0x00600000; /** * Indicates whether the background is opaque. * * @hide */ - static final int OPAQUE_BACKGROUND = 0x00800000; + static final int PFLAG_OPAQUE_BACKGROUND = 0x00800000; /** * Indicates whether the scrollbars are opaque. * * @hide */ - static final int OPAQUE_SCROLLBARS = 0x01000000; + static final int PFLAG_OPAQUE_SCROLLBARS = 0x01000000; /** * Indicates whether the view is opaque. * * @hide */ - static final int OPAQUE_MASK = 0x01800000; + static final int PFLAG_OPAQUE_MASK = 0x01800000; /** * Indicates a prepressed state; @@ -1683,27 +1684,27 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * @hide */ - private static final int PREPRESSED = 0x02000000; + private static final int PFLAG_PREPRESSED = 0x02000000; /** * Indicates whether the view is temporarily detached. * * @hide */ - static final int CANCEL_NEXT_UP_EVENT = 0x04000000; + static final int PFLAG_CANCEL_NEXT_UP_EVENT = 0x04000000; /** * Indicates that we should awaken scroll bars once attached * * @hide */ - private static final int AWAKEN_SCROLL_BARS_ON_ATTACH = 0x08000000; + private static final int PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH = 0x08000000; /** * Indicates that the view has received HOVER_ENTER. Cleared on HOVER_EXIT. * @hide */ - private static final int HOVERED = 0x10000000; + private static final int PFLAG_HOVERED = 0x10000000; /** * Indicates that pivotX or pivotY were explicitly set and we should not assume the center @@ -1711,10 +1712,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * @hide */ - private static final int PIVOT_EXPLICITLY_SET = 0x20000000; + private static final int PFLAG_PIVOT_EXPLICITLY_SET = 0x20000000; /** {@hide} */ - static final int ACTIVATED = 0x40000000; + static final int PFLAG_ACTIVATED = 0x40000000; /** * Indicates that this view was specifically invalidated, not just dirtied because some @@ -1724,7 +1725,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * @hide */ - static final int INVALIDATED = 0x80000000; + static final int PFLAG_INVALIDATED = 0x80000000; /* Masks for mPrivateFlags2 */ @@ -1733,7 +1734,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * Cleared when the drag operation concludes. * @hide */ - static final int DRAG_CAN_ACCEPT = 0x00000001; + static final int PFLAG2_DRAG_CAN_ACCEPT = 0x00000001; /** * Indicates that this view is currently directly under the drag location in a @@ -1741,7 +1742,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * the drag exits the view, or when the drag operation concludes. * @hide */ - static final int DRAG_HOVERED = 0x00000002; + static final int PFLAG2_DRAG_HOVERED = 0x00000002; /** * Horizontal layout direction of this view is from Left to Right. @@ -1771,32 +1772,33 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED) * @hide */ - static final int LAYOUT_DIRECTION_MASK_SHIFT = 2; + static final int PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT = 2; /** * Mask for use with private flags indicating bits used for horizontal layout direction. * @hide */ - static final int LAYOUT_DIRECTION_MASK = 0x00000003 << LAYOUT_DIRECTION_MASK_SHIFT; + static final int PFLAG2_LAYOUT_DIRECTION_MASK = 0x00000003 << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT; /** * Indicates whether the view horizontal layout direction has been resolved and drawn to the * right-to-left direction. * @hide */ - static final int LAYOUT_DIRECTION_RESOLVED_RTL = 4 << LAYOUT_DIRECTION_MASK_SHIFT; + static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL = 4 << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT; /** * Indicates whether the view horizontal layout direction has been resolved. * @hide */ - static final int LAYOUT_DIRECTION_RESOLVED = 8 << LAYOUT_DIRECTION_MASK_SHIFT; + static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED = 8 << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT; /** * Mask for use with private flags indicating bits used for resolved horizontal layout direction. * @hide */ - static final int LAYOUT_DIRECTION_RESOLVED_MASK = 0x0000000C << LAYOUT_DIRECTION_MASK_SHIFT; + static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK = 0x0000000C + << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT; /* * Array of horizontal layout direction flags for mapping attribute "layoutDirection" to correct @@ -1823,7 +1825,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * @hide */ - static final int HAS_TRANSIENT_STATE = 0x00000100; + static final int PFLAG2_HAS_TRANSIENT_STATE = 0x00000100; /** @@ -1863,58 +1865,61 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * Default text direction is inherited */ - protected static int TEXT_DIRECTION_DEFAULT = TEXT_DIRECTION_INHERIT; + public static int TEXT_DIRECTION_DEFAULT = TEXT_DIRECTION_INHERIT; /** * Bit shift to get the horizontal layout direction. (bits after LAYOUT_DIRECTION_RESOLVED) * @hide */ - static final int TEXT_DIRECTION_MASK_SHIFT = 6; + static final int PFLAG2_TEXT_DIRECTION_MASK_SHIFT = 6; /** * Mask for use with private flags indicating bits used for text direction. * @hide */ - static final int TEXT_DIRECTION_MASK = 0x00000007 << TEXT_DIRECTION_MASK_SHIFT; + static final int PFLAG2_TEXT_DIRECTION_MASK = 0x00000007 + << PFLAG2_TEXT_DIRECTION_MASK_SHIFT; /** * Array of text direction flags for mapping attribute "textDirection" to correct * flag value. * @hide */ - private static final int[] TEXT_DIRECTION_FLAGS = { - TEXT_DIRECTION_INHERIT << TEXT_DIRECTION_MASK_SHIFT, - TEXT_DIRECTION_FIRST_STRONG << TEXT_DIRECTION_MASK_SHIFT, - TEXT_DIRECTION_ANY_RTL << TEXT_DIRECTION_MASK_SHIFT, - TEXT_DIRECTION_LTR << TEXT_DIRECTION_MASK_SHIFT, - TEXT_DIRECTION_RTL << TEXT_DIRECTION_MASK_SHIFT, - TEXT_DIRECTION_LOCALE << TEXT_DIRECTION_MASK_SHIFT + private static final int[] PFLAG2_TEXT_DIRECTION_FLAGS = { + TEXT_DIRECTION_INHERIT << PFLAG2_TEXT_DIRECTION_MASK_SHIFT, + TEXT_DIRECTION_FIRST_STRONG << PFLAG2_TEXT_DIRECTION_MASK_SHIFT, + TEXT_DIRECTION_ANY_RTL << PFLAG2_TEXT_DIRECTION_MASK_SHIFT, + TEXT_DIRECTION_LTR << PFLAG2_TEXT_DIRECTION_MASK_SHIFT, + TEXT_DIRECTION_RTL << PFLAG2_TEXT_DIRECTION_MASK_SHIFT, + TEXT_DIRECTION_LOCALE << PFLAG2_TEXT_DIRECTION_MASK_SHIFT }; /** * Indicates whether the view text direction has been resolved. * @hide */ - static final int TEXT_DIRECTION_RESOLVED = 0x00000008 << TEXT_DIRECTION_MASK_SHIFT; + static final int PFLAG2_TEXT_DIRECTION_RESOLVED = 0x00000008 + << PFLAG2_TEXT_DIRECTION_MASK_SHIFT; /** * Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED) * @hide */ - static final int TEXT_DIRECTION_RESOLVED_MASK_SHIFT = 10; + static final int PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT = 10; /** * Mask for use with private flags indicating bits used for resolved text direction. * @hide */ - static final int TEXT_DIRECTION_RESOLVED_MASK = 0x00000007 << TEXT_DIRECTION_RESOLVED_MASK_SHIFT; + static final int PFLAG2_TEXT_DIRECTION_RESOLVED_MASK = 0x00000007 + << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT; /** * Indicates whether the view text direction has been resolved to the "first strong" heuristic. * @hide */ - static final int TEXT_DIRECTION_RESOLVED_DEFAULT = - TEXT_DIRECTION_FIRST_STRONG << TEXT_DIRECTION_RESOLVED_MASK_SHIFT; + static final int PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT = + TEXT_DIRECTION_FIRST_STRONG << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT; /* * Default text alignment. The text alignment of this View is inherited from its parent. @@ -1970,58 +1975,59 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * Default text alignment is inherited */ - protected static int TEXT_ALIGNMENT_DEFAULT = TEXT_ALIGNMENT_GRAVITY; + public static int TEXT_ALIGNMENT_DEFAULT = TEXT_ALIGNMENT_GRAVITY; /** * Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED) * @hide */ - static final int TEXT_ALIGNMENT_MASK_SHIFT = 13; + static final int PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT = 13; /** * Mask for use with private flags indicating bits used for text alignment. * @hide */ - static final int TEXT_ALIGNMENT_MASK = 0x00000007 << TEXT_ALIGNMENT_MASK_SHIFT; + static final int PFLAG2_TEXT_ALIGNMENT_MASK = 0x00000007 << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT; /** * Array of text direction flags for mapping attribute "textAlignment" to correct * flag value. * @hide */ - private static final int[] TEXT_ALIGNMENT_FLAGS = { - TEXT_ALIGNMENT_INHERIT << TEXT_ALIGNMENT_MASK_SHIFT, - TEXT_ALIGNMENT_GRAVITY << TEXT_ALIGNMENT_MASK_SHIFT, - TEXT_ALIGNMENT_TEXT_START << TEXT_ALIGNMENT_MASK_SHIFT, - TEXT_ALIGNMENT_TEXT_END << TEXT_ALIGNMENT_MASK_SHIFT, - TEXT_ALIGNMENT_CENTER << TEXT_ALIGNMENT_MASK_SHIFT, - TEXT_ALIGNMENT_VIEW_START << TEXT_ALIGNMENT_MASK_SHIFT, - TEXT_ALIGNMENT_VIEW_END << TEXT_ALIGNMENT_MASK_SHIFT + private static final int[] PFLAG2_TEXT_ALIGNMENT_FLAGS = { + TEXT_ALIGNMENT_INHERIT << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT, + TEXT_ALIGNMENT_GRAVITY << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT, + TEXT_ALIGNMENT_TEXT_START << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT, + TEXT_ALIGNMENT_TEXT_END << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT, + TEXT_ALIGNMENT_CENTER << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT, + TEXT_ALIGNMENT_VIEW_START << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT, + TEXT_ALIGNMENT_VIEW_END << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT }; /** * Indicates whether the view text alignment has been resolved. * @hide */ - static final int TEXT_ALIGNMENT_RESOLVED = 0x00000008 << TEXT_ALIGNMENT_MASK_SHIFT; + static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED = 0x00000008 << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT; /** * Bit shift to get the resolved text alignment. * @hide */ - static final int TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT = 17; + static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT = 17; /** * Mask for use with private flags indicating bits used for text alignment. * @hide */ - static final int TEXT_ALIGNMENT_RESOLVED_MASK = 0x00000007 << TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT; + static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK = 0x00000007 + << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT; /** * Indicates whether if the view text alignment has been resolved to gravity */ - public static final int TEXT_ALIGNMENT_RESOLVED_DEFAULT = - TEXT_ALIGNMENT_GRAVITY << TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT; + private static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT = + TEXT_ALIGNMENT_GRAVITY << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT; // Accessiblity constants for mPrivateFlags2 @@ -2029,7 +2035,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * Shift for the bits in {@link #mPrivateFlags2} related to the * "importantForAccessibility" attribute. */ - static final int IMPORTANT_FOR_ACCESSIBILITY_SHIFT = 20; + static final int PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT = 20; /** * Automatically determine whether a view is important for accessibility. @@ -2055,26 +2061,27 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * Mask for obtainig the bits which specify how to determine * whether a view is important for accessibility. */ - static final int IMPORTANT_FOR_ACCESSIBILITY_MASK = (IMPORTANT_FOR_ACCESSIBILITY_AUTO + static final int PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK = (IMPORTANT_FOR_ACCESSIBILITY_AUTO | IMPORTANT_FOR_ACCESSIBILITY_YES | IMPORTANT_FOR_ACCESSIBILITY_NO) - << IMPORTANT_FOR_ACCESSIBILITY_SHIFT; + << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT; /** * Flag indicating whether a view has accessibility focus. */ - static final int ACCESSIBILITY_FOCUSED = 0x00000040 << IMPORTANT_FOR_ACCESSIBILITY_SHIFT; + static final int PFLAG2_ACCESSIBILITY_FOCUSED = 0x00000040 << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT; /** * Flag indicating whether a view state for accessibility has changed. */ - static final int ACCESSIBILITY_STATE_CHANGED = 0x00000080 << IMPORTANT_FOR_ACCESSIBILITY_SHIFT; + static final int PFLAG2_ACCESSIBILITY_STATE_CHANGED = 0x00000080 + << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT; /** * Flag indicating whether a view failed the quickReject() check in draw(). This condition * is used to check whether later changes to the view's transform should invalidate the * view to force the quickReject test to run again. */ - static final int VIEW_QUICK_REJECTED = 0x10000000; + static final int PFLAG2_VIEW_QUICK_REJECTED = 0x10000000; /** * Flag indicating that start/end padding has been resolved into left/right padding @@ -2083,7 +2090,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * during measurement. In some special cases this is required such as when an adapter-based * view measures prospective children without attaching them to a window. */ - static final int PADDING_RESOLVED = 0x20000000; + static final int PFLAG2_PADDING_RESOLVED = 0x20000000; // There are a couple of flags left in mPrivateFlags2 @@ -2096,19 +2103,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * an animation is cleared between successive frames, in order to tell the associated * DisplayList to clear its animation matrix. */ - static final int VIEW_IS_ANIMATING_TRANSFORM = 0x1; + static final int PFLAG3_VIEW_IS_ANIMATING_TRANSFORM = 0x1; /** * Flag indicating that view has an alpha animation set on it. This is used to track whether an * animation is cleared between successive frames, in order to tell the associated * DisplayList to restore its alpha value. */ - static final int VIEW_IS_ANIMATING_ALPHA = 0x2; + static final int PFLAG3_VIEW_IS_ANIMATING_ALPHA = 0x2; /* End of masks for mPrivateFlags3 */ - static final int DRAG_MASK = DRAG_CAN_ACCEPT | DRAG_HOVERED; + static final int DRAG_MASK = PFLAG2_DRAG_CAN_ACCEPT | PFLAG2_DRAG_HOVERED; /** * Always allow a user to over-scroll this view, provided it is a @@ -2475,16 +2482,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * {@hide} */ @ViewDebug.ExportedProperty(flagMapping = { - @ViewDebug.FlagToString(mask = FORCE_LAYOUT, equals = FORCE_LAYOUT, + @ViewDebug.FlagToString(mask = PFLAG_FORCE_LAYOUT, equals = PFLAG_FORCE_LAYOUT, name = "FORCE_LAYOUT"), - @ViewDebug.FlagToString(mask = LAYOUT_REQUIRED, equals = LAYOUT_REQUIRED, + @ViewDebug.FlagToString(mask = PFLAG_LAYOUT_REQUIRED, equals = PFLAG_LAYOUT_REQUIRED, name = "LAYOUT_REQUIRED"), - @ViewDebug.FlagToString(mask = DRAWING_CACHE_VALID, equals = DRAWING_CACHE_VALID, + @ViewDebug.FlagToString(mask = PFLAG_DRAWING_CACHE_VALID, equals = PFLAG_DRAWING_CACHE_VALID, name = "DRAWING_CACHE_INVALID", outputIf = false), - @ViewDebug.FlagToString(mask = DRAWN, equals = DRAWN, name = "DRAWN", outputIf = true), - @ViewDebug.FlagToString(mask = DRAWN, equals = DRAWN, name = "NOT_DRAWN", outputIf = false), - @ViewDebug.FlagToString(mask = DIRTY_MASK, equals = DIRTY_OPAQUE, name = "DIRTY_OPAQUE"), - @ViewDebug.FlagToString(mask = DIRTY_MASK, equals = DIRTY, name = "DIRTY") + @ViewDebug.FlagToString(mask = PFLAG_DRAWN, equals = PFLAG_DRAWN, name = "DRAWN", outputIf = true), + @ViewDebug.FlagToString(mask = PFLAG_DRAWN, equals = PFLAG_DRAWN, name = "NOT_DRAWN", outputIf = false), + @ViewDebug.FlagToString(mask = PFLAG_DIRTY_MASK, equals = PFLAG_DIRTY_OPAQUE, name = "DIRTY_OPAQUE"), + @ViewDebug.FlagToString(mask = PFLAG_DIRTY_MASK, equals = PFLAG_DIRTY, name = "DIRTY") }) int mPrivateFlags; int mPrivateFlags2; @@ -2790,6 +2797,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback, int mUserPaddingEnd; /** + * Whether a left padding has been defined during layout inflation. + * + * @hide + */ + boolean mUserPaddingLeftDefined = false; + + /** + * Whether a right padding has been defined during layout inflation. + * + * @hide + */ + boolean mUserPaddingRightDefined = false; + + /** * Default undefined padding */ private static final int UNDEFINED_PADDING = Integer.MIN_VALUE; @@ -3086,6 +3107,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ private boolean mSendingHoverAccessibilityEvents; + /** + * Delegate for injecting accessiblity functionality. + */ + AccessibilityDelegate mAccessibilityDelegate; + + /** + * Consistency verifier for debugging purposes. + * @hide + */ + protected final InputEventConsistencyVerifier mInputEventConsistencyVerifier = + InputEventConsistencyVerifier.isInstrumentationEnabled() ? + new InputEventConsistencyVerifier(this, 0) : null; + private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1); /** @@ -3099,10 +3133,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mResources = context != null ? context.getResources() : null; mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED; // Set layout and text direction defaults - mPrivateFlags2 = (LAYOUT_DIRECTION_DEFAULT << LAYOUT_DIRECTION_MASK_SHIFT) | - (TEXT_DIRECTION_DEFAULT << TEXT_DIRECTION_MASK_SHIFT) | - (TEXT_ALIGNMENT_DEFAULT << TEXT_ALIGNMENT_MASK_SHIFT) | - (IMPORTANT_FOR_ACCESSIBILITY_DEFAULT << IMPORTANT_FOR_ACCESSIBILITY_SHIFT); + mPrivateFlags2 = (LAYOUT_DIRECTION_DEFAULT << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) | + (TEXT_DIRECTION_DEFAULT << PFLAG2_TEXT_DIRECTION_MASK_SHIFT) | + (TEXT_ALIGNMENT_DEFAULT << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT) | + (IMPORTANT_FOR_ACCESSIBILITY_DEFAULT << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); setOverScrollMode(OVER_SCROLL_IF_CONTENT_SCROLLS); mUserPaddingStart = UNDEFINED_PADDING; @@ -3110,19 +3144,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * Delegate for injecting accessiblity functionality. - */ - AccessibilityDelegate mAccessibilityDelegate; - - /** - * Consistency verifier for debugging purposes. - * @hide - */ - protected final InputEventConsistencyVerifier mInputEventConsistencyVerifier = - InputEventConsistencyVerifier.isInstrumentationEnabled() ? - new InputEventConsistencyVerifier(this, 0) : null; - - /** * Constructor that is called when inflating a view from XML. This is called * when a view is being constructed from an XML file, supplying attributes * that were specified in the XML file. This version uses a default style of @@ -3195,8 +3216,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, boolean transformSet = false; int scrollbarStyle = SCROLLBARS_INSIDE_OVERLAY; - int overScrollMode = mOverScrollMode; + boolean initializeScrollbars = false; + + final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion; + final int N = a.getIndexCount(); for (int i = 0; i < N; i++) { int attr = a.getIndex(i); @@ -3206,15 +3230,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback, break; case com.android.internal.R.styleable.View_padding: padding = a.getDimensionPixelSize(attr, -1); + mUserPaddingLeftDefined = true; + mUserPaddingRightDefined = true; break; case com.android.internal.R.styleable.View_paddingLeft: leftPadding = a.getDimensionPixelSize(attr, -1); + mUserPaddingLeftDefined = true; break; case com.android.internal.R.styleable.View_paddingTop: topPadding = a.getDimensionPixelSize(attr, -1); break; case com.android.internal.R.styleable.View_paddingRight: rightPadding = a.getDimensionPixelSize(attr, -1); + mUserPaddingRightDefined = true; break; case com.android.internal.R.styleable.View_paddingBottom: bottomPadding = a.getDimensionPixelSize(attr, -1); @@ -3325,12 +3353,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, break; case com.android.internal.R.styleable.View_layoutDirection: // Clear any layout direction flags (included resolved bits) already set - mPrivateFlags2 &= ~(LAYOUT_DIRECTION_MASK | LAYOUT_DIRECTION_RESOLVED_MASK); + mPrivateFlags2 &= ~(PFLAG2_LAYOUT_DIRECTION_MASK | PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK); // Set the layout direction flags depending on the value of the attribute final int layoutDirection = a.getInt(attr, -1); final int value = (layoutDirection != -1) ? LAYOUT_DIRECTION_FLAGS[layoutDirection] : LAYOUT_DIRECTION_DEFAULT; - mPrivateFlags2 |= (value << LAYOUT_DIRECTION_MASK_SHIFT); + mPrivateFlags2 |= (value << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT); break; case com.android.internal.R.styleable.View_drawingCacheQuality: final int cacheQuality = a.getInt(attr, 0); @@ -3359,12 +3387,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (scrollbars != SCROLLBARS_NONE) { viewFlagValues |= scrollbars; viewFlagMasks |= SCROLLBARS_MASK; - initializeScrollbars(a); + initializeScrollbars = true; } break; //noinspection deprecation case R.styleable.View_fadingEdge: - if (context.getApplicationInfo().targetSdkVersion >= ICE_CREAM_SANDWICH) { + if (targetSdkVersion >= ICE_CREAM_SANDWICH) { // Ignore the attribute starting with ICS break; } @@ -3475,19 +3503,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback, break; case R.styleable.View_textDirection: // Clear any text direction flag already set - mPrivateFlags2 &= ~TEXT_DIRECTION_MASK; + mPrivateFlags2 &= ~PFLAG2_TEXT_DIRECTION_MASK; // Set the text direction flags depending on the value of the attribute final int textDirection = a.getInt(attr, -1); if (textDirection != -1) { - mPrivateFlags2 |= TEXT_DIRECTION_FLAGS[textDirection]; + mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_FLAGS[textDirection]; } break; case R.styleable.View_textAlignment: // Clear any text alignment flag already set - mPrivateFlags2 &= ~TEXT_ALIGNMENT_MASK; + mPrivateFlags2 &= ~PFLAG2_TEXT_ALIGNMENT_MASK; // Set the text alignment flag depending on the value of the attribute final int textAlignment = a.getInt(attr, TEXT_ALIGNMENT_DEFAULT); - mPrivateFlags2 |= TEXT_ALIGNMENT_FLAGS[textAlignment]; + mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_FLAGS[textAlignment]; break; case R.styleable.View_importantForAccessibility: setImportantForAccessibility(a.getInt(attr, @@ -3496,12 +3524,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } - a.recycle(); - setOverScrollMode(overScrollMode); - // Cache user padding as we cannot fully resolve padding here (we dont have yet the resolved - // layout direction). Those cached values will be used later during padding resolution. + // Cache start/end user padding as we cannot fully resolve padding here (we dont have yet + // the resolved layout direction). Those cached values will be used later during padding + // resolution. mUserPaddingStart = startPadding; mUserPaddingEnd = endPadding; @@ -3529,6 +3556,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, setFlags(viewFlagValues, viewFlagMasks); } + if (initializeScrollbars) { + initializeScrollbars(a); + } + + a.recycle(); + // Needs to be called after mViewFlags is set if (scrollbarStyle != SCROLLBARS_INSIDE_OVERLAY) { recomputePadding(); @@ -3562,6 +3595,81 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mResources = null; } + public String toString() { + StringBuilder out = new StringBuilder(128); + out.append(getClass().getName()); + out.append('{'); + out.append(Integer.toHexString(System.identityHashCode(this))); + out.append(' '); + switch (mViewFlags&VISIBILITY_MASK) { + case VISIBLE: out.append('V'); break; + case INVISIBLE: out.append('I'); break; + case GONE: out.append('G'); break; + default: out.append('.'); break; + } + out.append((mViewFlags&FOCUSABLE_MASK) == FOCUSABLE ? 'F' : '.'); + out.append((mViewFlags&ENABLED_MASK) == ENABLED ? 'E' : '.'); + out.append((mViewFlags&DRAW_MASK) == WILL_NOT_DRAW ? '.' : 'D'); + out.append((mViewFlags&SCROLLBARS_HORIZONTAL) != 0 ? 'H' : '.'); + out.append((mViewFlags&SCROLLBARS_VERTICAL) != 0 ? 'V' : '.'); + out.append((mViewFlags&CLICKABLE) != 0 ? 'C' : '.'); + out.append((mViewFlags&LONG_CLICKABLE) != 0 ? 'L' : '.'); + out.append(' '); + out.append((mPrivateFlags&PFLAG_IS_ROOT_NAMESPACE) != 0 ? 'R' : '.'); + out.append((mPrivateFlags&PFLAG_FOCUSED) != 0 ? 'F' : '.'); + out.append((mPrivateFlags&PFLAG_SELECTED) != 0 ? 'S' : '.'); + if ((mPrivateFlags&PFLAG_PREPRESSED) != 0) { + out.append('p'); + } else { + out.append((mPrivateFlags&PFLAG_PRESSED) != 0 ? 'P' : '.'); + } + out.append((mPrivateFlags&PFLAG_HOVERED) != 0 ? 'H' : '.'); + out.append((mPrivateFlags&PFLAG_ACTIVATED) != 0 ? 'A' : '.'); + out.append((mPrivateFlags&PFLAG_INVALIDATED) != 0 ? 'I' : '.'); + out.append((mPrivateFlags&PFLAG_DIRTY_MASK) != 0 ? 'D' : '.'); + out.append(' '); + out.append(mLeft); + out.append(','); + out.append(mTop); + out.append('-'); + out.append(mRight); + out.append(','); + out.append(mBottom); + final int id = getId(); + if (id != NO_ID) { + out.append(" #"); + out.append(Integer.toHexString(id)); + final Resources r = mResources; + if (id != 0 && r != null) { + try { + String pkgname; + switch (id&0xff000000) { + case 0x7f000000: + pkgname="app"; + break; + case 0x01000000: + pkgname="android"; + break; + default: + pkgname = r.getResourcePackageName(id); + break; + } + String typename = r.getResourceTypeName(id); + String entryname = r.getResourceEntryName(id); + out.append(" "); + out.append(pkgname); + out.append(":"); + out.append(typename); + out.append("/"); + out.append(entryname); + } catch (Resources.NotFoundException e) { + } + } + } + out.append("}"); + return out.toString(); + } + /** * <p> * Initializes the fading edges from a given set of styled attributes. This @@ -4119,8 +4227,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, System.out.println(this + " requestFocus()"); } - if ((mPrivateFlags & FOCUSED) == 0) { - mPrivateFlags |= FOCUSED; + if ((mPrivateFlags & PFLAG_FOCUSED) == 0) { + mPrivateFlags |= PFLAG_FOCUSED; if (mParent != null) { mParent.requestChildFocus(this, this); @@ -4204,8 +4312,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, System.out.println(this + " clearFocus()"); } - if ((mPrivateFlags & FOCUSED) != 0) { - mPrivateFlags &= ~FOCUSED; + if ((mPrivateFlags & PFLAG_FOCUSED) != 0) { + mPrivateFlags &= ~PFLAG_FOCUSED; if (mParent != null) { mParent.clearChildFocus(this); @@ -4239,8 +4347,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, System.out.println(this + " unFocus()"); } - if ((mPrivateFlags & FOCUSED) != 0) { - mPrivateFlags &= ~FOCUSED; + if ((mPrivateFlags & PFLAG_FOCUSED) != 0) { + mPrivateFlags &= ~PFLAG_FOCUSED; onFocusChanged(false, 0, null); refreshDrawableState(); @@ -4259,7 +4367,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @ViewDebug.ExportedProperty(category = "focus") public boolean hasFocus() { - return (mPrivateFlags & FOCUSED) != 0; + return (mPrivateFlags & PFLAG_FOCUSED) != 0; } /** @@ -4959,7 +5067,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @ViewDebug.ExportedProperty(category = "focus") public boolean isFocused() { - return (mPrivateFlags & FOCUSED) != 0; + return (mPrivateFlags & PFLAG_FOCUSED) != 0; } /** @@ -4970,7 +5078,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * be found. */ public View findFocus() { - return (mPrivateFlags & FOCUSED) != 0 ? this : null; + return (mPrivateFlags & PFLAG_FOCUSED) != 0 ? this : null; } /** @@ -4983,7 +5091,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @attr ref android.R.styleable#View_isScrollContainer */ public boolean isScrollContainer() { - return (mPrivateFlags & SCROLL_CONTAINER_ADDED) != 0; + return (mPrivateFlags & PFLAG_SCROLL_CONTAINER_ADDED) != 0; } /** @@ -4997,16 +5105,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void setScrollContainer(boolean isScrollContainer) { if (isScrollContainer) { - if (mAttachInfo != null && (mPrivateFlags&SCROLL_CONTAINER_ADDED) == 0) { + if (mAttachInfo != null && (mPrivateFlags&PFLAG_SCROLL_CONTAINER_ADDED) == 0) { mAttachInfo.mScrollContainers.add(this); - mPrivateFlags |= SCROLL_CONTAINER_ADDED; + mPrivateFlags |= PFLAG_SCROLL_CONTAINER_ADDED; } - mPrivateFlags |= SCROLL_CONTAINER; + mPrivateFlags |= PFLAG_SCROLL_CONTAINER; } else { - if ((mPrivateFlags&SCROLL_CONTAINER_ADDED) != 0) { + if ((mPrivateFlags&PFLAG_SCROLL_CONTAINER_ADDED) != 0) { mAttachInfo.mScrollContainers.remove(this); } - mPrivateFlags &= ~(SCROLL_CONTAINER|SCROLL_CONTAINER_ADDED); + mPrivateFlags &= ~(PFLAG_SCROLL_CONTAINER|PFLAG_SCROLL_CONTAINER_ADDED); } } @@ -5513,7 +5621,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LOCALE, to = "LOCALE") }) public int getLayoutDirection() { - return (mPrivateFlags2 & LAYOUT_DIRECTION_MASK) >> LAYOUT_DIRECTION_MASK_SHIFT; + return (mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_MASK) >> PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT; } /** @@ -5531,12 +5639,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, public void setLayoutDirection(int layoutDirection) { if (getLayoutDirection() != layoutDirection) { // Reset the current layout direction and the resolved one - mPrivateFlags2 &= ~LAYOUT_DIRECTION_MASK; + mPrivateFlags2 &= ~PFLAG2_LAYOUT_DIRECTION_MASK; resetResolvedLayoutDirection(); - // Set the new layout direction (filtered) and ask for a layout pass + // Reset padding resolution + mPrivateFlags2 &= ~PFLAG2_PADDING_RESOLVED; + // Set the new layout direction (filtered) mPrivateFlags2 |= - ((layoutDirection << LAYOUT_DIRECTION_MASK_SHIFT) & LAYOUT_DIRECTION_MASK); - resolvePadding(); + ((layoutDirection << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) & PFLAG2_LAYOUT_DIRECTION_MASK); + resolveRtlProperties(); + // ... and ask for a layout pass requestLayout(); } } @@ -5552,11 +5663,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @ViewDebug.IntToString(from = LAYOUT_DIRECTION_RTL, to = "RESOLVED_DIRECTION_RTL") }) public int getResolvedLayoutDirection() { + final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion; + if (targetSdkVersion < JELLY_BEAN_MR1) { + mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED; + return LAYOUT_DIRECTION_LTR; + } // The layout direction will be resolved only if needed - if ((mPrivateFlags2 & LAYOUT_DIRECTION_RESOLVED) != LAYOUT_DIRECTION_RESOLVED) { + if ((mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_RESOLVED) != PFLAG2_LAYOUT_DIRECTION_RESOLVED) { resolveLayoutDirection(); } - return ((mPrivateFlags2 & LAYOUT_DIRECTION_RESOLVED_RTL) == LAYOUT_DIRECTION_RESOLVED_RTL) ? + return ((mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL) == PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL) ? LAYOUT_DIRECTION_RTL : LAYOUT_DIRECTION_LTR; } @@ -5585,7 +5701,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @ViewDebug.ExportedProperty(category = "layout") public boolean hasTransientState() { - return (mPrivateFlags2 & HAS_TRANSIENT_STATE) == HAS_TRANSIENT_STATE; + return (mPrivateFlags2 & PFLAG2_HAS_TRANSIENT_STATE) == PFLAG2_HAS_TRANSIENT_STATE; } /** @@ -5612,8 +5728,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if ((hasTransientState && mTransientStateCount == 1) || (!hasTransientState && mTransientStateCount == 0)) { // update flag if we've just incremented up from 0 or decremented down to 0 - mPrivateFlags2 = (mPrivateFlags2 & ~HAS_TRANSIENT_STATE) | - (hasTransientState ? HAS_TRANSIENT_STATE : 0); + mPrivateFlags2 = (mPrivateFlags2 & ~PFLAG2_HAS_TRANSIENT_STATE) | + (hasTransientState ? PFLAG2_HAS_TRANSIENT_STATE : 0); if (mParent != null) { try { mParent.childHasTransientStateChanged(this, hasTransientState); @@ -5736,12 +5852,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * the View's internal state from a previously set "pressed" state. */ public void setPressed(boolean pressed) { - final boolean needsRefresh = pressed != ((mPrivateFlags & PRESSED) == PRESSED); + final boolean needsRefresh = pressed != ((mPrivateFlags & PFLAG_PRESSED) == PFLAG_PRESSED); if (pressed) { - mPrivateFlags |= PRESSED; + mPrivateFlags |= PFLAG_PRESSED; } else { - mPrivateFlags &= ~PRESSED; + mPrivateFlags &= ~PFLAG_PRESSED; } if (needsRefresh) { @@ -5772,7 +5888,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return true if the view is currently pressed, false otherwise */ public boolean isPressed() { - return (mPrivateFlags & PRESSED) == PRESSED; + return (mPrivateFlags & PFLAG_PRESSED) == PFLAG_PRESSED; } /** @@ -6099,7 +6215,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return True if this View is accessibility focused. */ boolean isAccessibilityFocused() { - return (mPrivateFlags2 & ACCESSIBILITY_FOCUSED) != 0; + return (mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) != 0; } /** @@ -6124,8 +6240,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if ((mViewFlags & VISIBILITY_MASK) != VISIBLE) { return false; } - if ((mPrivateFlags2 & ACCESSIBILITY_FOCUSED) == 0) { - mPrivateFlags2 |= ACCESSIBILITY_FOCUSED; + if ((mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) == 0) { + mPrivateFlags2 |= PFLAG2_ACCESSIBILITY_FOCUSED; ViewRootImpl viewRootImpl = getViewRootImpl(); if (viewRootImpl != null) { viewRootImpl.setAccessibilityFocus(this, null); @@ -6147,8 +6263,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide */ public void clearAccessibilityFocus() { - if ((mPrivateFlags2 & ACCESSIBILITY_FOCUSED) != 0) { - mPrivateFlags2 &= ~ACCESSIBILITY_FOCUSED; + if ((mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) != 0) { + mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_FOCUSED; invalidate(); sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED); notifyAccessibilityStateChanged(); @@ -6196,8 +6312,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * another view. */ void clearAccessibilityFocusNoCallbacks() { - if ((mPrivateFlags2 & ACCESSIBILITY_FOCUSED) != 0) { - mPrivateFlags2 &= ~ACCESSIBILITY_FOCUSED; + if ((mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) != 0) { + mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_FOCUSED; invalidate(); } } @@ -6354,8 +6470,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_NO, to = "no") }) public int getImportantForAccessibility() { - return (mPrivateFlags2 & IMPORTANT_FOR_ACCESSIBILITY_MASK) - >> IMPORTANT_FOR_ACCESSIBILITY_SHIFT; + return (mPrivateFlags2 & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK) + >> PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT; } /** @@ -6373,9 +6489,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void setImportantForAccessibility(int mode) { if (mode != getImportantForAccessibility()) { - mPrivateFlags2 &= ~IMPORTANT_FOR_ACCESSIBILITY_MASK; - mPrivateFlags2 |= (mode << IMPORTANT_FOR_ACCESSIBILITY_SHIFT) - & IMPORTANT_FOR_ACCESSIBILITY_MASK; + mPrivateFlags2 &= ~PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK; + mPrivateFlags2 |= (mode << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT) + & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK; notifyAccessibilityStateChanged(); } } @@ -6388,8 +6504,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide */ public boolean isImportantForAccessibility() { - final int mode = (mPrivateFlags2 & IMPORTANT_FOR_ACCESSIBILITY_MASK) - >> IMPORTANT_FOR_ACCESSIBILITY_SHIFT; + final int mode = (mPrivateFlags2 & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK) + >> PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT; switch (mode) { case IMPORTANT_FOR_ACCESSIBILITY_YES: return true; @@ -6498,8 +6614,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (!AccessibilityManager.getInstance(mContext).isEnabled()) { return; } - if ((mPrivateFlags2 & ACCESSIBILITY_STATE_CHANGED) == 0) { - mPrivateFlags2 |= ACCESSIBILITY_STATE_CHANGED; + if ((mPrivateFlags2 & PFLAG2_ACCESSIBILITY_STATE_CHANGED) == 0) { + mPrivateFlags2 |= PFLAG2_ACCESSIBILITY_STATE_CHANGED; if (mParent != null) { mParent.childAccessibilityStateChanged(this); } @@ -6513,7 +6629,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide */ public void resetAccessibilityStateChanged() { - mPrivateFlags2 &= ~ACCESSIBILITY_STATE_CHANGED; + mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_STATE_CHANGED; } /** @@ -6765,7 +6881,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void onStartTemporaryDetach() { removeUnsetPressCallback(); - mPrivateFlags |= CANCEL_NEXT_UP_EVENT; + mPrivateFlags |= PFLAG_CANCEL_NEXT_UP_EVENT; } /** @@ -7084,13 +7200,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (isPressed()) { setPressed(false); } - if (imm != null && (mPrivateFlags & FOCUSED) != 0) { + if (imm != null && (mPrivateFlags & PFLAG_FOCUSED) != 0) { imm.focusOut(this); } removeLongPressCallback(); removeTapCallback(); onFocusLost(); - } else if (imm != null && (mPrivateFlags & FOCUSED) != 0) { + } else if (imm != null && (mPrivateFlags & PFLAG_FOCUSED) != 0) { imm.focusIn(this); } refreshDrawableState(); @@ -7130,7 +7246,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (mAttachInfo != null) { initialAwakenScrollBars(); } else { - mPrivateFlags |= AWAKEN_SCROLL_BARS_ON_ATTACH; + mPrivateFlags |= PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH; } } } @@ -7231,7 +7347,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, outRect.bottom -= insets.bottom; return; } - Display d = WindowManagerImpl.getDefault().getDefaultDisplay(); + Display d = DisplayManager.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY); d.getRectSize(outRect); } @@ -7730,7 +7846,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @ViewDebug.ExportedProperty public boolean isHovered() { - return (mPrivateFlags & HOVERED) != 0; + return (mPrivateFlags & PFLAG_HOVERED) != 0; } /** @@ -7750,14 +7866,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void setHovered(boolean hovered) { if (hovered) { - if ((mPrivateFlags & HOVERED) == 0) { - mPrivateFlags |= HOVERED; + if ((mPrivateFlags & PFLAG_HOVERED) == 0) { + mPrivateFlags |= PFLAG_HOVERED; refreshDrawableState(); onHoverChanged(true); } } else { - if ((mPrivateFlags & HOVERED) != 0) { - mPrivateFlags &= ~HOVERED; + if ((mPrivateFlags & PFLAG_HOVERED) != 0) { + mPrivateFlags &= ~PFLAG_HOVERED; refreshDrawableState(); onHoverChanged(false); } @@ -7789,7 +7905,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, final int viewFlags = mViewFlags; if ((viewFlags & ENABLED_MASK) == DISABLED) { - if (event.getAction() == MotionEvent.ACTION_UP && (mPrivateFlags & PRESSED) != 0) { + if (event.getAction() == MotionEvent.ACTION_UP && (mPrivateFlags & PFLAG_PRESSED) != 0) { setPressed(false); } // A disabled view that is clickable still consumes the touch @@ -7808,8 +7924,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) { switch (event.getAction()) { case MotionEvent.ACTION_UP: - boolean prepressed = (mPrivateFlags & PREPRESSED) != 0; - if ((mPrivateFlags & PRESSED) != 0 || prepressed) { + boolean prepressed = (mPrivateFlags & PFLAG_PREPRESSED) != 0; + if ((mPrivateFlags & PFLAG_PRESSED) != 0 || prepressed) { // take focus if we don't have it already and we should in // touch mode. boolean focusTaken = false; @@ -7871,7 +7987,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // For views inside a scrolling container, delay the pressed feedback for // a short period in case this is a scroll. if (isInScrollingContainer) { - mPrivateFlags |= PREPRESSED; + mPrivateFlags |= PFLAG_PREPRESSED; if (mPendingCheckForTap == null) { mPendingCheckForTap = new CheckForTap(); } @@ -7896,7 +8012,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (!pointInView(x, y, mTouchSlop)) { // Outside button removeTapCallback(); - if ((mPrivateFlags & PRESSED) != 0) { + if ((mPrivateFlags & PFLAG_PRESSED) != 0) { // Remove any future long press/tap checks removeLongPressCallback(); @@ -7947,7 +8063,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * Remove the prepress detection timer. */ private void removeUnsetPressCallback() { - if ((mPrivateFlags & PRESSED) != 0 && mUnsetPressedState != null) { + if ((mPrivateFlags & PFLAG_PRESSED) != 0 && mUnsetPressedState != null) { setPressed(false); removeCallbacks(mUnsetPressedState); } @@ -7958,7 +8074,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ private void removeTapCallback() { if (mPendingCheckForTap != null) { - mPrivateFlags &= ~PREPRESSED; + mPrivateFlags &= ~PFLAG_PREPRESSED; removeCallbacks(mPendingCheckForTap); } } @@ -8023,13 +8139,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /* Check if the FOCUSABLE bit has changed */ if (((changed & FOCUSABLE_MASK) != 0) && - ((privateFlags & HAS_BOUNDS) !=0)) { + ((privateFlags & PFLAG_HAS_BOUNDS) !=0)) { if (((old & FOCUSABLE_MASK) == FOCUSABLE) - && ((privateFlags & FOCUSED) != 0)) { + && ((privateFlags & PFLAG_FOCUSED) != 0)) { /* Give up focus if we are no longer focusable */ clearFocus(); } else if (((old & FOCUSABLE_MASK) == NOT_FOCUSABLE) - && ((privateFlags & FOCUSED) == 0)) { + && ((privateFlags & PFLAG_FOCUSED) == 0)) { /* * Tell the view system that we are now available to take focus * if no one else already has it. @@ -8048,7 +8164,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * it was not visible. Marking it drawn ensures that the invalidation will * go through. */ - mPrivateFlags |= DRAWN; + mPrivateFlags |= PFLAG_DRAWN; invalidate(true); needGlobalAttributesUpdate(true); @@ -8078,7 +8194,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } // Mark the view drawn to ensure that it gets invalidated properly the next // time it is visible and gets invalidated - mPrivateFlags |= DRAWN; + mPrivateFlags |= PFLAG_DRAWN; } if (mAttachInfo != null) { mAttachInfo.mViewVisibilityChanged = true; @@ -8092,7 +8208,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * If this view is becoming invisible, set the DRAWN flag so that * the next invalidate() will not be skipped. */ - mPrivateFlags |= DRAWN; + mPrivateFlags |= PFLAG_DRAWN; if (((mViewFlags & VISIBILITY_MASK) == INVISIBLE) && hasFocus()) { // root view becoming invisible shouldn't clear focus and accessibility focus @@ -8123,25 +8239,25 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if ((changed & DRAWING_CACHE_ENABLED) != 0) { destroyDrawingCache(); - mPrivateFlags &= ~DRAWING_CACHE_VALID; + mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID; invalidateParentCaches(); } if ((changed & DRAWING_CACHE_QUALITY_MASK) != 0) { destroyDrawingCache(); - mPrivateFlags &= ~DRAWING_CACHE_VALID; + mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID; } if ((changed & DRAW_MASK) != 0) { if ((mViewFlags & WILL_NOT_DRAW) != 0) { if (mBackground != null) { - mPrivateFlags &= ~SKIP_DRAW; - mPrivateFlags |= ONLY_DRAWS_BACKGROUND; + mPrivateFlags &= ~PFLAG_SKIP_DRAW; + mPrivateFlags |= PFLAG_ONLY_DRAWS_BACKGROUND; } else { - mPrivateFlags |= SKIP_DRAW; + mPrivateFlags |= PFLAG_SKIP_DRAW; } } else { - mPrivateFlags &= ~SKIP_DRAW; + mPrivateFlags &= ~PFLAG_SKIP_DRAW; } requestLayout(); invalidate(true); @@ -8449,7 +8565,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // asked for the matrix; recalculate it with the current values // Figure out if we need to update the pivot point - if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) { + if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) { if ((mRight - mLeft) != info.mPrevWidth || (mBottom - mTop) != info.mPrevHeight) { info.mPrevWidth = mRight - mLeft; info.mPrevHeight = mBottom - mTop; @@ -8593,7 +8709,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (mDisplayList != null) { mDisplayList.setCameraDistance(-Math.abs(distance) / dpi); } - if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) { + if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { // View was rejected last time it was drawn by its parent; this may have changed invalidateParentIfNeeded(); } @@ -8639,7 +8755,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (mDisplayList != null) { mDisplayList.setRotation(rotation); } - if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) { + if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { // View was rejected last time it was drawn by its parent; this may have changed invalidateParentIfNeeded(); } @@ -8690,7 +8806,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (mDisplayList != null) { mDisplayList.setRotationY(rotationY); } - if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) { + if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { // View was rejected last time it was drawn by its parent; this may have changed invalidateParentIfNeeded(); } @@ -8741,7 +8857,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (mDisplayList != null) { mDisplayList.setRotationX(rotationX); } - if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) { + if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { // View was rejected last time it was drawn by its parent; this may have changed invalidateParentIfNeeded(); } @@ -8784,7 +8900,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (mDisplayList != null) { mDisplayList.setScaleX(scaleX); } - if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) { + if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { // View was rejected last time it was drawn by its parent; this may have changed invalidateParentIfNeeded(); } @@ -8827,7 +8943,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (mDisplayList != null) { mDisplayList.setScaleY(scaleY); } - if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) { + if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { // View was rejected last time it was drawn by its parent; this may have changed invalidateParentIfNeeded(); } @@ -8868,7 +8984,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void setPivotX(float pivotX) { ensureTransformationInfo(); - mPrivateFlags |= PIVOT_EXPLICITLY_SET; + mPrivateFlags |= PFLAG_PIVOT_EXPLICITLY_SET; final TransformationInfo info = mTransformationInfo; if (info.mPivotX != pivotX) { invalidateViewProperty(true, false); @@ -8878,7 +8994,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (mDisplayList != null) { mDisplayList.setPivotX(pivotX); } - if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) { + if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { // View was rejected last time it was drawn by its parent; this may have changed invalidateParentIfNeeded(); } @@ -8918,7 +9034,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void setPivotY(float pivotY) { ensureTransformationInfo(); - mPrivateFlags |= PIVOT_EXPLICITLY_SET; + mPrivateFlags |= PFLAG_PIVOT_EXPLICITLY_SET; final TransformationInfo info = mTransformationInfo; if (info.mPivotY != pivotY) { invalidateViewProperty(true, false); @@ -8928,7 +9044,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (mDisplayList != null) { mDisplayList.setPivotY(pivotY); } - if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) { + if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { // View was rejected last time it was drawn by its parent; this may have changed invalidateParentIfNeeded(); } @@ -8988,12 +9104,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (mTransformationInfo.mAlpha != alpha) { mTransformationInfo.mAlpha = alpha; if (onSetAlpha((int) (alpha * 255))) { - mPrivateFlags |= ALPHA_SET; + mPrivateFlags |= PFLAG_ALPHA_SET; // subclass is handling alpha - don't optimize rendering cache invalidation invalidateParentCaches(); invalidate(true); } else { - mPrivateFlags &= ~ALPHA_SET; + mPrivateFlags &= ~PFLAG_ALPHA_SET; invalidateViewProperty(true, false); if (mDisplayList != null) { mDisplayList.setAlpha(alpha); @@ -9018,10 +9134,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mTransformationInfo.mAlpha = alpha; boolean subclassHandlesAlpha = onSetAlpha((int) (alpha * 255)); if (subclassHandlesAlpha) { - mPrivateFlags |= ALPHA_SET; + mPrivateFlags |= PFLAG_ALPHA_SET; return true; } else { - mPrivateFlags &= ~ALPHA_SET; + mPrivateFlags &= ~PFLAG_ALPHA_SET; if (mDisplayList != null) { mDisplayList.setAlpha(alpha); } @@ -9081,16 +9197,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, onSizeChanged(width, mBottom - mTop, width, oldHeight); if (!matrixIsIdentity) { - if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) { + if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) { // A change in dimension means an auto-centered pivot point changes, too mTransformationInfo.mMatrixDirty = true; } - mPrivateFlags |= DRAWN; // force another invalidation with the new orientation + mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation invalidate(true); } mBackgroundSizeChanged = true; invalidateParentIfNeeded(); - if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) { + if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { // View was rejected last time it was drawn by its parent; this may have changed invalidateParentIfNeeded(); } @@ -9113,7 +9229,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return The dirty state of this view. */ public boolean isDirty() { - return (mPrivateFlags & DIRTY_MASK) != 0; + return (mPrivateFlags & PFLAG_DIRTY_MASK) != 0; } /** @@ -9154,16 +9270,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, onSizeChanged(width, mBottom - mTop, width, oldHeight); if (!matrixIsIdentity) { - if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) { + if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) { // A change in dimension means an auto-centered pivot point changes, too mTransformationInfo.mMatrixDirty = true; } - mPrivateFlags |= DRAWN; // force another invalidation with the new orientation + mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation invalidate(true); } mBackgroundSizeChanged = true; invalidateParentIfNeeded(); - if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) { + if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { // View was rejected last time it was drawn by its parent; this may have changed invalidateParentIfNeeded(); } @@ -9221,16 +9337,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, onSizeChanged(mRight - mLeft, height, oldWidth, height); if (!matrixIsIdentity) { - if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) { + if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) { // A change in dimension means an auto-centered pivot point changes, too mTransformationInfo.mMatrixDirty = true; } - mPrivateFlags |= DRAWN; // force another invalidation with the new orientation + mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation invalidate(true); } mBackgroundSizeChanged = true; invalidateParentIfNeeded(); - if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) { + if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { // View was rejected last time it was drawn by its parent; this may have changed invalidateParentIfNeeded(); } @@ -9285,16 +9401,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, onSizeChanged(mRight - mLeft, height, oldWidth, height); if (!matrixIsIdentity) { - if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) { + if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) { // A change in dimension means an auto-centered pivot point changes, too mTransformationInfo.mMatrixDirty = true; } - mPrivateFlags |= DRAWN; // force another invalidation with the new orientation + mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation invalidate(true); } mBackgroundSizeChanged = true; invalidateParentIfNeeded(); - if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) { + if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { // View was rejected last time it was drawn by its parent; this may have changed invalidateParentIfNeeded(); } @@ -9382,7 +9498,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (mDisplayList != null) { mDisplayList.setTranslationX(translationX); } - if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) { + if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { // View was rejected last time it was drawn by its parent; this may have changed invalidateParentIfNeeded(); } @@ -9423,7 +9539,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (mDisplayList != null) { mDisplayList.setTranslationY(translationY); } - if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) { + if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { // View was rejected last time it was drawn by its parent; this may have changed invalidateParentIfNeeded(); } @@ -9657,6 +9773,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, throw new NullPointerException("Layout parameters cannot be null"); } mLayoutParams = params; + resolveLayoutParams(); if (mParent instanceof ViewGroup) { ((ViewGroup) mParent).onSetLayoutParams(this, params); } @@ -9664,6 +9781,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * Resolve the layout parameters depending on the resolved layout direction + */ + private void resolveLayoutParams() { + if (mLayoutParams != null) { + mLayoutParams.onResolveLayoutDirection(getResolvedLayoutDirection()); + } + } + + /** * Set the scrolled position of your view. This will cause a call to * {@link #onScrollChanged(int, int, int, int)} and the view will be * invalidated. @@ -9884,12 +10010,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (skipInvalidate()) { return; } - if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) || - (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID || - (mPrivateFlags & INVALIDATED) != INVALIDATED) { - mPrivateFlags &= ~DRAWING_CACHE_VALID; - mPrivateFlags |= INVALIDATED; - mPrivateFlags |= DIRTY; + if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS) || + (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID || + (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED) { + mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID; + mPrivateFlags |= PFLAG_INVALIDATED; + mPrivateFlags |= PFLAG_DIRTY; final ViewParent p = mParent; final AttachInfo ai = mAttachInfo; //noinspection PointlessBooleanExpression,ConstantConditions @@ -9927,12 +10053,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (skipInvalidate()) { return; } - if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) || - (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID || - (mPrivateFlags & INVALIDATED) != INVALIDATED) { - mPrivateFlags &= ~DRAWING_CACHE_VALID; - mPrivateFlags |= INVALIDATED; - mPrivateFlags |= DIRTY; + if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS) || + (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID || + (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED) { + mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID; + mPrivateFlags |= PFLAG_INVALIDATED; + mPrivateFlags |= PFLAG_DIRTY; final ViewParent p = mParent; final AttachInfo ai = mAttachInfo; //noinspection PointlessBooleanExpression,ConstantConditions @@ -9979,15 +10105,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (skipInvalidate()) { return; } - if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) || - (invalidateCache && (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID) || - (mPrivateFlags & INVALIDATED) != INVALIDATED || isOpaque() != mLastIsOpaque) { + if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS) || + (invalidateCache && (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID) || + (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED || isOpaque() != mLastIsOpaque) { mLastIsOpaque = isOpaque(); - mPrivateFlags &= ~DRAWN; - mPrivateFlags |= DIRTY; + mPrivateFlags &= ~PFLAG_DRAWN; + mPrivateFlags |= PFLAG_DIRTY; if (invalidateCache) { - mPrivateFlags |= INVALIDATED; - mPrivateFlags &= ~DRAWING_CACHE_VALID; + mPrivateFlags |= PFLAG_INVALIDATED; + mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID; } final AttachInfo ai = mAttachInfo; final ViewParent p = mParent; @@ -10028,12 +10154,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * list properties are not being used in this view */ void invalidateViewProperty(boolean invalidateParent, boolean forceRedraw) { - if (mDisplayList == null || (mPrivateFlags & DRAW_ANIMATION) == DRAW_ANIMATION) { + if (mDisplayList == null || (mPrivateFlags & PFLAG_DRAW_ANIMATION) == PFLAG_DRAW_ANIMATION) { if (invalidateParent) { invalidateParentCaches(); } if (forceRedraw) { - mPrivateFlags |= DRAWN; // force another invalidation with the new orientation + mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation } invalidate(false); } else { @@ -10077,7 +10203,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ protected void invalidateParentCaches() { if (mParent instanceof View) { - ((View) mParent).mPrivateFlags |= INVALIDATED; + ((View) mParent).mPrivateFlags |= PFLAG_INVALIDATED; } } @@ -10109,7 +10235,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @ViewDebug.ExportedProperty(category = "drawing") public boolean isOpaque() { - return (mPrivateFlags & OPAQUE_MASK) == OPAQUE_MASK && + return (mPrivateFlags & PFLAG_OPAQUE_MASK) == PFLAG_OPAQUE_MASK && ((mTransformationInfo != null ? mTransformationInfo.mAlpha : 1.0f) >= 1.0f); } @@ -10123,17 +10249,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // - Doesn't have scrollbars or scrollbars are inside overlay if (mBackground != null && mBackground.getOpacity() == PixelFormat.OPAQUE) { - mPrivateFlags |= OPAQUE_BACKGROUND; + mPrivateFlags |= PFLAG_OPAQUE_BACKGROUND; } else { - mPrivateFlags &= ~OPAQUE_BACKGROUND; + mPrivateFlags &= ~PFLAG_OPAQUE_BACKGROUND; } final int flags = mViewFlags; if (((flags & SCROLLBARS_VERTICAL) == 0 && (flags & SCROLLBARS_HORIZONTAL) == 0) || (flags & SCROLLBARS_STYLE_MASK) == SCROLLBARS_INSIDE_OVERLAY) { - mPrivateFlags |= OPAQUE_SCROLLBARS; + mPrivateFlags |= PFLAG_OPAQUE_SCROLLBARS; } else { - mPrivateFlags &= ~OPAQUE_SCROLLBARS; + mPrivateFlags &= ~PFLAG_OPAQUE_SCROLLBARS; } } @@ -10141,7 +10267,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide */ protected boolean hasOpaqueScrollbars() { - return (mPrivateFlags & OPAQUE_SCROLLBARS) == OPAQUE_SCROLLBARS; + return (mPrivateFlags & PFLAG_OPAQUE_SCROLLBARS) == PFLAG_OPAQUE_SCROLLBARS; } /** @@ -11186,23 +11312,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @see #onDetachedFromWindow() */ protected void onAttachedToWindow() { - if ((mPrivateFlags & REQUEST_TRANSPARENT_REGIONS) != 0) { + if ((mPrivateFlags & PFLAG_REQUEST_TRANSPARENT_REGIONS) != 0) { mParent.requestTransparentRegion(this); } - if ((mPrivateFlags & AWAKEN_SCROLL_BARS_ON_ATTACH) != 0) { + if ((mPrivateFlags & PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH) != 0) { initialAwakenScrollBars(); - mPrivateFlags &= ~AWAKEN_SCROLL_BARS_ON_ATTACH; + mPrivateFlags &= ~PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH; } jumpDrawablesToCurrentState(); - // Order is important here: LayoutDirection MUST be resolved before Padding - // and TextDirection - resolveLayoutDirection(); - resolvePadding(); - resolveTextDirection(); - resolveTextAlignment(); + resolveRtlProperties(); clearAccessibilityFocus(); if (isFocused()) { @@ -11215,6 +11336,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } + void resolveRtlProperties() { + // Order is important here: LayoutDirection MUST be resolved first... + resolveLayoutDirection(); + // ... then we can resolve the others properties depending on the resolved LayoutDirection. + resolvePadding(); + resolveLayoutParams(); + resolveTextDirection(); + resolveTextAlignment(); + } + /** * @see #onScreenStateChanged(int) */ @@ -11248,7 +11379,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void resolveLayoutDirection() { // Clear any previous layout direction resolution - mPrivateFlags2 &= ~LAYOUT_DIRECTION_RESOLVED_MASK; + mPrivateFlags2 &= ~PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK; if (hasRtlSupport()) { // Set resolved depending on layout direction @@ -11265,15 +11396,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (!viewGroup.canResolveLayoutDirection()) return; if (viewGroup.getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL) { - mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED_RTL; + mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL; } break; case LAYOUT_DIRECTION_RTL: - mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED_RTL; + mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL; break; case LAYOUT_DIRECTION_LOCALE: if(isLayoutDirectionRtl(Locale.getDefault())) { - mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED_RTL; + mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL; } break; default: @@ -11282,7 +11413,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } // Set to resolved - mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED; + mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED; onResolvedLayoutDirectionChanged(); } @@ -11295,56 +11426,66 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * Return if padding has been resolved + */ + boolean isPaddingResolved() { + return (mPrivateFlags2 & PFLAG2_PADDING_RESOLVED) != 0; + } + + /** * Resolve padding depending on layout direction. */ public void resolvePadding() { - // If the user specified the absolute padding (either with android:padding or - // android:paddingLeft/Top/Right/Bottom), use this padding, otherwise - // use the default padding or the padding from the background drawable - // (stored at this point in mPadding*) - int resolvedLayoutDirection = getResolvedLayoutDirection(); - switch (resolvedLayoutDirection) { - case LAYOUT_DIRECTION_RTL: - // Start user padding override Right user padding. Otherwise, if Right user - // padding is not defined, use the default Right padding. If Right user padding - // is defined, just use it. - if (mUserPaddingStart != UNDEFINED_PADDING) { - mUserPaddingRight = mUserPaddingStart; - } - if (mUserPaddingRight == UNDEFINED_PADDING) { - mUserPaddingRight = mPaddingRight; - } - if (mUserPaddingEnd != UNDEFINED_PADDING) { - mUserPaddingLeft = mUserPaddingEnd; - } - if (mUserPaddingLeft == UNDEFINED_PADDING) { - mUserPaddingLeft = mPaddingLeft; - } - break; - case LAYOUT_DIRECTION_LTR: - default: - // Start user padding override Left user padding. Otherwise, if Left user - // padding is not defined, use the default left padding. If Left user padding - // is defined, just use it. - if (mUserPaddingStart != UNDEFINED_PADDING) { - mUserPaddingLeft = mUserPaddingStart; - } - if (mUserPaddingLeft == UNDEFINED_PADDING) { - mUserPaddingLeft = mPaddingLeft; - } - if (mUserPaddingEnd != UNDEFINED_PADDING) { - mUserPaddingRight = mUserPaddingEnd; - } - if (mUserPaddingRight == UNDEFINED_PADDING) { - mUserPaddingRight = mPaddingRight; - } - } + final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion; + if (targetSdkVersion < JELLY_BEAN_MR1 || !hasRtlSupport()) { + // Pre Jelly Bean MR1 case (compatibility mode) OR no RTL support case: + // left / right padding are used if defined. If they are not defined and start / end + // padding are defined (e.g. in Frameworks resources), then we use start / end and + // resolve them as left / right (layout direction is not taken into account). + if (!mUserPaddingLeftDefined && mUserPaddingStart != UNDEFINED_PADDING) { + mUserPaddingLeft = mUserPaddingStart; + } + if (!mUserPaddingRightDefined && mUserPaddingEnd != UNDEFINED_PADDING) { + mUserPaddingRight = mUserPaddingEnd; + } - mUserPaddingBottom = (mUserPaddingBottom >= 0) ? mUserPaddingBottom : mPaddingBottom; + mUserPaddingBottom = (mUserPaddingBottom >= 0) ? mUserPaddingBottom : mPaddingBottom; - internalSetPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight, mUserPaddingBottom); - onPaddingChanged(resolvedLayoutDirection); - mPrivateFlags2 |= PADDING_RESOLVED; + internalSetPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight, + mUserPaddingBottom); + } else { + // Post Jelly Bean MR1 case: we need to take the resolved layout direction into account. + // If start / end padding are defined, they will be resolved (hence overriding) to + // left / right or right / left depending on the resolved layout direction. + // If start / end padding are not defined, use the left / right ones. + int resolvedLayoutDirection = getResolvedLayoutDirection(); + switch (resolvedLayoutDirection) { + case LAYOUT_DIRECTION_RTL: + if (mUserPaddingStart != UNDEFINED_PADDING) { + mUserPaddingRight = mUserPaddingStart; + } + if (mUserPaddingEnd != UNDEFINED_PADDING) { + mUserPaddingLeft = mUserPaddingEnd; + } + break; + case LAYOUT_DIRECTION_LTR: + default: + if (mUserPaddingStart != UNDEFINED_PADDING) { + mUserPaddingLeft = mUserPaddingStart; + } + if (mUserPaddingEnd != UNDEFINED_PADDING) { + mUserPaddingRight = mUserPaddingEnd; + } + } + + mUserPaddingBottom = (mUserPaddingBottom >= 0) ? mUserPaddingBottom : mPaddingBottom; + + internalSetPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight, + mUserPaddingBottom); + onPaddingChanged(resolvedLayoutDirection); + } + + mPrivateFlags2 |= PFLAG2_PADDING_RESOLVED; } /** @@ -11380,7 +11521,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void resetResolvedLayoutDirection() { // Reset the current resolved bits - mPrivateFlags2 &= ~LAYOUT_DIRECTION_RESOLVED_MASK; + mPrivateFlags2 &= ~PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK; onResolvedLayoutDirectionReset(); // Reset also the text direction resetResolvedTextDirection(); @@ -11414,7 +11555,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @see #onAttachedToWindow() */ protected void onDetachedFromWindow() { - mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT; + mPrivateFlags &= ~PFLAG_CANCEL_NEXT_UP_EVENT; removeUnsetPressCallback(); removeLongPressCallback(); @@ -11440,7 +11581,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, resetResolvedLayoutDirection(); resetResolvedTextAlignment(); resetAccessibilityStateChanged(); - mPrivateFlags2 &= ~PADDING_RESOLVED; + mPrivateFlags2 &= ~PFLAG2_PADDING_RESOLVED; } /** @@ -11482,6 +11623,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * Gets the logical display to which the view's window has been attached. + * + * @return The logical display, or null if the view is not currently attached to a window. + */ + public Display getDisplay() { + return mAttachInfo != null ? mAttachInfo.mDisplay : null; + } + + /** * Retrieve private session object this view hierarchy is using to * communicate with the window manager. * @return the session object to communicate with the window manager @@ -11499,14 +11649,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mAttachInfo = info; mWindowAttachCount++; // We will need to evaluate the drawable state at least once. - mPrivateFlags |= DRAWABLE_STATE_DIRTY; + mPrivateFlags |= PFLAG_DRAWABLE_STATE_DIRTY; if (mFloatingTreeObserver != null) { info.mTreeObserver.merge(mFloatingTreeObserver); mFloatingTreeObserver = null; } - if ((mPrivateFlags&SCROLL_CONTAINER) != 0) { + if ((mPrivateFlags&PFLAG_SCROLL_CONTAINER) != 0) { mAttachInfo.mScrollContainers.add(this); - mPrivateFlags |= SCROLL_CONTAINER_ADDED; + mPrivateFlags |= PFLAG_SCROLL_CONTAINER_ADDED; } performCollectViewAttributes(mAttachInfo, visibility); onAttachedToWindow(); @@ -11528,7 +11678,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (vis != GONE) { onWindowVisibilityChanged(vis); } - if ((mPrivateFlags&DRAWABLE_STATE_DIRTY) != 0) { + if ((mPrivateFlags&PFLAG_DRAWABLE_STATE_DIRTY) != 0) { // If nobody has evaluated the drawable state yet, then do it now. refreshDrawableState(); } @@ -11558,9 +11708,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } - if ((mPrivateFlags & SCROLL_CONTAINER_ADDED) != 0) { + if ((mPrivateFlags & PFLAG_SCROLL_CONTAINER_ADDED) != 0) { mAttachInfo.mScrollContainers.remove(this); - mPrivateFlags &= ~SCROLL_CONTAINER_ADDED; + mPrivateFlags &= ~PFLAG_SCROLL_CONTAINER_ADDED; } mAttachInfo = null; @@ -11592,9 +11742,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) { if (mID != NO_ID && (mViewFlags & SAVE_DISABLED_MASK) == 0) { - mPrivateFlags &= ~SAVE_STATE_CALLED; + mPrivateFlags &= ~PFLAG_SAVE_STATE_CALLED; Parcelable state = onSaveInstanceState(); - if ((mPrivateFlags & SAVE_STATE_CALLED) == 0) { + if ((mPrivateFlags & PFLAG_SAVE_STATE_CALLED) == 0) { throw new IllegalStateException( "Derived class did not call super.onSaveInstanceState()"); } @@ -11628,7 +11778,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @see #setSaveEnabled(boolean) */ protected Parcelable onSaveInstanceState() { - mPrivateFlags |= SAVE_STATE_CALLED; + mPrivateFlags |= PFLAG_SAVE_STATE_CALLED; return BaseSavedState.EMPTY_STATE; } @@ -11663,9 +11813,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (state != null) { // Log.i("View", "Restoreing #" + Integer.toHexString(mID) // + ": " + state); - mPrivateFlags &= ~SAVE_STATE_CALLED; + mPrivateFlags &= ~PFLAG_SAVE_STATE_CALLED; onRestoreInstanceState(state); - if ((mPrivateFlags & SAVE_STATE_CALLED) == 0) { + if ((mPrivateFlags & PFLAG_SAVE_STATE_CALLED) == 0) { throw new IllegalStateException( "Derived class did not call super.onRestoreInstanceState()"); } @@ -11686,7 +11836,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @see #dispatchRestoreInstanceState(android.util.SparseArray) */ protected void onRestoreInstanceState(Parcelable state) { - mPrivateFlags |= SAVE_STATE_CALLED; + mPrivateFlags |= PFLAG_SAVE_STATE_CALLED; if (state != BaseSavedState.EMPTY_STATE && state != null) { throw new IllegalArgumentException("Wrong state class, expecting View State but " + "received " + state.getClass().toString() + " instead. This usually happens " @@ -11901,7 +12051,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return null; } - if ((mPrivateFlags & DRAWING_CACHE_VALID) == 0 || mHardwareLayer == null) { + if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0 || mHardwareLayer == null) { if (mHardwareLayer == null) { mHardwareLayer = mAttachInfo.mHardwareRenderer.createHardwareLayer( width, height, isOpaque()); @@ -12031,10 +12181,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @SuppressWarnings({"UnusedDeclaration"}) public void outputDirtyFlags(String indent, boolean clear, int clearMask) { - Log.d("View", indent + this + " DIRTY(" + (mPrivateFlags & View.DIRTY_MASK) + - ") DRAWN(" + (mPrivateFlags & DRAWN) + ")" + " CACHE_VALID(" + - (mPrivateFlags & View.DRAWING_CACHE_VALID) + - ") INVALIDATED(" + (mPrivateFlags & INVALIDATED) + ")"); + Log.d("View", indent + this + " DIRTY(" + (mPrivateFlags & View.PFLAG_DIRTY_MASK) + + ") DRAWN(" + (mPrivateFlags & PFLAG_DRAWN) + ")" + " CACHE_VALID(" + + (mPrivateFlags & View.PFLAG_DRAWING_CACHE_VALID) + + ") INVALIDATED(" + (mPrivateFlags & PFLAG_INVALIDATED) + ")"); if (clear) { mPrivateFlags &= clearMask; } @@ -12098,15 +12248,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return null; } - if (((mPrivateFlags & DRAWING_CACHE_VALID) == 0 || + if (((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0 || displayList == null || !displayList.isValid() || (!isLayer && mRecreateDisplayList))) { // Don't need to recreate the display list, just need to tell our // children to restore/recreate theirs if (displayList != null && displayList.isValid() && !isLayer && !mRecreateDisplayList) { - mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID; - mPrivateFlags &= ~DIRTY_MASK; + mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID; + mPrivateFlags &= ~PFLAG_DIRTY_MASK; dispatchGetDisplayList(); return displayList; @@ -12161,12 +12311,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, canvas.translate(-mScrollX, -mScrollY); if (!isLayer) { - mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID; - mPrivateFlags &= ~DIRTY_MASK; + mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID; + mPrivateFlags &= ~PFLAG_DIRTY_MASK; } // Fast path for layouts with no backgrounds - if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) { + if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) { dispatchDraw(canvas); } else { draw(canvas); @@ -12184,8 +12334,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } } else if (!isLayer) { - mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID; - mPrivateFlags &= ~DIRTY_MASK; + mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID; + mPrivateFlags &= ~PFLAG_DIRTY_MASK; } return displayList; @@ -12307,7 +12457,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, public void setDrawingCacheBackgroundColor(int color) { if (color != mDrawingCacheBackgroundColor) { mDrawingCacheBackgroundColor = color; - mPrivateFlags &= ~DRAWING_CACHE_VALID; + mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID; } } @@ -12353,7 +12503,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @see #destroyDrawingCache() */ public void buildDrawingCache(boolean autoScale) { - if ((mPrivateFlags & DRAWING_CACHE_VALID) == 0 || (autoScale ? + if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0 || (autoScale ? mDrawingCache == null : mUnscaledDrawingCache == null)) { mCachingFailed = false; @@ -12469,15 +12619,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, canvas.translate(-mScrollX, -mScrollY); - mPrivateFlags |= DRAWN; + mPrivateFlags |= PFLAG_DRAWN; if (mAttachInfo == null || !mAttachInfo.mHardwareAccelerated || mLayerType != LAYER_TYPE_NONE) { - mPrivateFlags |= DRAWING_CACHE_VALID; + mPrivateFlags |= PFLAG_DRAWING_CACHE_VALID; } // Fast path for layouts with no backgrounds - if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) { - mPrivateFlags &= ~DIRTY_MASK; + if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) { + mPrivateFlags &= ~PFLAG_DIRTY_MASK; dispatchDraw(canvas); } else { draw(canvas); @@ -12545,10 +12695,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // Temporarily remove the dirty mask int flags = mPrivateFlags; - mPrivateFlags &= ~DIRTY_MASK; + mPrivateFlags &= ~PFLAG_DIRTY_MASK; // Fast path for layouts with no backgrounds - if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) { + if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) { dispatchDraw(canvas); } else { draw(canvas); @@ -12738,7 +12888,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } else if ((flags & ViewGroup.FLAG_INVALIDATE_REQUIRED) == 0) { // The child need to draw an animation, potentially offscreen, so // make sure we do not cancel invalidate requests - parent.mPrivateFlags |= DRAW_ANIMATION; + parent.mPrivateFlags |= PFLAG_DRAW_ANIMATION; parent.invalidate(mLeft, mTop, mRight, mBottom); } } else { @@ -12751,7 +12901,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // The child need to draw an animation, potentially offscreen, so // make sure we do not cancel invalidate requests - parent.mPrivateFlags |= DRAW_ANIMATION; + parent.mPrivateFlags |= PFLAG_DRAW_ANIMATION; final int left = mLeft + (int) region.left; final int top = mTop + (int) region.top; @@ -12813,7 +12963,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mTransformationInfo.matrix3D = new Matrix(); } displayList.setCameraDistance(mTransformationInfo.mCamera.getLocationZ()); - if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == PIVOT_EXPLICITLY_SET) { + if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == PFLAG_PIVOT_EXPLICITLY_SET) { displayList.setPivotX(getPivotX()); displayList.setPivotY(getPivotY()); } @@ -12861,15 +13011,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, more = drawAnimation(parent, drawingTime, a, scalingRequired); concatMatrix = a.willChangeTransformationMatrix(); if (concatMatrix) { - mPrivateFlags3 |= VIEW_IS_ANIMATING_TRANSFORM; + mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_TRANSFORM; } transformToApply = parent.mChildTransformation; } else { - if ((mPrivateFlags3 & VIEW_IS_ANIMATING_TRANSFORM) == VIEW_IS_ANIMATING_TRANSFORM && + if ((mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_TRANSFORM) == PFLAG3_VIEW_IS_ANIMATING_TRANSFORM && mDisplayList != null) { // No longer animating: clear out old animation matrix mDisplayList.setAnimationMatrix(null); - mPrivateFlags3 &= ~VIEW_IS_ANIMATING_TRANSFORM; + mPrivateFlags3 &= ~PFLAG3_VIEW_IS_ANIMATING_TRANSFORM; } if (!useDisplayListProperties && (flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) { @@ -12888,21 +13038,21 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // Sets the flag as early as possible to allow draw() implementations // to call invalidate() successfully when doing animations - mPrivateFlags |= DRAWN; + mPrivateFlags |= PFLAG_DRAWN; if (!concatMatrix && (flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) == 0 && canvas.quickReject(mLeft, mTop, mRight, mBottom, Canvas.EdgeType.BW) && - (mPrivateFlags & DRAW_ANIMATION) == 0) { - mPrivateFlags2 |= VIEW_QUICK_REJECTED; + (mPrivateFlags & PFLAG_DRAW_ANIMATION) == 0) { + mPrivateFlags2 |= PFLAG2_VIEW_QUICK_REJECTED; return more; } - mPrivateFlags2 &= ~VIEW_QUICK_REJECTED; + mPrivateFlags2 &= ~PFLAG2_VIEW_QUICK_REJECTED; if (hardwareAccelerated) { // Clear INVALIDATED flag to allow invalidation to occur during rendering, but // retain the flag's value temporarily in the mRecreateDisplayList flag - mRecreateDisplayList = (mPrivateFlags & INVALIDATED) == INVALIDATED; - mPrivateFlags &= ~INVALIDATED; + mRecreateDisplayList = (mPrivateFlags & PFLAG_INVALIDATED) == PFLAG_INVALIDATED; + mPrivateFlags &= ~PFLAG_INVALIDATED; } DisplayList displayList = null; @@ -12986,7 +13136,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, float alpha = useDisplayListProperties ? 1 : getAlpha(); if (transformToApply != null || alpha < 1 || !hasIdentityMatrix() || - (mPrivateFlags3 & VIEW_IS_ANIMATING_ALPHA) == VIEW_IS_ANIMATING_ALPHA) { + (mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_ALPHA) == PFLAG3_VIEW_IS_ANIMATING_ALPHA) { if (transformToApply != null || !childHasIdentityMatrix) { int transX = 0; int transY = 0; @@ -13026,11 +13176,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // Deal with alpha if it is or used to be <1 if (alpha < 1 || - (mPrivateFlags3 & VIEW_IS_ANIMATING_ALPHA) == VIEW_IS_ANIMATING_ALPHA) { + (mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_ALPHA) == PFLAG3_VIEW_IS_ANIMATING_ALPHA) { if (alpha < 1) { - mPrivateFlags3 |= VIEW_IS_ANIMATING_ALPHA; + mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_ALPHA; } else { - mPrivateFlags3 &= ~VIEW_IS_ANIMATING_ALPHA; + mPrivateFlags3 &= ~PFLAG3_VIEW_IS_ANIMATING_ALPHA; } parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION; if (hasNoCache) { @@ -13051,13 +13201,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } else { // Alpha is handled by the child directly, clobber the layer's alpha - mPrivateFlags |= ALPHA_SET; + mPrivateFlags |= PFLAG_ALPHA_SET; } } } - } else if ((mPrivateFlags & ALPHA_SET) == ALPHA_SET) { + } else if ((mPrivateFlags & PFLAG_ALPHA_SET) == PFLAG_ALPHA_SET) { onSetAlpha(255); - mPrivateFlags &= ~ALPHA_SET; + mPrivateFlags &= ~PFLAG_ALPHA_SET; } if ((flags & ViewGroup.FLAG_CLIP_CHILDREN) == ViewGroup.FLAG_CLIP_CHILDREN && @@ -13104,19 +13254,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (!layerRendered) { if (!hasDisplayList) { // Fast path for layouts with no backgrounds - if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) { - mPrivateFlags &= ~DIRTY_MASK; + if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) { + mPrivateFlags &= ~PFLAG_DIRTY_MASK; dispatchDraw(canvas); } else { draw(canvas); } } else { - mPrivateFlags &= ~DIRTY_MASK; + mPrivateFlags &= ~PFLAG_DIRTY_MASK; ((HardwareCanvas) canvas).drawDisplayList(displayList, null, flags); } } } else if (cache != null) { - mPrivateFlags &= ~DIRTY_MASK; + mPrivateFlags &= ~PFLAG_DIRTY_MASK; Paint cachePaint; if (layerType == LAYER_TYPE_NONE) { @@ -13156,7 +13306,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // display lists to render, force an invalidate to allow the animation to // continue drawing another frame parent.invalidate(true); - if (a.hasAlpha() && (mPrivateFlags & ALPHA_SET) == ALPHA_SET) { + if (a.hasAlpha() && (mPrivateFlags & PFLAG_ALPHA_SET) == PFLAG_ALPHA_SET) { // alpha animations should cause the child to recreate its display list invalidate(true); } @@ -13178,9 +13328,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void draw(Canvas canvas) { final int privateFlags = mPrivateFlags; - final boolean dirtyOpaque = (privateFlags & DIRTY_MASK) == DIRTY_OPAQUE && + final boolean dirtyOpaque = (privateFlags & PFLAG_DIRTY_MASK) == PFLAG_DIRTY_OPAQUE && (mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState); - mPrivateFlags = (privateFlags & ~DIRTY_MASK) | DRAWN; + mPrivateFlags = (privateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN; /* * Draw traversal performs several drawing steps which must be executed @@ -13435,12 +13585,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, String output = ""; int numFlags = 0; - if ((privateFlags & WANTS_FOCUS) == WANTS_FOCUS) { + if ((privateFlags & PFLAG_WANTS_FOCUS) == PFLAG_WANTS_FOCUS) { output += "WANTS_FOCUS"; numFlags++; } - if ((privateFlags & FOCUSED) == FOCUSED) { + if ((privateFlags & PFLAG_FOCUSED) == PFLAG_FOCUSED) { if (numFlags > 0) { output += " "; } @@ -13448,7 +13598,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, numFlags++; } - if ((privateFlags & SELECTED) == SELECTED) { + if ((privateFlags & PFLAG_SELECTED) == PFLAG_SELECTED) { if (numFlags > 0) { output += " "; } @@ -13456,7 +13606,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, numFlags++; } - if ((privateFlags & IS_ROOT_NAMESPACE) == IS_ROOT_NAMESPACE) { + if ((privateFlags & PFLAG_IS_ROOT_NAMESPACE) == PFLAG_IS_ROOT_NAMESPACE) { if (numFlags > 0) { output += " "; } @@ -13464,7 +13614,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, numFlags++; } - if ((privateFlags & HAS_BOUNDS) == HAS_BOUNDS) { + if ((privateFlags & PFLAG_HAS_BOUNDS) == PFLAG_HAS_BOUNDS) { if (numFlags > 0) { output += " "; } @@ -13472,7 +13622,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, numFlags++; } - if ((privateFlags & DRAWN) == DRAWN) { + if ((privateFlags & PFLAG_DRAWN) == PFLAG_DRAWN) { if (numFlags > 0) { output += " "; } @@ -13489,7 +13639,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return true if the layout will be forced during next layout pass */ public boolean isLayoutRequested() { - return (mPrivateFlags & FORCE_LAYOUT) == FORCE_LAYOUT; + return (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT; } /** @@ -13519,9 +13669,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, int oldB = mBottom; int oldR = mRight; boolean changed = setFrame(l, t, r, b); - if (changed || (mPrivateFlags & LAYOUT_REQUIRED) == LAYOUT_REQUIRED) { + if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) { onLayout(changed, l, t, r, b); - mPrivateFlags &= ~LAYOUT_REQUIRED; + mPrivateFlags &= ~PFLAG_LAYOUT_REQUIRED; ListenerInfo li = mListenerInfo; if (li != null && li.mOnLayoutChangeListeners != null) { @@ -13533,7 +13683,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } } - mPrivateFlags &= ~FORCE_LAYOUT; + mPrivateFlags &= ~PFLAG_FORCE_LAYOUT; } /** @@ -13577,7 +13727,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, changed = true; // Remember our drawn bit - int drawn = mPrivateFlags & DRAWN; + int drawn = mPrivateFlags & PFLAG_DRAWN; int oldWidth = mRight - mLeft; int oldHeight = mBottom - mTop; @@ -13596,11 +13746,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mDisplayList.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom); } - mPrivateFlags |= HAS_BOUNDS; + mPrivateFlags |= PFLAG_HAS_BOUNDS; if (sizeChanged) { - if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) { + if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) { // A change in dimension means an auto-centered pivot point changes, too if (mTransformationInfo != null) { mTransformationInfo.mMatrixDirty = true; @@ -13615,7 +13765,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // This is because someone may have invalidated this view // before this call to setFrame came in, thereby clearing // the DRAWN bit. - mPrivateFlags |= DRAWN; + mPrivateFlags |= PFLAG_DRAWN; invalidate(sizeChanged); // parent display list may need to be recreated based on a change in the bounds // of any child @@ -13793,7 +13943,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @see #getDrawableState */ public void refreshDrawableState() { - mPrivateFlags |= DRAWABLE_STATE_DIRTY; + mPrivateFlags |= PFLAG_DRAWABLE_STATE_DIRTY; drawableStateChanged(); ViewParent parent = mParent; @@ -13813,11 +13963,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @see #onCreateDrawableState(int) */ public final int[] getDrawableState() { - if ((mDrawableState != null) && ((mPrivateFlags & DRAWABLE_STATE_DIRTY) == 0)) { + if ((mDrawableState != null) && ((mPrivateFlags & PFLAG_DRAWABLE_STATE_DIRTY) == 0)) { return mDrawableState; } else { mDrawableState = onCreateDrawableState(0); - mPrivateFlags &= ~DRAWABLE_STATE_DIRTY; + mPrivateFlags &= ~PFLAG_DRAWABLE_STATE_DIRTY; return mDrawableState; } } @@ -13848,12 +13998,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, int privateFlags = mPrivateFlags; int viewStateIndex = 0; - if ((privateFlags & PRESSED) != 0) viewStateIndex |= VIEW_STATE_PRESSED; + if ((privateFlags & PFLAG_PRESSED) != 0) viewStateIndex |= VIEW_STATE_PRESSED; if ((mViewFlags & ENABLED_MASK) == ENABLED) viewStateIndex |= VIEW_STATE_ENABLED; if (isFocused()) viewStateIndex |= VIEW_STATE_FOCUSED; - if ((privateFlags & SELECTED) != 0) viewStateIndex |= VIEW_STATE_SELECTED; + if ((privateFlags & PFLAG_SELECTED) != 0) viewStateIndex |= VIEW_STATE_SELECTED; if (hasWindowFocus()) viewStateIndex |= VIEW_STATE_WINDOW_FOCUSED; - if ((privateFlags & ACTIVATED) != 0) viewStateIndex |= VIEW_STATE_ACTIVATED; + if ((privateFlags & PFLAG_ACTIVATED) != 0) viewStateIndex |= VIEW_STATE_ACTIVATED; if (mAttachInfo != null && mAttachInfo.mHardwareAccelerationRequested && HardwareRenderer.isAvailable()) { // This is set if HW acceleration is requested, even if the current @@ -13861,11 +14011,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // windows to better match their app. viewStateIndex |= VIEW_STATE_ACCELERATED; } - if ((privateFlags & HOVERED) != 0) viewStateIndex |= VIEW_STATE_HOVERED; + if ((privateFlags & PFLAG_HOVERED) != 0) viewStateIndex |= VIEW_STATE_HOVERED; final int privateFlags2 = mPrivateFlags2; - if ((privateFlags2 & DRAG_CAN_ACCEPT) != 0) viewStateIndex |= VIEW_STATE_DRAG_CAN_ACCEPT; - if ((privateFlags2 & DRAG_HOVERED) != 0) viewStateIndex |= VIEW_STATE_DRAG_HOVERED; + if ((privateFlags2 & PFLAG2_DRAG_CAN_ACCEPT) != 0) viewStateIndex |= VIEW_STATE_DRAG_CAN_ACCEPT; + if ((privateFlags2 & PFLAG2_DRAG_HOVERED) != 0) viewStateIndex |= VIEW_STATE_DRAG_HOVERED; drawableState = VIEW_STATE_SETS[viewStateIndex]; @@ -13873,10 +14023,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (false) { Log.i("View", "drawableStateIndex=" + viewStateIndex); Log.i("View", toString() - + " pressed=" + ((privateFlags & PRESSED) != 0) + + " pressed=" + ((privateFlags & PFLAG_PRESSED) != 0) + " en=" + ((mViewFlags & ENABLED_MASK) == ENABLED) + " fo=" + hasFocus() - + " sl=" + ((privateFlags & SELECTED) != 0) + + " sl=" + ((privateFlags & PFLAG_SELECTED) != 0) + " wf=" + hasWindowFocus() + ": " + Arrays.toString(drawableState)); } @@ -14016,6 +14166,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } background.setLayoutDirection(getResolvedLayoutDirection()); if (background.getPadding(padding)) { + // Reset padding resolution + mPrivateFlags2 &= ~PFLAG2_PADDING_RESOLVED; switch (background.getLayoutDirection()) { case LAYOUT_DIRECTION_RTL: internalSetPadding(padding.right, padding.top, padding.left, padding.bottom); @@ -14040,23 +14192,23 @@ public class View implements Drawable.Callback, KeyEvent.Callback, background.setVisible(getVisibility() == VISIBLE, false); mBackground = background; - if ((mPrivateFlags & SKIP_DRAW) != 0) { - mPrivateFlags &= ~SKIP_DRAW; - mPrivateFlags |= ONLY_DRAWS_BACKGROUND; + if ((mPrivateFlags & PFLAG_SKIP_DRAW) != 0) { + mPrivateFlags &= ~PFLAG_SKIP_DRAW; + mPrivateFlags |= PFLAG_ONLY_DRAWS_BACKGROUND; requestLayout = true; } } else { /* Remove the background */ mBackground = null; - if ((mPrivateFlags & ONLY_DRAWS_BACKGROUND) != 0) { + if ((mPrivateFlags & PFLAG_ONLY_DRAWS_BACKGROUND) != 0) { /* * This view ONLY drew the background before and we're removing * the background, so now it won't draw anything * (hence we SKIP_DRAW) */ - mPrivateFlags &= ~ONLY_DRAWS_BACKGROUND; - mPrivateFlags |= SKIP_DRAW; + mPrivateFlags &= ~PFLAG_ONLY_DRAWS_BACKGROUND; + mPrivateFlags |= PFLAG_SKIP_DRAW; } /* @@ -14112,13 +14264,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @param bottom the bottom padding in pixels */ public void setPadding(int left, int top, int right, int bottom) { + // Reset padding resolution + mPrivateFlags2 &= ~PFLAG2_PADDING_RESOLVED; + mUserPaddingStart = UNDEFINED_PADDING; mUserPaddingEnd = UNDEFINED_PADDING; internalSetPadding(left, top, right, bottom); } - void internalSetPadding(int left, int top, int right, int bottom) { + /** + * @hide + */ + protected void internalSetPadding(int left, int top, int right, int bottom) { mUserPaddingLeft = left; mUserPaddingRight = right; mUserPaddingBottom = bottom; @@ -14193,6 +14351,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @param bottom the bottom padding in pixels */ public void setPaddingRelative(int start, int top, int end, int bottom) { + // Reset padding resolution + mPrivateFlags2 &= ~PFLAG2_PADDING_RESOLVED; + mUserPaddingStart = start; mUserPaddingEnd = end; @@ -14234,6 +14395,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return the left padding in pixels */ public int getPaddingLeft() { + if (!isPaddingResolved()) { + resolvePadding(); + } return mPaddingLeft; } @@ -14245,6 +14409,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return the start padding in pixels */ public int getPaddingStart() { + if (!isPaddingResolved()) { + resolvePadding(); + } return (getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL) ? mPaddingRight : mPaddingLeft; } @@ -14257,6 +14424,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return the right padding in pixels */ public int getPaddingRight() { + if (!isPaddingResolved()) { + resolvePadding(); + } return mPaddingRight; } @@ -14268,6 +14438,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return the end padding in pixels */ public int getPaddingEnd() { + if (!isPaddingResolved()) { + resolvePadding(); + } return (getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL) ? mPaddingLeft : mPaddingRight; } @@ -14310,8 +14483,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @param selected true if the view must be selected, false otherwise */ public void setSelected(boolean selected) { - if (((mPrivateFlags & SELECTED) != 0) != selected) { - mPrivateFlags = (mPrivateFlags & ~SELECTED) | (selected ? SELECTED : 0); + if (((mPrivateFlags & PFLAG_SELECTED) != 0) != selected) { + mPrivateFlags = (mPrivateFlags & ~PFLAG_SELECTED) | (selected ? PFLAG_SELECTED : 0); if (!selected) resetPressedState(); invalidate(true); refreshDrawableState(); @@ -14339,7 +14512,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @ViewDebug.ExportedProperty public boolean isSelected() { - return (mPrivateFlags & SELECTED) != 0; + return (mPrivateFlags & PFLAG_SELECTED) != 0; } /** @@ -14356,8 +14529,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @param activated true if the view must be activated, false otherwise */ public void setActivated(boolean activated) { - if (((mPrivateFlags & ACTIVATED) != 0) != activated) { - mPrivateFlags = (mPrivateFlags & ~ACTIVATED) | (activated ? ACTIVATED : 0); + if (((mPrivateFlags & PFLAG_ACTIVATED) != 0) != activated) { + mPrivateFlags = (mPrivateFlags & ~PFLAG_ACTIVATED) | (activated ? PFLAG_ACTIVATED : 0); invalidate(true); refreshDrawableState(); dispatchSetActivated(activated); @@ -14381,7 +14554,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @ViewDebug.ExportedProperty public boolean isActivated() { - return (mPrivateFlags & ACTIVATED) != 0; + return (mPrivateFlags & PFLAG_ACTIVATED) != 0; } /** @@ -14669,9 +14842,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void setIsRootNamespace(boolean isRoot) { if (isRoot) { - mPrivateFlags |= IS_ROOT_NAMESPACE; + mPrivateFlags |= PFLAG_IS_ROOT_NAMESPACE; } else { - mPrivateFlags &= ~IS_ROOT_NAMESPACE; + mPrivateFlags &= ~PFLAG_IS_ROOT_NAMESPACE; } } @@ -14681,7 +14854,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return true if the view belongs to the root namespace, false otherwise */ public boolean isRootNamespace() { - return (mPrivateFlags&IS_ROOT_NAMESPACE) != 0; + return (mPrivateFlags&PFLAG_IS_ROOT_NAMESPACE) != 0; } /** @@ -14830,7 +15003,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } Log.d(VIEW_LOG_TAG, output); - if ((mPrivateFlags & FOCUSED) != 0) { + if ((mPrivateFlags & PFLAG_FOCUSED) != 0) { output = debugIndent(depth) + " FOCUSED"; Log.d(VIEW_LOG_TAG, output); } @@ -14910,12 +15083,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * tree. */ public void requestLayout() { - mPrivateFlags |= FORCE_LAYOUT; - mPrivateFlags |= INVALIDATED; - - if (mLayoutParams != null) { - mLayoutParams.onResolveLayoutDirection(getResolvedLayoutDirection()); - } + mPrivateFlags |= PFLAG_FORCE_LAYOUT; + mPrivateFlags |= PFLAG_INVALIDATED; if (mParent != null && !mParent.isLayoutRequested()) { mParent.requestLayout(); @@ -14928,8 +15097,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * on the parent. */ public void forceLayout() { - mPrivateFlags |= FORCE_LAYOUT; - mPrivateFlags |= INVALIDATED; + mPrivateFlags |= PFLAG_FORCE_LAYOUT; + mPrivateFlags |= PFLAG_INVALIDATED; } /** @@ -14953,14 +15122,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @see #onMeasure(int, int) */ public final void measure(int widthMeasureSpec, int heightMeasureSpec) { - if ((mPrivateFlags & FORCE_LAYOUT) == FORCE_LAYOUT || + if ((mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT || widthMeasureSpec != mOldWidthMeasureSpec || heightMeasureSpec != mOldHeightMeasureSpec) { // first clears the measured dimension flag - mPrivateFlags &= ~MEASURED_DIMENSION_SET; + mPrivateFlags &= ~PFLAG_MEASURED_DIMENSION_SET; - if ((mPrivateFlags2 & PADDING_RESOLVED) == 0) { + if (!isPaddingResolved()) { resolvePadding(); } @@ -14969,13 +15138,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // flag not set, setMeasuredDimension() was not invoked, we raise // an exception to warn the developer - if ((mPrivateFlags & MEASURED_DIMENSION_SET) != MEASURED_DIMENSION_SET) { + if ((mPrivateFlags & PFLAG_MEASURED_DIMENSION_SET) != PFLAG_MEASURED_DIMENSION_SET) { throw new IllegalStateException("onMeasure() did not set the" + " measured dimension by calling" + " setMeasuredDimension()"); } - mPrivateFlags |= LAYOUT_REQUIRED; + mPrivateFlags |= PFLAG_LAYOUT_REQUIRED; } mOldWidthMeasureSpec = widthMeasureSpec; @@ -15049,7 +15218,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mMeasuredWidth = measuredWidth; mMeasuredHeight = measuredHeight; - mPrivateFlags |= MEASURED_DIMENSION_SET; + mPrivateFlags |= PFLAG_MEASURED_DIMENSION_SET; } /** @@ -15293,7 +15462,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @see #getAnimation() */ protected void onAnimationStart() { - mPrivateFlags |= ANIMATION_STARTED; + mPrivateFlags |= PFLAG_ANIMATION_STARTED; } /** @@ -15305,7 +15474,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @see #getAnimation() */ protected void onAnimationEnd() { - mPrivateFlags &= ~ANIMATION_STARTED; + mPrivateFlags &= ~PFLAG_ANIMATION_STARTED; } /** @@ -15342,14 +15511,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, final AttachInfo attachInfo = mAttachInfo; if (region != null && attachInfo != null) { final int pflags = mPrivateFlags; - if ((pflags & SKIP_DRAW) == 0) { + if ((pflags & PFLAG_SKIP_DRAW) == 0) { // The SKIP_DRAW flag IS NOT set, so this view draws. We need to // remove it from the transparent region. final int[] location = attachInfo.mTransparentLocation; getLocationInWindow(location); region.op(location[0], location[1], location[0] + mRight - mLeft, location[1] + mBottom - mTop, Region.Op.DIFFERENCE); - } else if ((pflags & ONLY_DRAWS_BACKGROUND) != 0 && mBackground != null) { + } else if ((pflags & PFLAG_ONLY_DRAWS_BACKGROUND) != 0 && mBackground != null) { // The ONLY_DRAWS_BACKGROUND flag IS set and the background drawable // exists, so we remove the background drawable's non-transparent // parts from this transparent region. @@ -15826,7 +15995,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } boolean canAcceptDrag() { - return (mPrivateFlags2 & DRAG_CAN_ACCEPT) != 0; + return (mPrivateFlags2 & PFLAG2_DRAG_CAN_ACCEPT) != 0; } /** @@ -16091,7 +16260,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @ViewDebug.IntToString(from = TEXT_DIRECTION_LOCALE, to = "LOCALE") }) public int getTextDirection() { - return (mPrivateFlags2 & TEXT_DIRECTION_MASK) >> TEXT_DIRECTION_MASK_SHIFT; + return (mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_MASK) >> PFLAG2_TEXT_DIRECTION_MASK_SHIFT; } /** @@ -16109,10 +16278,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, public void setTextDirection(int textDirection) { if (getTextDirection() != textDirection) { // Reset the current text direction and the resolved one - mPrivateFlags2 &= ~TEXT_DIRECTION_MASK; + mPrivateFlags2 &= ~PFLAG2_TEXT_DIRECTION_MASK; resetResolvedTextDirection(); // Set the new text direction - mPrivateFlags2 |= ((textDirection << TEXT_DIRECTION_MASK_SHIFT) & TEXT_DIRECTION_MASK); + mPrivateFlags2 |= ((textDirection << PFLAG2_TEXT_DIRECTION_MASK_SHIFT) & PFLAG2_TEXT_DIRECTION_MASK); // Refresh requestLayout(); invalidate(true); @@ -16137,10 +16306,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public int getResolvedTextDirection() { // The text direction will be resolved only if needed - if ((mPrivateFlags2 & TEXT_DIRECTION_RESOLVED) != TEXT_DIRECTION_RESOLVED) { + if ((mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_RESOLVED) != PFLAG2_TEXT_DIRECTION_RESOLVED) { resolveTextDirection(); } - return (mPrivateFlags2 & TEXT_DIRECTION_RESOLVED_MASK) >> TEXT_DIRECTION_RESOLVED_MASK_SHIFT; + return (mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_RESOLVED_MASK) >> PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT; } /** @@ -16149,7 +16318,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void resolveTextDirection() { // Reset any previous text direction resolution - mPrivateFlags2 &= ~(TEXT_DIRECTION_RESOLVED | TEXT_DIRECTION_RESOLVED_MASK); + mPrivateFlags2 &= ~(PFLAG2_TEXT_DIRECTION_RESOLVED | PFLAG2_TEXT_DIRECTION_RESOLVED_MASK); if (hasRtlSupport()) { // Set resolved text direction flag depending on text direction flag @@ -16168,15 +16337,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, case TEXT_DIRECTION_RTL: case TEXT_DIRECTION_LOCALE: mPrivateFlags2 |= - (parentResolvedDirection << TEXT_DIRECTION_RESOLVED_MASK_SHIFT); + (parentResolvedDirection << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT); break; default: // Default resolved direction is "first strong" heuristic - mPrivateFlags2 |= TEXT_DIRECTION_RESOLVED_DEFAULT; + mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT; } } else { // We cannot do the resolution if there is no parent, so use the default one - mPrivateFlags2 |= TEXT_DIRECTION_RESOLVED_DEFAULT; + mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT; } break; case TEXT_DIRECTION_FIRST_STRONG: @@ -16185,19 +16354,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback, case TEXT_DIRECTION_RTL: case TEXT_DIRECTION_LOCALE: // Resolved direction is the same as text direction - mPrivateFlags2 |= (textDirection << TEXT_DIRECTION_RESOLVED_MASK_SHIFT); + mPrivateFlags2 |= (textDirection << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT); break; default: // Default resolved direction is "first strong" heuristic - mPrivateFlags2 |= TEXT_DIRECTION_RESOLVED_DEFAULT; + mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT; } } else { // Default resolved direction is "first strong" heuristic - mPrivateFlags2 |= TEXT_DIRECTION_RESOLVED_DEFAULT; + mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT; } // Set to resolved - mPrivateFlags2 |= TEXT_DIRECTION_RESOLVED; + mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED; onResolvedTextDirectionChanged(); } @@ -16230,7 +16399,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * reset is done. */ public void resetResolvedTextDirection() { - mPrivateFlags2 &= ~(TEXT_DIRECTION_RESOLVED | TEXT_DIRECTION_RESOLVED_MASK); + mPrivateFlags2 &= ~(PFLAG2_TEXT_DIRECTION_RESOLVED | PFLAG2_TEXT_DIRECTION_RESOLVED_MASK); onResolvedTextDirectionReset(); } @@ -16266,7 +16435,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_END, to = "VIEW_END") }) public int getTextAlignment() { - return (mPrivateFlags2 & TEXT_ALIGNMENT_MASK) >> TEXT_ALIGNMENT_MASK_SHIFT; + return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_MASK) >> PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT; } /** @@ -16287,10 +16456,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, public void setTextAlignment(int textAlignment) { if (textAlignment != getTextAlignment()) { // Reset the current and resolved text alignment - mPrivateFlags2 &= ~TEXT_ALIGNMENT_MASK; + mPrivateFlags2 &= ~PFLAG2_TEXT_ALIGNMENT_MASK; resetResolvedTextAlignment(); // Set the new text alignment - mPrivateFlags2 |= ((textAlignment << TEXT_ALIGNMENT_MASK_SHIFT) & TEXT_ALIGNMENT_MASK); + mPrivateFlags2 |= ((textAlignment << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT) & PFLAG2_TEXT_ALIGNMENT_MASK); // Refresh requestLayout(); invalidate(true); @@ -16324,10 +16493,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, }) public int getResolvedTextAlignment() { // If text alignment is not resolved, then resolve it - if ((mPrivateFlags2 & TEXT_ALIGNMENT_RESOLVED) != TEXT_ALIGNMENT_RESOLVED) { + if ((mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_RESOLVED) != PFLAG2_TEXT_ALIGNMENT_RESOLVED) { resolveTextAlignment(); } - return (mPrivateFlags2 & TEXT_ALIGNMENT_RESOLVED_MASK) >> TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT; + return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK) >> PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT; } /** @@ -16336,7 +16505,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void resolveTextAlignment() { // Reset any previous text alignment resolution - mPrivateFlags2 &= ~(TEXT_ALIGNMENT_RESOLVED | TEXT_ALIGNMENT_RESOLVED_MASK); + mPrivateFlags2 &= ~(PFLAG2_TEXT_ALIGNMENT_RESOLVED | PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK); if (hasRtlSupport()) { // Set resolved text alignment flag depending on text alignment flag @@ -16358,16 +16527,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // Resolved text alignment is the same as the parent resolved // text alignment mPrivateFlags2 |= - (parentResolvedTextAlignment << TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT); + (parentResolvedTextAlignment << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT); break; default: // Use default resolved text alignment - mPrivateFlags2 |= TEXT_ALIGNMENT_RESOLVED_DEFAULT; + mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT; } } else { // We cannot do the resolution if there is no parent so use the default - mPrivateFlags2 |= TEXT_ALIGNMENT_RESOLVED_DEFAULT; + mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT; } break; case TEXT_ALIGNMENT_GRAVITY: @@ -16377,19 +16546,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback, case TEXT_ALIGNMENT_VIEW_START: case TEXT_ALIGNMENT_VIEW_END: // Resolved text alignment is the same as text alignment - mPrivateFlags2 |= (textAlignment << TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT); + mPrivateFlags2 |= (textAlignment << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT); break; default: // Use default resolved text alignment - mPrivateFlags2 |= TEXT_ALIGNMENT_RESOLVED_DEFAULT; + mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT; } } else { // Use default resolved text alignment - mPrivateFlags2 |= TEXT_ALIGNMENT_RESOLVED_DEFAULT; + mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT; } // Set the resolved - mPrivateFlags2 |= TEXT_ALIGNMENT_RESOLVED; + mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED; onResolvedTextAlignmentChanged(); } @@ -16423,7 +16592,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void resetResolvedTextAlignment() { // Reset any previous text alignment resolution - mPrivateFlags2 &= ~(TEXT_ALIGNMENT_RESOLVED | TEXT_ALIGNMENT_RESOLVED_MASK); + mPrivateFlags2 &= ~(PFLAG2_TEXT_ALIGNMENT_RESOLVED | PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK); onResolvedTextAlignmentReset(); } @@ -16753,7 +16922,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private final class CheckForTap implements Runnable { public void run() { - mPrivateFlags &= ~PREPRESSED; + mPrivateFlags &= ~PFLAG_PREPRESSED; setPressed(true); checkForLongClick(ViewConfiguration.getTapTimeout()); } @@ -17101,6 +17270,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, final IBinder mWindowToken; + final Display mDisplay; + final Callbacks mRootCallbacks; HardwareCanvas mHardwareCanvas; @@ -17360,11 +17531,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * @param handler the events handler the view must use */ - AttachInfo(IWindowSession session, IWindow window, + AttachInfo(IWindowSession session, IWindow window, Display display, ViewRootImpl viewRootImpl, Handler handler, Callbacks effectPlayer) { mSession = session; mWindow = window; mWindowToken = window.asBinder(); + mDisplay = display; mViewRootImpl = viewRootImpl; mHandler = handler; mRootCallbacks = effectPlayer; diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java index 3082976..499075e 100644 --- a/core/java/android/view/ViewConfiguration.java +++ b/core/java/android/view/ViewConfiguration.java @@ -279,7 +279,8 @@ public class ViewConfiguration { mWindowTouchSlop = (int) (sizeAndDensity * WINDOW_TOUCH_SLOP + 0.5f); // Size of the screen in bytes, in ARGB_8888 format - final Display display = WindowManagerImpl.getDefault().getDefaultDisplay(); + final WindowManager win = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE); + final Display display = win.getDefaultDisplay(); final Point size = new Point(); display.getRealSize(size); mMaximumDrawingCacheSize = 4 * size.x * size.y; @@ -288,7 +289,7 @@ public class ViewConfiguration { mOverflingDistance = (int) (sizeAndDensity * OVERFLING_DISTANCE + 0.5f); if (!sHasPermanentMenuKeySet) { - IWindowManager wm = WindowManagerImpl.getWindowManagerService(); + IWindowManager wm = WindowManagerGlobal.getWindowManagerService(); try { sHasPermanentMenuKey = !wm.hasSystemNavBar() && !wm.hasNavigationBar(); sHasPermanentMenuKeySet = true; diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java index dae9265..1286eb9 100644 --- a/core/java/android/view/ViewDebug.java +++ b/core/java/android/view/ViewDebug.java @@ -497,8 +497,8 @@ public class ViewDebug { throws IOException { long durationMeasure = - (root || (view.mPrivateFlags & View.MEASURED_DIMENSION_SET) != 0) ? profileViewOperation( - view, new ViewOperation<Void>() { + (root || (view.mPrivateFlags & View.PFLAG_MEASURED_DIMENSION_SET) != 0) + ? profileViewOperation(view, new ViewOperation<Void>() { public Void[] pre() { forceLayout(view); return null; @@ -524,8 +524,8 @@ public class ViewDebug { }) : 0; long durationLayout = - (root || (view.mPrivateFlags & View.LAYOUT_REQUIRED) != 0) ? profileViewOperation( - view, new ViewOperation<Void>() { + (root || (view.mPrivateFlags & View.PFLAG_LAYOUT_REQUIRED) != 0) + ? profileViewOperation(view, new ViewOperation<Void>() { public Void[] pre() { return null; } @@ -538,9 +538,8 @@ public class ViewDebug { } }) : 0; long durationDraw = - (root || !view.willNotDraw() || (view.mPrivateFlags & View.DRAWN) != 0) ? profileViewOperation( - view, - new ViewOperation<Object>() { + (root || !view.willNotDraw() || (view.mPrivateFlags & View.PFLAG_DRAWN) != 0) + ? profileViewOperation(view, new ViewOperation<Object>() { public Object[] pre() { final DisplayMetrics metrics = (view != null && view.getResources() != null) ? @@ -651,7 +650,7 @@ public class ViewDebug { final boolean localVisible = view.getVisibility() == View.VISIBLE && visible; - if ((view.mPrivateFlags & View.SKIP_DRAW) != View.SKIP_DRAW) { + if ((view.mPrivateFlags & View.PFLAG_SKIP_DRAW) != View.PFLAG_SKIP_DRAW) { final int id = view.getId(); String name = view.getClass().getSimpleName(); if (id != View.NO_ID) { diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 1548743..3ab0e94 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -804,7 +804,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager */ @Override public boolean hasFocus() { - return (mPrivateFlags & FOCUSED) != 0 || mFocused != null; + return (mPrivateFlags & PFLAG_FOCUSED) != 0 || mFocused != null; } /* @@ -898,7 +898,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager for (int i = 0; i < childrenCount; i++) { View child = children[i]; if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE - && (child.mPrivateFlags & IS_ROOT_NAMESPACE) == 0) { + && (child.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) { child.findViewsWithText(outViews, text, flags); } } @@ -1177,7 +1177,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager final View view = mCurrentDragView; event.mAction = DragEvent.ACTION_DRAG_EXITED; view.dispatchDragEvent(event); - view.mPrivateFlags2 &= ~View.DRAG_HOVERED; + view.mPrivateFlags2 &= ~View.PFLAG2_DRAG_HOVERED; view.refreshDrawableState(); } mCurrentDragView = target; @@ -1186,7 +1186,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (target != null) { event.mAction = DragEvent.ACTION_DRAG_ENTERED; target.dispatchDragEvent(event); - target.mPrivateFlags2 |= View.DRAG_HOVERED; + target.mPrivateFlags2 |= View.PFLAG2_DRAG_HOVERED; target.refreshDrawableState(); } event.mAction = action; // restore the event's original state @@ -1220,7 +1220,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (mCurrentDragView != null) { final View view = mCurrentDragView; view.dispatchDragEvent(event); - view.mPrivateFlags2 &= ~View.DRAG_HOVERED; + view.mPrivateFlags2 &= ~View.PFLAG2_DRAG_HOVERED; view.refreshDrawableState(); mCurrentDragView = null; @@ -1281,7 +1281,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager mDragNotifiedChildren.add(child); canAccept = child.dispatchDragEvent(mCurrentDrag); if (canAccept && !child.canAcceptDrag()) { - child.mPrivateFlags2 |= View.DRAG_CAN_ACCEPT; + child.mPrivateFlags2 |= View.PFLAG2_DRAG_CAN_ACCEPT; child.refreshDrawableState(); } } @@ -1330,9 +1330,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager */ @Override public boolean dispatchKeyEventPreIme(KeyEvent event) { - if ((mPrivateFlags & (FOCUSED | HAS_BOUNDS)) == (FOCUSED | HAS_BOUNDS)) { + if ((mPrivateFlags & (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS)) + == (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS)) { return super.dispatchKeyEventPreIme(event); - } else if (mFocused != null && (mFocused.mPrivateFlags & HAS_BOUNDS) == HAS_BOUNDS) { + } else if (mFocused != null && (mFocused.mPrivateFlags & PFLAG_HAS_BOUNDS) + == PFLAG_HAS_BOUNDS) { return mFocused.dispatchKeyEventPreIme(event); } return false; @@ -1347,11 +1349,13 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager mInputEventConsistencyVerifier.onKeyEvent(event, 1); } - if ((mPrivateFlags & (FOCUSED | HAS_BOUNDS)) == (FOCUSED | HAS_BOUNDS)) { + if ((mPrivateFlags & (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS)) + == (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS)) { if (super.dispatchKeyEvent(event)) { return true; } - } else if (mFocused != null && (mFocused.mPrivateFlags & HAS_BOUNDS) == HAS_BOUNDS) { + } else if (mFocused != null && (mFocused.mPrivateFlags & PFLAG_HAS_BOUNDS) + == PFLAG_HAS_BOUNDS) { if (mFocused.dispatchKeyEvent(event)) { return true; } @@ -1368,9 +1372,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager */ @Override public boolean dispatchKeyShortcutEvent(KeyEvent event) { - if ((mPrivateFlags & (FOCUSED | HAS_BOUNDS)) == (FOCUSED | HAS_BOUNDS)) { + if ((mPrivateFlags & (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS)) + == (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS)) { return super.dispatchKeyShortcutEvent(event); - } else if (mFocused != null && (mFocused.mPrivateFlags & HAS_BOUNDS) == HAS_BOUNDS) { + } else if (mFocused != null && (mFocused.mPrivateFlags & PFLAG_HAS_BOUNDS) + == PFLAG_HAS_BOUNDS) { return mFocused.dispatchKeyShortcutEvent(event); } return false; @@ -1385,11 +1391,13 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager mInputEventConsistencyVerifier.onTrackballEvent(event, 1); } - if ((mPrivateFlags & (FOCUSED | HAS_BOUNDS)) == (FOCUSED | HAS_BOUNDS)) { + if ((mPrivateFlags & (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS)) + == (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS)) { if (super.dispatchTrackballEvent(event)) { return true; } - } else if (mFocused != null && (mFocused.mPrivateFlags & HAS_BOUNDS) == HAS_BOUNDS) { + } else if (mFocused != null && (mFocused.mPrivateFlags & PFLAG_HAS_BOUNDS) + == PFLAG_HAS_BOUNDS) { if (mFocused.dispatchTrackballEvent(event)) { return true; } @@ -1715,8 +1723,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager final float x = event.getX(); final float y = event.getY(); + final boolean customOrder = isChildrenDrawingOrderEnabled(); for (int i = childrenCount - 1; i >= 0; i--) { - final View child = children[i]; + final int childIndex = customOrder ? getChildDrawingOrder(childrenCount, i) : i; + final View child = children[childIndex]; if (!canViewReceivePointerEvents(child) || !isTransformedTouchPointInView(x, y, child, null)) { continue; @@ -1738,9 +1748,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager @Override protected boolean dispatchGenericFocusedEvent(MotionEvent event) { // Send the event to the focused child or to this view group if it has focus. - if ((mPrivateFlags & (FOCUSED | HAS_BOUNDS)) == (FOCUSED | HAS_BOUNDS)) { + if ((mPrivateFlags & (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS)) + == (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS)) { return super.dispatchGenericFocusedEvent(event); - } else if (mFocused != null && (mFocused.mPrivateFlags & HAS_BOUNDS) == HAS_BOUNDS) { + } else if (mFocused != null && (mFocused.mPrivateFlags & PFLAG_HAS_BOUNDS) + == PFLAG_HAS_BOUNDS) { return mFocused.dispatchGenericMotionEvent(event); } return false; @@ -1841,8 +1853,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager final float x = ev.getX(actionIndex); final float y = ev.getY(actionIndex); + final boolean customOrder = isChildrenDrawingOrderEnabled(); for (int i = childrenCount - 1; i >= 0; i--) { - final View child = children[i]; + final int childIndex = customOrder ? + getChildDrawingOrder(childrenCount, i) : i; + final View child = children[childIndex]; if (!canViewReceivePointerEvents(child) || !isTransformedTouchPointInView(x, y, child, null)) { continue; @@ -1860,7 +1875,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) { // Child wants to receive touch within its bounds. mLastTouchDownTime = ev.getDownTime(); - mLastTouchDownIndex = i; + mLastTouchDownIndex = childIndex; mLastTouchDownX = ev.getX(); mLastTouchDownY = ev.getY(); newTouchTarget = addTouchTarget(child, idBitsToAssign); @@ -1951,8 +1966,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * Returns true if the flag was previously set. */ private static boolean resetCancelNextUpFlag(View view) { - if ((view.mPrivateFlags & CANCEL_NEXT_UP_EVENT) != 0) { - view.mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT; + if ((view.mPrivateFlags & PFLAG_CANCEL_NEXT_UP_EVENT) != 0) { + view.mPrivateFlags &= ~PFLAG_CANCEL_NEXT_UP_EVENT; return true; } return false; @@ -2517,8 +2532,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager super.dispatchDetachedFromWindow(); } + /** + * @hide + */ @Override - void internalSetPadding(int left, int top, int right, int bottom) { + protected void internalSetPadding(int left, int top, int right, int bottom) { super.internalSetPadding(left, top, right, bottom); if ((mPaddingLeft | mPaddingTop | mPaddingRight | mPaddingBottom) != 0) { @@ -2766,7 +2784,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } // We will draw our child's animation, let's reset the flag - mPrivateFlags &= ~DRAW_ANIMATION; + mPrivateFlags &= ~PFLAG_DRAW_ANIMATION; mGroupFlags &= ~FLAG_INVALIDATE_REQUIRED; boolean more = false; @@ -2886,8 +2904,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager final View child = children[i]; if (((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) && child.hasStaticLayer()) { - child.mRecreateDisplayList = (child.mPrivateFlags & INVALIDATED) == INVALIDATED; - child.mPrivateFlags &= ~INVALIDATED; + child.mRecreateDisplayList = (child.mPrivateFlags & PFLAG_INVALIDATED) + == PFLAG_INVALIDATED; + child.mPrivateFlags &= ~PFLAG_INVALIDATED; child.getDisplayList(); child.mRecreateDisplayList = false; } @@ -3030,7 +3049,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager for (int i = 0; i < len; i++) { View v = where[i]; - if ((v.mPrivateFlags & IS_ROOT_NAMESPACE) == 0) { + if ((v.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) { v = v.findViewById(id); if (v != null) { @@ -3057,7 +3076,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager for (int i = 0; i < len; i++) { View v = where[i]; - if ((v.mPrivateFlags & IS_ROOT_NAMESPACE) == 0) { + if ((v.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) { v = v.findViewWithTag(tag); if (v != null) { @@ -3084,7 +3103,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager for (int i = 0; i < len; i++) { View v = where[i]; - if (v != childToSkip && (v.mPrivateFlags & IS_ROOT_NAMESPACE) == 0) { + if (v != childToSkip && (v.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) { v = v.findViewByPredicate(predicate); if (v != null) { @@ -3294,7 +3313,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager boolean preventRequestLayout) { child.mParent = null; addViewInner(child, index, params, preventRequestLayout); - child.mPrivateFlags = (child.mPrivateFlags & ~DIRTY_MASK) | DRAWN; + child.mPrivateFlags = (child.mPrivateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN; return true; } @@ -3304,7 +3323,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * @param child the child on which to perform the cleanup */ protected void cleanupLayoutState(View child) { - child.mPrivateFlags &= ~View.FORCE_LAYOUT; + child.mPrivateFlags &= ~View.PFLAG_FORCE_LAYOUT; } private void addViewInner(View child, int index, LayoutParams params, @@ -3372,6 +3391,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (child.hasTransientState()) { childHasTransientStateChanged(child, true); } + + if (child.getLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT) { + child.resetResolvedLayoutDirection(); + child.resolveRtlProperties(); + } } private void addInArray(View child, int index) { @@ -3597,6 +3621,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager childHasTransientStateChanged(view, false); } + view.resetResolvedLayoutDirection(); + onViewRemoved(view); needGlobalAttributesUpdate(false); @@ -3844,9 +3870,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager addInArray(child, index); child.mParent = this; - child.mPrivateFlags = (child.mPrivateFlags & ~DIRTY_MASK & ~DRAWING_CACHE_VALID) | - DRAWN | INVALIDATED; - this.mPrivateFlags |= INVALIDATED; + child.mPrivateFlags = (child.mPrivateFlags & ~PFLAG_DIRTY_MASK + & ~PFLAG_DRAWING_CACHE_VALID) + | PFLAG_DRAWN | PFLAG_INVALIDATED; + this.mPrivateFlags |= PFLAG_INVALIDATED; if (child.hasFocus()) { requestChildFocus(child, child.findFocus()); @@ -3947,7 +3974,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // If the child is drawing an animation, we want to copy this flag onto // ourselves and the parent to make sure the invalidate request goes // through - final boolean drawAnimation = (child.mPrivateFlags & DRAW_ANIMATION) == DRAW_ANIMATION; + final boolean drawAnimation = (child.mPrivateFlags & PFLAG_DRAW_ANIMATION) + == PFLAG_DRAW_ANIMATION; // Check whether the child that requests the invalidate is fully opaque // Views being animated or transformed are not considered opaque because we may @@ -3957,11 +3985,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager child.getAnimation() == null && childMatrix.isIdentity(); // Mark the child as dirty, using the appropriate flag // Make sure we do not set both flags at the same time - int opaqueFlag = isOpaque ? DIRTY_OPAQUE : DIRTY; + int opaqueFlag = isOpaque ? PFLAG_DIRTY_OPAQUE : PFLAG_DIRTY; if (child.mLayerType != LAYER_TYPE_NONE) { - mPrivateFlags |= INVALIDATED; - mPrivateFlags &= ~DRAWING_CACHE_VALID; + mPrivateFlags |= PFLAG_INVALIDATED; + mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID; child.mLocalDirtyRect.union(dirty); } @@ -4003,7 +4031,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (drawAnimation) { if (view != null) { - view.mPrivateFlags |= DRAW_ANIMATION; + view.mPrivateFlags |= PFLAG_DRAW_ANIMATION; } else if (parent instanceof ViewRootImpl) { ((ViewRootImpl) parent).mIsAnimating = true; } @@ -4014,10 +4042,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (view != null) { if ((view.mViewFlags & FADING_EDGE_MASK) != 0 && view.getSolidColor() == 0) { - opaqueFlag = DIRTY; + opaqueFlag = PFLAG_DIRTY; } - if ((view.mPrivateFlags & DIRTY_MASK) != DIRTY) { - view.mPrivateFlags = (view.mPrivateFlags & ~DIRTY_MASK) | opaqueFlag; + if ((view.mPrivateFlags & PFLAG_DIRTY_MASK) != PFLAG_DIRTY) { + view.mPrivateFlags = (view.mPrivateFlags & ~PFLAG_DIRTY_MASK) | opaqueFlag; } } @@ -4048,8 +4076,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * does not intersect with this ViewGroup's bounds. */ public ViewParent invalidateChildInParent(final int[] location, final Rect dirty) { - if ((mPrivateFlags & DRAWN) == DRAWN || - (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID) { + if ((mPrivateFlags & PFLAG_DRAWN) == PFLAG_DRAWN || + (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID) { if ((mGroupFlags & (FLAG_OPTIMIZE_INVALIDATE | FLAG_ANIMATION_DONE)) != FLAG_OPTIMIZE_INVALIDATE) { dirty.offset(location[CHILD_LEFT_INDEX] - mScrollX, @@ -4063,20 +4091,20 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager dirty.setEmpty(); } } - mPrivateFlags &= ~DRAWING_CACHE_VALID; + mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID; location[CHILD_LEFT_INDEX] = left; location[CHILD_TOP_INDEX] = top; if (mLayerType != LAYER_TYPE_NONE) { - mPrivateFlags |= INVALIDATED; + mPrivateFlags |= PFLAG_INVALIDATED; mLocalDirtyRect.union(dirty); } return mParent; } else { - mPrivateFlags &= ~DRAWN & ~DRAWING_CACHE_VALID; + mPrivateFlags &= ~PFLAG_DRAWN & ~PFLAG_DRAWING_CACHE_VALID; location[CHILD_LEFT_INDEX] = mLeft; location[CHILD_TOP_INDEX] = mTop; @@ -4088,7 +4116,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } if (mLayerType != LAYER_TYPE_NONE) { - mPrivateFlags |= INVALIDATED; + mPrivateFlags |= PFLAG_INVALIDATED; mLocalDirtyRect.union(dirty); } @@ -4150,8 +4178,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * coordinate system, pruning the invalidation if the parent has already been invalidated. */ private ViewParent invalidateChildInParentFast(int left, int top, final Rect dirty) { - if ((mPrivateFlags & DRAWN) == DRAWN || - (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID) { + if ((mPrivateFlags & PFLAG_DRAWN) == PFLAG_DRAWN || + (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID) { dirty.offset(left - mScrollX, top - mScrollY); if ((mGroupFlags & FLAG_CLIP_CHILDREN) == 0 || @@ -4914,11 +4942,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager view.clearAnimation(); } - if ((view.mPrivateFlags & ANIMATION_STARTED) == ANIMATION_STARTED) { + if ((view.mPrivateFlags & PFLAG_ANIMATION_STARTED) == PFLAG_ANIMATION_STARTED) { view.onAnimationEnd(); // Should be performed by onAnimationEnd() but this avoid an infinite loop, // so we'd rather be safe than sorry - view.mPrivateFlags &= ~ANIMATION_STARTED; + view.mPrivateFlags &= ~PFLAG_ANIMATION_STARTED; // Draw one more frame after the animation is done mGroupFlags |= FLAG_INVALIDATE_REQUIRED; } @@ -5017,7 +5045,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager @Override public boolean gatherTransparentRegion(Region region) { // If no transparent regions requested, we are always opaque. - final boolean meOpaque = (mPrivateFlags & View.REQUEST_TRANSPARENT_REGIONS) == 0; + final boolean meOpaque = (mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) == 0; if (meOpaque && region == null) { // The caller doesn't care about the region, so stop now. return true; @@ -5042,7 +5070,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager */ public void requestTransparentRegion(View child) { if (child != null) { - child.mPrivateFlags |= View.REQUEST_TRANSPARENT_REGIONS; + child.mPrivateFlags |= View.PFLAG_REQUEST_TRANSPARENT_REGIONS; if (mParent != null) { mParent.requestTransparentRegion(this); } diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java index ce6f4c5..d8db14c 100644 --- a/core/java/android/view/ViewPropertyAnimator.java +++ b/core/java/android/view/ViewPropertyAnimator.java @@ -1036,7 +1036,7 @@ public class ViewPropertyAnimator { if ((propertyMask & TRANSFORM_MASK) != 0) { mView.mTransformationInfo.mMatrixDirty = true; if (!useDisplayListProperties) { - mView.mPrivateFlags |= View.DRAWN; // force another invalidation + mView.mPrivateFlags |= View.PFLAG_DRAWN; // force another invalidation } } // invalidate(false) in all cases except if alphaHandled gets set to true diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index afcbaaf..725d9b5 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -18,7 +18,6 @@ package android.view; import android.Manifest; import android.animation.LayoutTransition; -import android.animation.ValueAnimator; import android.app.ActivityManagerNative; import android.content.ClipDescription; import android.content.ComponentCallbacks; @@ -88,7 +87,7 @@ import java.util.HashSet; /** * The top of a view hierarchy, implementing the needed protocol between View * and the WindowManager. This is for the most part an internal implementation - * detail of {@link WindowManagerImpl}. + * detail of {@link WindowManagerGlobal}. * * {@hide} */ @@ -126,11 +125,6 @@ public final class ViewRootImpl implements ViewParent, */ static final int MAX_TRACKBALL_DELAY = 250; - static IWindowSession sWindowSession; - - static final Object mStaticInit = new Object(); - static boolean mInitialized = false; - static final ThreadLocal<RunQueue> sRunQueues = new ThreadLocal<RunQueue>(); static final ArrayList<Runnable> sFirstDrawHandlers = new ArrayList<Runnable>(); @@ -143,6 +137,9 @@ public final class ViewRootImpl implements ViewParent, private static boolean sRenderThreadQueried = false; private static final Object[] sRenderThreadQueryLock = new Object[0]; + final IWindowSession mWindowSession; + final Display mDisplay; + long mLastTrackballTime = 0; final TrackballAxis mTrackballAxisX = new TrackballAxis(); final TrackballAxis mTrackballAxisY = new TrackballAxis(); @@ -250,7 +247,7 @@ public final class ViewRootImpl implements ViewParent, boolean mAdded; boolean mAddedTouchMode; - CompatibilityInfoHolder mCompatibilityInfo; + final CompatibilityInfoHolder mCompatibilityInfo; // These are accessed by multiple threads. final Rect mWinFrame; // frame given by window manager. @@ -322,24 +319,6 @@ public final class ViewRootImpl implements ViewParent, InputEventConsistencyVerifier.isInstrumentationEnabled() ? new InputEventConsistencyVerifier(this, 0) : null; - public static IWindowSession getWindowSession(Looper mainLooper) { - synchronized (mStaticInit) { - if (!mInitialized) { - try { - InputMethodManager imm = InputMethodManager.getInstance(mainLooper); - IWindowManager windowManager = WindowManagerImpl.getWindowManagerService(); - sWindowSession = windowManager.openSession( - imm.getClient(), imm.getInputContext()); - float animatorScale = windowManager.getAnimationScale(2); - ValueAnimator.setDurationScale(animatorScale); - mInitialized = true; - } catch (RemoteException e) { - } - } - return sWindowSession; - } - } - static final class SystemUiVisibilityInfo { int seq; int globalVisibility; @@ -347,7 +326,7 @@ public final class ViewRootImpl implements ViewParent, int localChanges; } - public ViewRootImpl(Context context) { + public ViewRootImpl(Context context, Display display) { super(); if (MEASURE_LATENCY) { @@ -359,7 +338,11 @@ public final class ViewRootImpl implements ViewParent, // Initialize the statics when this class is first instantiated. This is // done here instead of in the static block because Zygote does not // allow the spawning of threads. - getWindowSession(context.getMainLooper()); + mWindowSession = WindowManagerGlobal.getWindowSession(context.getMainLooper()); + mDisplay = display; + + CompatibilityInfoHolder cih = display.getCompatibilityInfo(); + mCompatibilityInfo = cih != null ? cih : new CompatibilityInfoHolder(); mThread = Thread.currentThread(); mLocation = new WindowLeaked(null); @@ -383,7 +366,7 @@ public final class ViewRootImpl implements ViewParent, new AccessibilityInteractionConnectionManager(); mAccessibilityManager.addAccessibilityStateChangeListener( mAccessibilityInteractionConnectionManager); - mAttachInfo = new View.AttachInfo(sWindowSession, mWindow, this, mHandler, this); + mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this); mViewConfiguration = ViewConfiguration.get(context); mDensity = context.getResources().getDisplayMetrics().densityDpi; mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi; @@ -460,9 +443,10 @@ public final class ViewRootImpl implements ViewParent, * @hide */ static boolean isInTouchMode() { - if (mInitialized) { + IWindowSession windowSession = WindowManagerGlobal.peekWindowSession(); + if (windowSession != null) { try { - return sWindowSession.getInTouchMode(); + return windowSession.getInTouchMode(); } catch (RemoteException e) { } } @@ -541,8 +525,8 @@ public final class ViewRootImpl implements ViewParent, mOrigWindowType = mWindowAttributes.type; mAttachInfo.mRecomputeGlobalAttributes = true; collectViewAttributes(); - res = sWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes, - getHostVisibility(), Display.DEFAULT_DISPLAY, + res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes, + getHostVisibility(), mDisplay.getDisplayId(), mAttachInfo.mContentInsets, mInputChannel); } catch (RemoteException e) { mAdded = false; @@ -565,7 +549,7 @@ public final class ViewRootImpl implements ViewParent, mPendingContentInsets.set(mAttachInfo.mContentInsets); mPendingVisibleInsets.set(0, 0, 0, 0); if (DEBUG_LAYOUT) Log.v(TAG, "Added window " + mWindow); - if (res < WindowManagerImpl.ADD_OKAY) { + if (res < WindowManagerGlobal.ADD_OKAY) { mView = null; mAttachInfo.mRootView = null; mAdded = false; @@ -573,33 +557,33 @@ public final class ViewRootImpl implements ViewParent, unscheduleTraversals(); setAccessibilityFocus(null, null); switch (res) { - case WindowManagerImpl.ADD_BAD_APP_TOKEN: - case WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN: - throw new WindowManagerImpl.BadTokenException( + case WindowManagerGlobal.ADD_BAD_APP_TOKEN: + case WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN: + throw new WindowManager.BadTokenException( "Unable to add window -- token " + attrs.token + " is not valid; is your activity running?"); - case WindowManagerImpl.ADD_NOT_APP_TOKEN: - throw new WindowManagerImpl.BadTokenException( + case WindowManagerGlobal.ADD_NOT_APP_TOKEN: + throw new WindowManager.BadTokenException( "Unable to add window -- token " + attrs.token + " is not for an application"); - case WindowManagerImpl.ADD_APP_EXITING: - throw new WindowManagerImpl.BadTokenException( + case WindowManagerGlobal.ADD_APP_EXITING: + throw new WindowManager.BadTokenException( "Unable to add window -- app for token " + attrs.token + " is exiting"); - case WindowManagerImpl.ADD_DUPLICATE_ADD: - throw new WindowManagerImpl.BadTokenException( + case WindowManagerGlobal.ADD_DUPLICATE_ADD: + throw new WindowManager.BadTokenException( "Unable to add window -- window " + mWindow + " has already been added"); - case WindowManagerImpl.ADD_STARTING_NOT_NEEDED: + case WindowManagerGlobal.ADD_STARTING_NOT_NEEDED: // Silently ignore -- we would have just removed it // right away, anyway. return; - case WindowManagerImpl.ADD_MULTIPLE_SINGLETON: - throw new WindowManagerImpl.BadTokenException( + case WindowManagerGlobal.ADD_MULTIPLE_SINGLETON: + throw new WindowManager.BadTokenException( "Unable to add window " + mWindow + " -- another window of this type already exists"); - case WindowManagerImpl.ADD_PERMISSION_DENIED: - throw new WindowManagerImpl.BadTokenException( + case WindowManagerGlobal.ADD_PERMISSION_DENIED: + throw new WindowManager.BadTokenException( "Unable to add window " + mWindow + " -- permission denied for this window type"); } @@ -622,8 +606,8 @@ public final class ViewRootImpl implements ViewParent, } view.assignParent(this); - mAddedTouchMode = (res&WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE) != 0; - mAppVisible = (res&WindowManagerImpl.ADD_FLAG_APP_VISIBLE) != 0; + mAddedTouchMode = (res & WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE) != 0; + mAppVisible = (res & WindowManagerGlobal.ADD_FLAG_APP_VISIBLE) != 0; if (mAccessibilityManager.isEnabled()) { mAccessibilityInteractionConnectionManager.ensureConnection(); @@ -1164,9 +1148,8 @@ public final class ViewRootImpl implements ViewParent, if (lp.type == WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL) { // NOTE -- system code, won't try to do compat mode. - Display disp = WindowManagerImpl.getDefault().getDefaultDisplay(); Point size = new Point(); - disp.getRealSize(size); + mDisplay.getRealSize(size); desiredWindowWidth = size.x; desiredWindowHeight = size.y; } else { @@ -1251,9 +1234,8 @@ public final class ViewRootImpl implements ViewParent, if (lp.type == WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL) { // NOTE -- system code, won't try to do compat mode. - Display disp = WindowManagerImpl.getDefault().getDefaultDisplay(); Point size = new Point(); - disp.getRealSize(size); + mDisplay.getRealSize(size); desiredWindowWidth = size.x; desiredWindowHeight = size.y; } else { @@ -1303,7 +1285,7 @@ public final class ViewRootImpl implements ViewParent, } } - if (params != null && (host.mPrivateFlags & View.REQUEST_TRANSPARENT_REGIONS) != 0) { + if (params != null && (host.mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) != 0) { if (!PixelFormat.formatHasAlpha(params.format)) { params.format = PixelFormat.TRANSLUCENT; } @@ -1502,7 +1484,7 @@ public final class ViewRootImpl implements ViewParent, } catch (Surface.OutOfResourcesException e) { Log.e(TAG, "OutOfResourcesException initializing HW surface", e); try { - if (!sWindowSession.outOfMemory(mWindow)) { + if (!mWindowSession.outOfMemory(mWindow)) { Slog.w(TAG, "No processes killed for memory; killing self"); Process.killProcess(Process.myPid()); } @@ -1535,7 +1517,7 @@ public final class ViewRootImpl implements ViewParent, } catch (Surface.OutOfResourcesException e) { Log.e(TAG, "OutOfResourcesException updating HW surface", e); try { - if (!sWindowSession.outOfMemory(mWindow)) { + if (!mWindowSession.outOfMemory(mWindow)) { Slog.w(TAG, "No processes killed for memory; killing self"); Process.killProcess(Process.myPid()); } @@ -1629,7 +1611,7 @@ public final class ViewRootImpl implements ViewParent, if (!mStopped) { boolean focusChangedDueToTouchMode = ensureTouchModeLocally( - (relayoutResult&WindowManagerImpl.RELAYOUT_RES_IN_TOUCH_MODE) != 0); + (relayoutResult&WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE) != 0); if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth() || mHeight != host.getMeasuredHeight() || contentInsetsChanged) { int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width); @@ -1709,7 +1691,7 @@ public final class ViewRootImpl implements ViewParent, // By this point all views have been sized and positionned // We can compute the transparent area - if ((host.mPrivateFlags & View.REQUEST_TRANSPARENT_REGIONS) != 0) { + if ((host.mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) != 0) { // start out transparent // TODO: AVOID THAT CALL BY CACHING THE RESULT? host.getLocationInWindow(mTmpLocation); @@ -1726,7 +1708,7 @@ public final class ViewRootImpl implements ViewParent, mPreviousTransparentRegion.set(mTransparentRegion); // reconfigure window manager try { - sWindowSession.setTransparentRegion(mWindow, mTransparentRegion); + mWindowSession.setTransparentRegion(mWindow, mTransparentRegion); } catch (RemoteException e) { } } @@ -1775,7 +1757,7 @@ public final class ViewRootImpl implements ViewParent, } try { - sWindowSession.setInsets(mWindow, insets.mTouchableInsets, + mWindowSession.setInsets(mWindow, insets.mTouchableInsets, contentInsets, visibleInsets, touchableRegion); } catch (RemoteException e) { } @@ -1800,7 +1782,7 @@ public final class ViewRootImpl implements ViewParent, + mRealFocusedView); } } - if ((relayoutResult&WindowManagerImpl.RELAYOUT_RES_ANIMATING) != 0) { + if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_ANIMATING) != 0) { // The first time we relayout the window, if the system is // doing window animations, we want to hold of on any future // draws until the animation is done. @@ -1831,7 +1813,7 @@ public final class ViewRootImpl implements ViewParent, } // Remember if we must report the next draw. - if ((relayoutResult & WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0) { + if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) { mReportNextDraw = true; } @@ -1893,7 +1875,7 @@ public final class ViewRootImpl implements ViewParent, // the test below should not fail unless someone is messing with us checkThread(); if (mView == child) { - mView.mPrivateFlags |= View.REQUEST_TRANSPARENT_REGIONS; + mView.mPrivateFlags |= View.PFLAG_REQUEST_TRANSPARENT_REGIONS; // Need to make sure we re-evaluate the window attributes next // time around, to ensure the window has the correct format. mWindowAttributesChanged = true; @@ -2061,7 +2043,7 @@ public final class ViewRootImpl implements ViewParent, } } try { - sWindowSession.finishDrawing(mWindow); + mWindowSession.finishDrawing(mWindow); } catch (RemoteException e) { } } @@ -2217,7 +2199,7 @@ public final class ViewRootImpl implements ViewParent, } catch (Surface.OutOfResourcesException e) { Log.e(TAG, "OutOfResourcesException locking surface", e); try { - if (!sWindowSession.outOfMemory(mWindow)) { + if (!mWindowSession.outOfMemory(mWindow)) { Slog.w(TAG, "No processes killed for memory; killing self"); Process.killProcess(Process.myPid()); } @@ -2256,7 +2238,7 @@ public final class ViewRootImpl implements ViewParent, dirty.setEmpty(); mIsAnimating = false; attachInfo.mDrawingTime = SystemClock.uptimeMillis(); - mView.mPrivateFlags |= View.DRAWN; + mView.mPrivateFlags |= View.PFLAG_DRAWN; if (DEBUG_DRAW) { Context cxt = mView.getContext(); @@ -2646,7 +2628,7 @@ public final class ViewRootImpl implements ViewParent, mInputEventReceiver = null; } try { - sWindowSession.remove(mWindow); + mWindowSession.remove(mWindow); } catch (RemoteException e) { } @@ -2891,7 +2873,7 @@ public final class ViewRootImpl implements ViewParent, } catch (Surface.OutOfResourcesException e) { Log.e(TAG, "OutOfResourcesException locking surface", e); try { - if (!sWindowSession.outOfMemory(mWindow)) { + if (!mWindowSession.outOfMemory(mWindow)) { Slog.w(TAG, "No processes killed for memory; killing self"); Process.killProcess(Process.myPid()); } @@ -3036,7 +3018,7 @@ public final class ViewRootImpl implements ViewParent, // tell the window manager try { - sWindowSession.setInTouchMode(inTouchMode); + mWindowSession.setInTouchMode(inTouchMode); } catch (RemoteException e) { throw new RuntimeException(e); } @@ -3750,10 +3732,10 @@ public final class ViewRootImpl implements ViewParent, if (prevDragView != mCurrentDragView) { try { if (prevDragView != null) { - sWindowSession.dragRecipientExited(mWindow); + mWindowSession.dragRecipientExited(mWindow); } if (mCurrentDragView != null) { - sWindowSession.dragRecipientEntered(mWindow); + mWindowSession.dragRecipientEntered(mWindow); } } catch (RemoteException e) { Slog.e(TAG, "Unable to note drag target change"); @@ -3765,7 +3747,7 @@ public final class ViewRootImpl implements ViewParent, mDragDescription = null; try { Log.i(TAG, "Reporting drop result: " + result); - sWindowSession.reportDropResult(mWindow, result); + mWindowSession.reportDropResult(mWindow, result); } catch (RemoteException e) { Log.e(TAG, "Unable to report drop result"); } @@ -3867,11 +3849,11 @@ public final class ViewRootImpl implements ViewParent, params.type = mOrigWindowType; } } - int relayoutResult = sWindowSession.relayout( + int relayoutResult = mWindowSession.relayout( mWindow, mSeq, params, (int) (mView.getMeasuredWidth() * appScale + 0.5f), (int) (mView.getMeasuredHeight() * appScale + 0.5f), - viewVisibility, insetsPending ? WindowManagerImpl.RELAYOUT_INSETS_PENDING : 0, + viewVisibility, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, mWinFrame, mPendingContentInsets, mPendingVisibleInsets, mPendingConfiguration, mSurface); //Log.d(TAG, "<<<<<< BACK FROM relayout"); @@ -3928,7 +3910,7 @@ public final class ViewRootImpl implements ViewParent, */ public boolean performHapticFeedback(int effectId, boolean always) { try { - return sWindowSession.performHapticFeedback(mWindow, effectId, always); + return mWindowSession.performHapticFeedback(mWindow, effectId, always); } catch (RemoteException e) { return false; } @@ -4007,8 +3989,8 @@ public final class ViewRootImpl implements ViewParent, // animation info. try { if ((relayoutWindow(mWindowAttributes, viewVisibility, false) - & WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0) { - sWindowSession.finishDrawing(mWindow); + & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) { + mWindowSession.finishDrawing(mWindow); } } catch (RemoteException e) { } @@ -4726,9 +4708,11 @@ public final class ViewRootImpl implements ViewParent, static class W extends IWindow.Stub { private final WeakReference<ViewRootImpl> mViewAncestor; + private final IWindowSession mWindowSession; W(ViewRootImpl viewAncestor) { mViewAncestor = new WeakReference<ViewRootImpl>(viewAncestor); + mWindowSession = viewAncestor.mWindowSession; } public void resized(Rect frame, Rect contentInsets, @@ -4827,7 +4811,7 @@ public final class ViewRootImpl implements ViewParent, boolean sync) { if (sync) { try { - sWindowSession.wallpaperOffsetsComplete(asBinder()); + mWindowSession.wallpaperOffsetsComplete(asBinder()); } catch (RemoteException e) { } } @@ -4837,7 +4821,7 @@ public final class ViewRootImpl implements ViewParent, int z, Bundle extras, boolean sync) { if (sync) { try { - sWindowSession.wallpaperCommandComplete(asBinder(), null); + mWindowSession.wallpaperCommandComplete(asBinder(), null); } catch (RemoteException e) { } } diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index f57f056..a242895 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -16,7 +16,6 @@ package android.view; -import android.app.Application; import android.content.Context; import android.content.res.Configuration; import android.content.res.TypedArray; @@ -455,7 +454,7 @@ public abstract class Window { * display panels. This is <em>not</em> used for displaying the * Window itself -- that must be done by the client. * - * @param wm The ViewManager for adding new windows. + * @param wm The window manager for adding new windows. */ public void setWindowManager(WindowManager wm, IBinder appToken, String appName) { setWindowManager(wm, appToken, appName, false); @@ -466,7 +465,7 @@ public abstract class Window { * display panels. This is <em>not</em> used for displaying the * Window itself -- that must be done by the client. * - * @param wm The ViewManager for adding new windows. + * @param wm The window manager for adding new windows. */ public void setWindowManager(WindowManager wm, IBinder appToken, String appName, boolean hardwareAccelerated) { @@ -475,14 +474,9 @@ public abstract class Window { mHardwareAccelerated = hardwareAccelerated || SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false); if (wm == null) { - wm = WindowManagerImpl.getDefault(); + wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE); } - mWindowManager = ((WindowManagerImpl)wm).makeLocal(this); - } - - CompatibilityInfoHolder getCompatibilityInfo() { - Application app = (Application)mContext.getApplicationContext(); - return app != null ? app.mLoadedApk.mCompatibilityInfo : null; + mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this); } void adjustLayoutParamsForSubWindow(WindowManager.LayoutParams wp) { diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java new file mode 100644 index 0000000..7855763c --- /dev/null +++ b/core/java/android/view/WindowManagerGlobal.java @@ -0,0 +1,516 @@ +/* + * 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.view; + +import android.animation.ValueAnimator; +import android.app.ActivityManager; +import android.content.ComponentCallbacks2; +import android.content.res.Configuration; +import android.opengl.ManagedEGLContext; +import android.os.IBinder; +import android.os.Looper; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.SystemProperties; +import android.util.AndroidRuntimeException; +import android.util.Log; +import android.view.inputmethod.InputMethodManager; + +import java.io.FileDescriptor; +import java.io.FileOutputStream; +import java.io.PrintWriter; + +/** + * Provides low-level communication with the system window manager for + * operations that are not associated with any particular context. + * + * This class is only used internally to implement global functions where + * the caller already knows the display and relevant compatibility information + * for the operation. For most purposes, you should use {@link WindowManager} instead + * since it is bound to a context. + * + * @see WindowManagerImpl + * @hide + */ +public final class WindowManagerGlobal { + private static final String TAG = "WindowManager"; + + /** + * The user is navigating with keys (not the touch screen), so + * navigational focus should be shown. + */ + public static final int RELAYOUT_RES_IN_TOUCH_MODE = 0x1; + + /** + * This is the first time the window is being drawn, + * so the client must call drawingFinished() when done + */ + public static final int RELAYOUT_RES_FIRST_TIME = 0x2; + + /** + * The window manager has changed the surface from the last call. + */ + public static final int RELAYOUT_RES_SURFACE_CHANGED = 0x4; + + /** + * The window manager is currently animating. It will call + * IWindow.doneAnimating() when done. + */ + public static final int RELAYOUT_RES_ANIMATING = 0x8; + + /** + * Flag for relayout: the client will be later giving + * internal insets; as a result, the window will not impact other window + * layouts until the insets are given. + */ + public static final int RELAYOUT_INSETS_PENDING = 0x1; + + /** + * Flag for relayout: the client may be currently using the current surface, + * so if it is to be destroyed as a part of the relayout the destroy must + * be deferred until later. The client will call performDeferredDestroy() + * when it is okay. + */ + public static final int RELAYOUT_DEFER_SURFACE_DESTROY = 0x2; + + public static final int ADD_FLAG_APP_VISIBLE = 0x2; + public static final int ADD_FLAG_IN_TOUCH_MODE = RELAYOUT_RES_IN_TOUCH_MODE; + + public static final int ADD_OKAY = 0; + public static final int ADD_BAD_APP_TOKEN = -1; + public static final int ADD_BAD_SUBWINDOW_TOKEN = -2; + public static final int ADD_NOT_APP_TOKEN = -3; + public static final int ADD_APP_EXITING = -4; + public static final int ADD_DUPLICATE_ADD = -5; + public static final int ADD_STARTING_NOT_NEEDED = -6; + public static final int ADD_MULTIPLE_SINGLETON = -7; + public static final int ADD_PERMISSION_DENIED = -8; + + private static WindowManagerGlobal sDefaultWindowManager; + private static IWindowManager sWindowManagerService; + private static IWindowSession sWindowSession; + + private final Object mLock = new Object(); + + private View[] mViews; + private ViewRootImpl[] mRoots; + private WindowManager.LayoutParams[] mParams; + private boolean mNeedsEglTerminate; + + private Runnable mSystemPropertyUpdater; + + private WindowManagerGlobal() { + } + + public static WindowManagerGlobal getInstance() { + synchronized (WindowManagerGlobal.class) { + if (sDefaultWindowManager == null) { + sDefaultWindowManager = new WindowManagerGlobal(); + } + return sDefaultWindowManager; + } + } + + public static IWindowManager getWindowManagerService() { + synchronized (WindowManagerGlobal.class) { + if (sWindowManagerService == null) { + sWindowManagerService = IWindowManager.Stub.asInterface( + ServiceManager.getService("window")); + } + return sWindowManagerService; + } + } + + public static IWindowSession getWindowSession(Looper mainLooper) { + synchronized (WindowManagerGlobal.class) { + if (sWindowSession == null) { + try { + InputMethodManager imm = InputMethodManager.getInstance(mainLooper); + IWindowManager windowManager = getWindowManagerService(); + sWindowSession = windowManager.openSession( + imm.getClient(), imm.getInputContext()); + float animatorScale = windowManager.getAnimationScale(2); + ValueAnimator.setDurationScale(animatorScale); + } catch (RemoteException e) { + Log.e(TAG, "Failed to open window session", e); + } + } + return sWindowSession; + } + } + + public static IWindowSession peekWindowSession() { + synchronized (WindowManagerGlobal.class) { + return sWindowSession; + } + } + + public void addView(View view, ViewGroup.LayoutParams params, + Display display, Window parentWindow) { + if (view == null) { + throw new IllegalArgumentException("view must not be null"); + } + if (display == null) { + throw new IllegalArgumentException("display must not be null"); + } + if (!(params instanceof WindowManager.LayoutParams)) { + throw new IllegalArgumentException("Params must be WindowManager.LayoutParams"); + } + + final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params; + if (parentWindow != null) { + parentWindow.adjustLayoutParamsForSubWindow(wparams); + } + + ViewRootImpl root; + View panelParentView = null; + + synchronized (mLock) { + // Start watching for system property changes. + if (mSystemPropertyUpdater == null) { + mSystemPropertyUpdater = new Runnable() { + @Override public void run() { + synchronized (mLock) { + for (ViewRootImpl root : mRoots) { + root.loadSystemProperties(); + } + } + } + }; + SystemProperties.addChangeCallback(mSystemPropertyUpdater); + } + + int index = findViewLocked(view, false); + if (index >= 0) { + throw new IllegalStateException("View " + view + + " has already been added to the window manager."); + } + + // If this is a panel window, then find the window it is being + // attached to for future reference. + if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW && + wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) { + final int count = mViews != null ? mViews.length : 0; + for (int i=0; i<count; i++) { + if (mRoots[i].mWindow.asBinder() == wparams.token) { + panelParentView = mViews[i]; + } + } + } + + root = new ViewRootImpl(view.getContext(), display); + + view.setLayoutParams(wparams); + + if (mViews == null) { + index = 1; + mViews = new View[1]; + mRoots = new ViewRootImpl[1]; + mParams = new WindowManager.LayoutParams[1]; + } else { + index = mViews.length + 1; + Object[] old = mViews; + mViews = new View[index]; + System.arraycopy(old, 0, mViews, 0, index-1); + old = mRoots; + mRoots = new ViewRootImpl[index]; + System.arraycopy(old, 0, mRoots, 0, index-1); + old = mParams; + mParams = new WindowManager.LayoutParams[index]; + System.arraycopy(old, 0, mParams, 0, index-1); + } + index--; + + mViews[index] = view; + mRoots[index] = root; + mParams[index] = wparams; + } + + // do this last because it fires off messages to start doing things + root.setView(view, wparams, panelParentView); + } + + public void updateViewLayout(View view, ViewGroup.LayoutParams params) { + if (view == null) { + throw new IllegalArgumentException("view must not be null"); + } + if (!(params instanceof WindowManager.LayoutParams)) { + throw new IllegalArgumentException("Params must be WindowManager.LayoutParams"); + } + + final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params; + + view.setLayoutParams(wparams); + + synchronized (mLock) { + int index = findViewLocked(view, true); + ViewRootImpl root = mRoots[index]; + mParams[index] = wparams; + root.setLayoutParams(wparams, false); + } + } + + public void removeView(View view, boolean immediate) { + if (view == null) { + throw new IllegalArgumentException("view must not be null"); + } + + synchronized (mLock) { + int index = findViewLocked(view, true); + View curView = removeViewLocked(index, immediate); + if (curView == view) { + return; + } + + throw new IllegalStateException("Calling with view " + view + + " but the ViewAncestor is attached to " + curView); + } + } + + public void closeAll(IBinder token, String who, String what) { + synchronized (mLock) { + if (mViews == null) + return; + + int count = mViews.length; + //Log.i("foo", "Closing all windows of " + token); + for (int i=0; i<count; i++) { + //Log.i("foo", "@ " + i + " token " + mParams[i].token + // + " view " + mRoots[i].getView()); + if (token == null || mParams[i].token == token) { + ViewRootImpl root = mRoots[i]; + + //Log.i("foo", "Force closing " + root); + if (who != null) { + WindowLeaked leak = new WindowLeaked( + what + " " + who + " has leaked window " + + root.getView() + " that was originally added here"); + leak.setStackTrace(root.getLocation().getStackTrace()); + Log.e(TAG, leak.getMessage(), leak); + } + + removeViewLocked(i, false); + i--; + count--; + } + } + } + } + + private View removeViewLocked(int index, boolean immediate) { + ViewRootImpl root = mRoots[index]; + View view = root.getView(); + + if (view != null) { + InputMethodManager imm = InputMethodManager.getInstance(view.getContext()); + if (imm != null) { + imm.windowDismissed(mViews[index].getWindowToken()); + } + } + root.die(immediate); + + final int count = mViews.length; + + // remove it from the list + View[] tmpViews = new View[count-1]; + removeItem(tmpViews, mViews, index); + mViews = tmpViews; + + ViewRootImpl[] tmpRoots = new ViewRootImpl[count-1]; + removeItem(tmpRoots, mRoots, index); + mRoots = tmpRoots; + + WindowManager.LayoutParams[] tmpParams + = new WindowManager.LayoutParams[count-1]; + removeItem(tmpParams, mParams, index); + mParams = tmpParams; + + if (view != null) { + view.assignParent(null); + // func doesn't allow null... does it matter if we clear them? + //view.setLayoutParams(null); + } + return view; + } + + private static void removeItem(Object[] dst, Object[] src, int index) { + if (dst.length > 0) { + if (index > 0) { + System.arraycopy(src, 0, dst, 0, index); + } + if (index < dst.length) { + System.arraycopy(src, index+1, dst, index, src.length-index-1); + } + } + } + + private int findViewLocked(View view, boolean required) { + synchronized (mLock) { + if (mViews != null) { + final int count = mViews.length; + for (int i = 0; i < count; i++) { + if (mViews[i] == view) { + return i; + } + } + } + if (required) { + throw new IllegalArgumentException("View not attached to window manager"); + } + return -1; + } + } + + public void startTrimMemory(int level) { + if (HardwareRenderer.isAvailable()) { + // On low-end gfx devices we trim when memory is moderate; + // on high-end devices we do this when low. + if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE + || (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE + && !ActivityManager.isHighEndGfx())) { + // Destroy all hardware surfaces and resources associated to + // known windows + synchronized (mLock) { + if (mViews == null) return; + int count = mViews.length; + for (int i = 0; i < count; i++) { + mRoots[i].terminateHardwareResources(); + } + } + // Force a full memory flush + mNeedsEglTerminate = true; + HardwareRenderer.startTrimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE); + return; + } + + HardwareRenderer.startTrimMemory(level); + } + } + + public void endTrimMemory() { + HardwareRenderer.endTrimMemory(); + + if (mNeedsEglTerminate) { + ManagedEGLContext.doTerminate(); + mNeedsEglTerminate = false; + } + } + + public void trimLocalMemory() { + synchronized (mLock) { + if (mViews == null) return; + int count = mViews.length; + for (int i = 0; i < count; i++) { + mRoots[i].destroyHardwareLayers(); + } + } + } + + public void dumpGfxInfo(FileDescriptor fd) { + FileOutputStream fout = new FileOutputStream(fd); + PrintWriter pw = new PrintWriter(fout); + try { + synchronized (mLock) { + if (mViews != null) { + final int count = mViews.length; + + pw.println("Profile data in ms:"); + + for (int i = 0; i < count; i++) { + ViewRootImpl root = mRoots[i]; + String name = getWindowName(root); + pw.printf("\n\t%s", name); + + HardwareRenderer renderer = + root.getView().mAttachInfo.mHardwareRenderer; + if (renderer != null) { + renderer.dumpGfxInfo(pw); + } + } + + pw.println("\nView hierarchy:\n"); + + int viewsCount = 0; + int displayListsSize = 0; + int[] info = new int[2]; + + for (int i = 0; i < count; i++) { + ViewRootImpl root = mRoots[i]; + root.dumpGfxInfo(info); + + String name = getWindowName(root); + pw.printf(" %s\n %d views, %.2f kB of display lists", + name, info[0], info[1] / 1024.0f); + HardwareRenderer renderer = + root.getView().mAttachInfo.mHardwareRenderer; + if (renderer != null) { + pw.printf(", %d frames rendered", renderer.getFrameCount()); + } + pw.printf("\n\n"); + + viewsCount += info[0]; + displayListsSize += info[1]; + } + + pw.printf("\nTotal ViewRootImpl: %d\n", count); + pw.printf("Total Views: %d\n", viewsCount); + pw.printf("Total DisplayList: %.2f kB\n\n", displayListsSize / 1024.0f); + } + } + } finally { + pw.flush(); + } + } + + private static String getWindowName(ViewRootImpl root) { + return root.mWindowAttributes.getTitle() + "/" + + root.getClass().getName() + '@' + Integer.toHexString(root.hashCode()); + } + + public void setStoppedState(IBinder token, boolean stopped) { + synchronized (mLock) { + if (mViews != null) { + int count = mViews.length; + for (int i=0; i < count; i++) { + if (token == null || mParams[i].token == token) { + ViewRootImpl root = mRoots[i]; + root.setStopped(stopped); + } + } + } + } + } + + public void reportNewConfiguration(Configuration config) { + synchronized (mLock) { + if (mViews != null) { + int count = mViews.length; + config = new Configuration(config); + for (int i=0; i < count; i++) { + ViewRootImpl root = mRoots[i]; + root.requestUpdateConfiguration(config); + } + } + } + } +} + +final class WindowLeaked extends AndroidRuntimeException { + public WindowLeaked(String msg) { + super(msg); + } +} diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java index bd95cdb..bf061df 100644 --- a/core/java/android/view/WindowManagerImpl.java +++ b/core/java/android/view/WindowManagerImpl.java @@ -16,34 +16,20 @@ package android.view; -import android.app.ActivityManager; -import android.content.ComponentCallbacks2; -import android.content.res.Configuration; -import android.opengl.ManagedEGLContext; -import android.os.IBinder; -import android.os.ServiceManager; -import android.os.SystemProperties; -import android.util.AndroidRuntimeException; -import android.util.Log; -import android.view.inputmethod.InputMethodManager; - -import java.io.FileDescriptor; -import java.io.FileOutputStream; -import java.io.PrintWriter; - -final class WindowLeaked extends AndroidRuntimeException { - public WindowLeaked(String msg) { - super(msg); - } -} +import android.content.Context; +import android.hardware.display.DisplayManager; /** - * Low-level communication with the global system window manager. It implements - * the ViewManager interface, allowing you to add any View subclass as a - * top-level window on the screen. Additional window manager specific layout - * parameters are defined for control over how windows are displayed. - * It also implements the WindowManager interface, allowing you to control the - * displays attached to the device. + * Provides low-level communication with the system window manager for + * operations that are bound to a particular context, display or parent window. + * Instances of this object are sensitive to the compatibility info associated + * with the running application. + * + * This object implements the {@link ViewManager} interface, + * allowing you to add any View subclass as a top-level window on the screen. + * Additional window manager specific layout parameters are defined for + * control over how windows are displayed. It also implements the {@link WindowManager} + * interface, allowing you to control the displays attached to the device. * * <p>Applications will not normally use WindowManager directly, instead relying * on the higher-level facilities in {@link android.app.Activity} and @@ -51,531 +37,58 @@ final class WindowLeaked extends AndroidRuntimeException { * * <p>Even for low-level window manager access, it is almost never correct to use * this class. For example, {@link android.app.Activity#getWindowManager} - * provides a ViewManager for adding windows that are associated with that + * provides a window manager for adding windows that are associated with that * activity -- the window manager will not normally allow you to add arbitrary * windows that are not associated with an activity. - * + * + * @see WindowManager + * @see WindowManagerGlobal * @hide */ -public class WindowManagerImpl implements WindowManager { - private static final String TAG = "WindowManager"; - - /** - * The user is navigating with keys (not the touch screen), so - * navigational focus should be shown. - */ - public static final int RELAYOUT_RES_IN_TOUCH_MODE = 0x1; - - /** - * This is the first time the window is being drawn, - * so the client must call drawingFinished() when done - */ - public static final int RELAYOUT_RES_FIRST_TIME = 0x2; - - /** - * The window manager has changed the surface from the last call. - */ - public static final int RELAYOUT_RES_SURFACE_CHANGED = 0x4; - - /** - * The window manager is currently animating. It will call - * IWindow.doneAnimating() when done. - */ - public static final int RELAYOUT_RES_ANIMATING = 0x8; - - /** - * Flag for relayout: the client will be later giving - * internal insets; as a result, the window will not impact other window - * layouts until the insets are given. - */ - public static final int RELAYOUT_INSETS_PENDING = 0x1; - - /** - * Flag for relayout: the client may be currently using the current surface, - * so if it is to be destroyed as a part of the relayout the destroy must - * be deferred until later. The client will call performDeferredDestroy() - * when it is okay. - */ - public static final int RELAYOUT_DEFER_SURFACE_DESTROY = 0x2; - - public static final int ADD_FLAG_APP_VISIBLE = 0x2; - public static final int ADD_FLAG_IN_TOUCH_MODE = RELAYOUT_RES_IN_TOUCH_MODE; - - public static final int ADD_OKAY = 0; - public static final int ADD_BAD_APP_TOKEN = -1; - public static final int ADD_BAD_SUBWINDOW_TOKEN = -2; - public static final int ADD_NOT_APP_TOKEN = -3; - public static final int ADD_APP_EXITING = -4; - public static final int ADD_DUPLICATE_ADD = -5; - public static final int ADD_STARTING_NOT_NEEDED = -6; - public static final int ADD_MULTIPLE_SINGLETON = -7; - public static final int ADD_PERMISSION_DENIED = -8; - - private static WindowManagerImpl sDefaultWindowManager; - private static IWindowManager sWindowManagerService; - - private final WindowManagerState mState; +public final class WindowManagerImpl implements WindowManager { + private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance(); + private final Context mContext; + private final Display mDisplay; private final Window mParentWindow; - private final CompatibilityInfoHolder mCompatibilityInfo; - private final Display mDefaultDisplay; - private WindowManagerImpl(WindowManagerState state, Window parentWindow, - CompatibilityInfoHolder compatibilityInfo) { - mState = state; - mParentWindow = parentWindow; - mCompatibilityInfo = compatibilityInfo; - mDefaultDisplay = mState.getDefaultDisplay(mCompatibilityInfo); + public WindowManagerImpl(Context context, int displayId) { + mContext = context; + mDisplay = DisplayManager.getInstance().getDisplay(displayId, mContext); + mParentWindow = null; } - public static WindowManagerImpl getDefault() { - synchronized (WindowManagerImpl.class) { - if (sDefaultWindowManager == null) { - sDefaultWindowManager = new WindowManagerImpl( - new WindowManagerState(), null, null); - } - return sDefaultWindowManager; - } - } - - public static IWindowManager getWindowManagerService() { - synchronized (WindowManagerImpl.class) { - if (sWindowManagerService == null) { - sWindowManagerService = IWindowManager.Stub.asInterface( - ServiceManager.getService("window")); - } - return sWindowManagerService; - } - } - - public WindowManagerImpl makeLocal(Window parentWindow) { - return new WindowManagerImpl(mState, parentWindow, parentWindow.getCompatibilityInfo()); + private WindowManagerImpl(Context context, Display display, Window parentWindow) { + mContext = context; + mDisplay = display; + mParentWindow = parentWindow; } - public WindowManagerImpl makeCompatible(CompatibilityInfoHolder compatInfo) { - if (compatInfo == mCompatibilityInfo) { - return this; - } - if (compatInfo == null && mParentWindow == null) { - return getDefault(); - } - return new WindowManagerImpl(mState, mParentWindow, compatInfo); + public WindowManagerImpl createLocalWindowManager(Window parentWindow) { + return new WindowManagerImpl(mContext, mDisplay, parentWindow); } @Override public void addView(View view, ViewGroup.LayoutParams params) { - mState.addView(view, params, mParentWindow, mCompatibilityInfo); + mGlobal.addView(view, params, mDisplay, mParentWindow); } @Override public void updateViewLayout(View view, ViewGroup.LayoutParams params) { - mState.updateViewLayout(view, params); + mGlobal.updateViewLayout(view, params); } @Override public void removeView(View view) { - mState.removeView(view, false); + mGlobal.removeView(view, false); } @Override public void removeViewImmediate(View view) { - mState.removeView(view, true); + mGlobal.removeView(view, true); } @Override public Display getDefaultDisplay() { - return mDefaultDisplay; - } - - public void closeAll(IBinder token, String who, String what) { - mState.closeAll(token, who, what); - } - - public void startTrimMemory(int level) { - mState.startTrimMemory(level); - } - - public void endTrimMemory() { - mState.endTrimMemory(); - } - - public void trimLocalMemory() { - mState.trimLocalMemory(); - } - - public void dumpGfxInfo(FileDescriptor fd) { - mState.dumpGfxInfo(fd); - } - - public void setStoppedState(IBinder token, boolean stopped) { - mState.setStoppedState(token, stopped); - } - - public void reportNewConfiguration(Configuration config) { - mState.reportNewConfiguration(config); - } - - static final class WindowManagerState { - private final Display mDefaultDisplay; - - private View[] mViews; - private ViewRootImpl[] mRoots; - private WindowManager.LayoutParams[] mParams; - private boolean mNeedsEglTerminate; - - private Runnable mSystemPropertyUpdater; - - public WindowManagerState() { - mDefaultDisplay = new Display(Display.DEFAULT_DISPLAY, null); - } - - public Display getDefaultDisplay(CompatibilityInfoHolder compatInfo) { - if (compatInfo == null) { - return mDefaultDisplay; - } - return new Display(Display.DEFAULT_DISPLAY, compatInfo); - } - - public void addView(View view, ViewGroup.LayoutParams params, Window parentWindow, - CompatibilityInfoHolder cih) { - if (!(params instanceof WindowManager.LayoutParams)) { - throw new IllegalArgumentException("Params must be WindowManager.LayoutParams"); - } - - final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params; - if (parentWindow != null) { - parentWindow.adjustLayoutParamsForSubWindow(wparams); - } - - ViewRootImpl root; - View panelParentView = null; - - synchronized (this) { - // Start watching for system property changes. - if (mSystemPropertyUpdater == null) { - mSystemPropertyUpdater = new Runnable() { - @Override public void run() { - synchronized (this) { - synchronized (this) { - for (ViewRootImpl root : mRoots) { - root.loadSystemProperties(); - } - } - } - } - }; - SystemProperties.addChangeCallback(mSystemPropertyUpdater); - } - - int index = findViewLocked(view, false); - if (index >= 0) { - throw new IllegalStateException("View " + view - + " has already been added to the window manager."); - } - - // If this is a panel window, then find the window it is being - // attached to for future reference. - if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW && - wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) { - final int count = mViews != null ? mViews.length : 0; - for (int i=0; i<count; i++) { - if (mRoots[i].mWindow.asBinder() == wparams.token) { - panelParentView = mViews[i]; - } - } - } - - root = new ViewRootImpl(view.getContext()); - if (cih == null) { - root.mCompatibilityInfo = new CompatibilityInfoHolder(); - } else { - root.mCompatibilityInfo = cih; - } - - view.setLayoutParams(wparams); - - if (mViews == null) { - index = 1; - mViews = new View[1]; - mRoots = new ViewRootImpl[1]; - mParams = new WindowManager.LayoutParams[1]; - } else { - index = mViews.length + 1; - Object[] old = mViews; - mViews = new View[index]; - System.arraycopy(old, 0, mViews, 0, index-1); - old = mRoots; - mRoots = new ViewRootImpl[index]; - System.arraycopy(old, 0, mRoots, 0, index-1); - old = mParams; - mParams = new WindowManager.LayoutParams[index]; - System.arraycopy(old, 0, mParams, 0, index-1); - } - index--; - - mViews[index] = view; - mRoots[index] = root; - mParams[index] = wparams; - } - - // do this last because it fires off messages to start doing things - root.setView(view, wparams, panelParentView); - } - - public void updateViewLayout(View view, ViewGroup.LayoutParams params) { - if (!(params instanceof WindowManager.LayoutParams)) { - throw new IllegalArgumentException("Params must be WindowManager.LayoutParams"); - } - - final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params; - - view.setLayoutParams(wparams); - - synchronized (this) { - int index = findViewLocked(view, true); - ViewRootImpl root = mRoots[index]; - mParams[index] = wparams; - root.setLayoutParams(wparams, false); - } - } - - public void removeView(View view, boolean immediate) { - synchronized (this) { - int index = findViewLocked(view, true); - View curView = removeViewLocked(index, immediate); - if (curView == view) { - return; - } - - throw new IllegalStateException("Calling with view " + view - + " but the ViewAncestor is attached to " + curView); - } - } - - public void closeAll(IBinder token, String who, String what) { - synchronized (this) { - if (mViews == null) - return; - - int count = mViews.length; - //Log.i("foo", "Closing all windows of " + token); - for (int i=0; i<count; i++) { - //Log.i("foo", "@ " + i + " token " + mParams[i].token - // + " view " + mRoots[i].getView()); - if (token == null || mParams[i].token == token) { - ViewRootImpl root = mRoots[i]; - - //Log.i("foo", "Force closing " + root); - if (who != null) { - WindowLeaked leak = new WindowLeaked( - what + " " + who + " has leaked window " - + root.getView() + " that was originally added here"); - leak.setStackTrace(root.getLocation().getStackTrace()); - Log.e(TAG, leak.getMessage(), leak); - } - - removeViewLocked(i, false); - i--; - count--; - } - } - } - } - - private View removeViewLocked(int index, boolean immediate) { - ViewRootImpl root = mRoots[index]; - View view = root.getView(); - - if (view != null) { - InputMethodManager imm = InputMethodManager.getInstance(view.getContext()); - if (imm != null) { - imm.windowDismissed(mViews[index].getWindowToken()); - } - } - root.die(immediate); - - final int count = mViews.length; - - // remove it from the list - View[] tmpViews = new View[count-1]; - removeItem(tmpViews, mViews, index); - mViews = tmpViews; - - ViewRootImpl[] tmpRoots = new ViewRootImpl[count-1]; - removeItem(tmpRoots, mRoots, index); - mRoots = tmpRoots; - - WindowManager.LayoutParams[] tmpParams - = new WindowManager.LayoutParams[count-1]; - removeItem(tmpParams, mParams, index); - mParams = tmpParams; - - if (view != null) { - view.assignParent(null); - // func doesn't allow null... does it matter if we clear them? - //view.setLayoutParams(null); - } - return view; - } - - private static void removeItem(Object[] dst, Object[] src, int index) { - if (dst.length > 0) { - if (index > 0) { - System.arraycopy(src, 0, dst, 0, index); - } - if (index < dst.length) { - System.arraycopy(src, index+1, dst, index, src.length-index-1); - } - } - } - - private int findViewLocked(View view, boolean required) { - synchronized (this) { - if (mViews != null) { - final int count = mViews.length; - for (int i = 0; i < count; i++) { - if (mViews[i] == view) { - return i; - } - } - } - if (required) { - throw new IllegalArgumentException("View not attached to window manager"); - } - return -1; - } - } - - public void startTrimMemory(int level) { - if (HardwareRenderer.isAvailable()) { - // On low-end gfx devices we trim when memory is moderate; - // on high-end devices we do this when low. - if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE - || (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE - && !ActivityManager.isHighEndGfx(mDefaultDisplay))) { - // Destroy all hardware surfaces and resources associated to - // known windows - synchronized (this) { - if (mViews == null) return; - int count = mViews.length; - for (int i = 0; i < count; i++) { - mRoots[i].terminateHardwareResources(); - } - } - // Force a full memory flush - mNeedsEglTerminate = true; - HardwareRenderer.startTrimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE); - return; - } - - HardwareRenderer.startTrimMemory(level); - } - } - - public void endTrimMemory() { - HardwareRenderer.endTrimMemory(); - - if (mNeedsEglTerminate) { - ManagedEGLContext.doTerminate(); - mNeedsEglTerminate = false; - } - } - - public void trimLocalMemory() { - synchronized (this) { - if (mViews == null) return; - int count = mViews.length; - for (int i = 0; i < count; i++) { - mRoots[i].destroyHardwareLayers(); - } - } - } - - public void dumpGfxInfo(FileDescriptor fd) { - FileOutputStream fout = new FileOutputStream(fd); - PrintWriter pw = new PrintWriter(fout); - try { - synchronized (this) { - if (mViews != null) { - final int count = mViews.length; - - pw.println("Profile data in ms:"); - - for (int i = 0; i < count; i++) { - ViewRootImpl root = mRoots[i]; - String name = getWindowName(root); - pw.printf("\n\t%s", name); - - HardwareRenderer renderer = - root.getView().mAttachInfo.mHardwareRenderer; - if (renderer != null) { - renderer.dumpGfxInfo(pw); - } - } - - pw.println("\nView hierarchy:\n"); - - int viewsCount = 0; - int displayListsSize = 0; - int[] info = new int[2]; - - for (int i = 0; i < count; i++) { - ViewRootImpl root = mRoots[i]; - root.dumpGfxInfo(info); - - String name = getWindowName(root); - pw.printf(" %s\n %d views, %.2f kB of display lists", - name, info[0], info[1] / 1024.0f); - HardwareRenderer renderer = - root.getView().mAttachInfo.mHardwareRenderer; - if (renderer != null) { - pw.printf(", %d frames rendered", renderer.getFrameCount()); - } - pw.printf("\n\n"); - - viewsCount += info[0]; - displayListsSize += info[1]; - } - - pw.printf("\nTotal ViewRootImpl: %d\n", count); - pw.printf("Total Views: %d\n", viewsCount); - pw.printf("Total DisplayList: %.2f kB\n\n", displayListsSize / 1024.0f); - } - } - } finally { - pw.flush(); - } - } - - private static String getWindowName(ViewRootImpl root) { - return root.mWindowAttributes.getTitle() + "/" + - root.getClass().getName() + '@' + Integer.toHexString(root.hashCode()); - } - - public void setStoppedState(IBinder token, boolean stopped) { - synchronized (this) { - if (mViews != null) { - int count = mViews.length; - for (int i=0; i < count; i++) { - if (token == null || mParams[i].token == token) { - ViewRootImpl root = mRoots[i]; - root.setStopped(stopped); - } - } - } - } - } - - public void reportNewConfiguration(Configuration config) { - synchronized (this) { - if (mViews != null) { - int count = mViews.length; - config = new Configuration(config); - for (int i=0; i < count; i++) { - ViewRootImpl root = mRoots[i]; - root.requestUpdateConfiguration(config); - } - } - } - } + return mDisplay; } } diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 7aa3bb4..7173d1d 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -390,8 +390,8 @@ public interface WindowManagerPolicy { */ public void switchKeyboardLayout(int deviceId, int direction); - public void shutdown(); - public void rebootSafeMode(); + public void shutdown(boolean confirm); + public void rebootSafeMode(boolean confirm); } /** @@ -487,9 +487,9 @@ public interface WindowManagerPolicy { * * @param attrs The window's LayoutParams. * - * @return {@link WindowManagerImpl#ADD_OKAY} if the add can proceed; + * @return {@link WindowManagerGlobal#ADD_OKAY} if the add can proceed; * else an error code, usually - * {@link WindowManagerImpl#ADD_PERMISSION_DENIED}, to abort the add. + * {@link WindowManagerGlobal#ADD_PERMISSION_DENIED}, to abort the add. */ public int checkAddPermission(WindowManager.LayoutParams attrs); @@ -662,7 +662,7 @@ public interface WindowManagerPolicy { * @param win The window being added. * @param attrs The window's LayoutParams. * - * @return {@link WindowManagerImpl#ADD_OKAY} if the add can proceed, else an + * @return {@link WindowManagerGlobal#ADD_OKAY} if the add can proceed, else an * error code to abort the add. */ public int prepareAddWindowLw(WindowState win, diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java index 193e98d..e8ff01f 100644 --- a/core/java/android/webkit/WebSettings.java +++ b/core/java/android/webkit/WebSettings.java @@ -16,8 +16,7 @@ package android.webkit; -import android.os.Message; -import android.os.Build; +import android.content.Context; /** * Manages settings state for a WebView. When a WebView is first created, it @@ -422,7 +421,7 @@ public abstract class WebSettings { * Gets the text zoom of the page in percent. * * @return the text zoom of the page in percent - * @see #setTextSizeZoom + * @see #setTextZoom */ public synchronized int getTextZoom() { throw new MustOverrideException(); @@ -435,7 +434,7 @@ public abstract class WebSettings { * @deprecated Use {@link #setTextZoom} instead. */ public synchronized void setTextSize(TextSize t) { - throw new MustOverrideException(); + setTextZoom(t.value); } /** @@ -448,7 +447,20 @@ public abstract class WebSettings { * @deprecated Use {@link #getTextZoom} instead. */ public synchronized TextSize getTextSize() { - throw new MustOverrideException(); + TextSize closestSize = null; + int smallestDelta = Integer.MAX_VALUE; + int textSize = getTextZoom(); + for (TextSize size : TextSize.values()) { + int delta = Math.abs(textSize - size.value); + if (delta == 0) { + return size; + } + if (delta < smallestDelta) { + smallestDelta = delta; + closestSize = size; + } + } + return closestSize != null ? closestSize : TextSize.NORMAL; } /** @@ -1226,6 +1238,18 @@ public abstract class WebSettings { } /** + * Returns the default User-Agent used by a WebView. + * An instance of WebView could use a different User-Agent if a call + * is made to {@link WebSettings#setUserAgent(int)} or + * {@link WebSettings#setUserAgentString(String)}. + * + * @param context a Context object used to access application assets + */ + public static String getDefaultUserAgent(Context context) { + return WebViewFactory.getProvider().getStatics().getDefaultUserAgent(context); + } + + /** * Tells the WebView whether it needs to set a node to have focus when * {@link WebView#requestFocus(int, android.graphics.Rect)} is called. The * default value is true. diff --git a/core/java/android/webkit/WebSettingsClassic.java b/core/java/android/webkit/WebSettingsClassic.java index 66651f7..d1f8b4b 100644 --- a/core/java/android/webkit/WebSettingsClassic.java +++ b/core/java/android/webkit/WebSettingsClassic.java @@ -374,6 +374,21 @@ public class WebSettingsClassic extends WebSettings { synchronized(sLockForLocaleSettings) { locale = sLocale; } + return getDefaultUserAgentForLocale(mContext, locale); + } + + /** + * Returns the default User-Agent used by a WebView. + * An instance of WebView could use a different User-Agent if a call + * is made to {@link WebSettings#setUserAgent(int)} or + * {@link WebSettings#setUserAgentString(String)}. + * + * @param context a Context object used to access application assets + * @param locale The Locale to use in the User-Agent string. + * @see WebViewFactoryProvider#getDefaultUserAgent(Context) + * @see WebView#getDefaultUserAgent(Context) + */ + public static String getDefaultUserAgentForLocale(Context context, Locale locale) { StringBuffer buffer = new StringBuffer(); // Add version final String version = Build.VERSION.RELEASE; @@ -417,9 +432,9 @@ public class WebSettingsClassic extends WebSettings { buffer.append(" Build/"); buffer.append(id); } - String mobile = mContext.getResources().getText( + String mobile = context.getResources().getText( com.android.internal.R.string.web_user_agent_target_content).toString(); - final String base = mContext.getResources().getText( + final String base = context.getResources().getText( com.android.internal.R.string.web_user_agent).toString(); return String.format(base, buffer, mobile); } @@ -650,34 +665,6 @@ public class WebSettingsClassic extends WebSettings { } /** - * @see android.webkit.WebSettings#setTextSize(android.webkit.WebSettingsClassic.TextSize) - */ - @Override - public synchronized void setTextSize(TextSize t) { - setTextZoom(t.value); - } - - /** - * @see android.webkit.WebSettings#getTextSize() - */ - @Override - public synchronized TextSize getTextSize() { - TextSize closestSize = null; - int smallestDelta = Integer.MAX_VALUE; - for (TextSize size : TextSize.values()) { - int delta = Math.abs(mTextSize - size.value); - if (delta == 0) { - return size; - } - if (delta < smallestDelta) { - smallestDelta = delta; - closestSize = size; - } - } - return closestSize != null ? closestSize : TextSize.NORMAL; - } - - /** * Set the double-tap zoom of the page in percent. Default is 100. * @param doubleTapZoom A percent value for increasing or decreasing the double-tap zoom. */ diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index a5420bb..436762d 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -1403,7 +1403,6 @@ public class WebView extends AbsoluteLayout * @return the address, or if no address is found, null */ public static String findAddress(String addr) { - checkThread(); return getFactory().getStatics().findAddress(addr); } diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java index 8d79492..9df4852 100644 --- a/core/java/android/webkit/WebViewClassic.java +++ b/core/java/android/webkit/WebViewClassic.java @@ -132,6 +132,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.Vector; @@ -1308,6 +1309,12 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc public WebViewDatabase getWebViewDatabase(Context context) { return WebViewDatabaseClassic.getInstance(context); } + + @Override + public String getDefaultUserAgent(Context context) { + return WebSettingsClassic.getDefaultUserAgentForLocale(context, + Locale.getDefault()); + } } private void onHandleUiEvent(MotionEvent event, int eventType, int flags) { @@ -6441,9 +6448,13 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc mWebViewPrivate.getVerticalScrollFactor()); final int hdelta = (int) (hscroll * mWebViewPrivate.getHorizontalScrollFactor()); - if (pinScrollBy(hdelta, vdelta, false, 0)) { - return true; - } + + abortAnimation(); + int oldTouchMode = mTouchMode; + startScrollingLayer(event.getX(), event.getY()); + doDrag(hdelta, vdelta); + mTouchMode = oldTouchMode; + return true; } } } @@ -7279,11 +7290,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc // nativeCreate sets mNativeClass to a non-zero value String drawableDir = BrowserFrame.getRawResFilename( BrowserFrame.DRAWABLEDIR, mContext); - WindowManager windowManager = - (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); - Display display = windowManager.getDefaultDisplay(); - nativeCreate(msg.arg1, drawableDir, - ActivityManager.isHighEndGfx(display)); + nativeCreate(msg.arg1, drawableDir, ActivityManager.isHighEndGfx()); if (mDelaySetPicture != null) { setNewPicture(mDelaySetPicture, true); mDelaySetPicture = null; diff --git a/core/java/android/webkit/WebViewFactoryProvider.java b/core/java/android/webkit/WebViewFactoryProvider.java index 1d302f1..934ef83 100644 --- a/core/java/android/webkit/WebViewFactoryProvider.java +++ b/core/java/android/webkit/WebViewFactoryProvider.java @@ -42,6 +42,12 @@ public interface WebViewFactoryProvider { * {@link android.webkit.WebView#disablePlatformNotifications()} */ void setPlatformNotificationsEnabled(boolean enable); + + /** + * Implements the API method: + * {@link android.webkit.WebSettings#getDefaultUserAgent(Context) } + */ + String getDefaultUserAgent(Context context); } Statics getStatics(); diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java index 46079f9..f91201a 100644 --- a/core/java/android/widget/CheckedTextView.java +++ b/core/java/android/widget/CheckedTextView.java @@ -151,7 +151,7 @@ public class CheckedTextView extends TextView implements Checkable { mCheckMarkWidth = 0; } mCheckMarkDrawable = d; - // Do padding resolution. This will call setPadding() and do a requestLayout() if needed. + // Do padding resolution. This will call internalSetPadding() and do a requestLayout() if needed. resolvePadding(); } @@ -169,6 +169,19 @@ public class CheckedTextView extends TextView implements Checkable { return mCheckMarkDrawable; } + /** + * @hide + */ + @Override + protected void internalSetPadding(int left, int top, int right, int bottom) { + super.internalSetPadding(left, top, right, bottom); + if (isLayoutRtl()) { + mBasePadding = mUserPaddingLeft; + } else { + mBasePadding = mUserPaddingRight; + } + } + @Override public void onPaddingChanged(int layoutDirection) { int newPadding = (mCheckMarkDrawable != null) ? @@ -221,8 +234,15 @@ public class CheckedTextView extends TextView implements Checkable { final int width = getWidth(); final int top = y; final int bottom = top + height; - final int left = isLayoutRtl ? getPaddingEnd() : width - getPaddingEnd(); - final int right = left + mCheckMarkWidth; + final int left; + final int right; + if (isLayoutRtl) { + right = getPaddingEnd(); + left = right - mCheckMarkWidth; + } else { + left = width - getPaddingEnd(); + right = left + mCheckMarkWidth; + } checkMarkDrawable.setBounds( left, top, right, bottom); checkMarkDrawable.draw(canvas); } diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index dd05a03..dcf90e9 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -61,9 +61,9 @@ import java.util.ArrayList; * the content of the inflated hierarchy. */ public class RemoteViews implements Parcelable, Filter { - + private static final String LOG_TAG = "RemoteViews"; - + /** * The intent extra that contains the appWidgetId. * @hide @@ -71,11 +71,11 @@ public class RemoteViews implements Parcelable, Filter { static final String EXTRA_REMOTEADAPTER_APPWIDGET_ID = "remoteAdapterAppWidgetId"; /** - * The package name of the package containing the layout + * The package name of the package containing the layout * resource. (Added to the parcel) */ private final String mPackage; - + /** * The resource ID of the layout file. (Added to the parcel) */ @@ -86,7 +86,7 @@ public class RemoteViews implements Parcelable, Filter { * inflated */ private ArrayList<Action> mActions; - + /** * A class to keep track of memory usage by this RemoteViews */ @@ -522,13 +522,13 @@ public class RemoteViews implements Parcelable, Filter { .getCompatibilityInfo().applicationScale; final int[] pos = new int[2]; v.getLocationOnScreen(pos); - + final Rect rect = new Rect(); rect.left = (int) (pos[0] * appScale + 0.5f); rect.top = (int) (pos[1] * appScale + 0.5f); rect.right = (int) ((pos[0] + v.getWidth()) * appScale + 0.5f); rect.bottom = (int) ((pos[1] + v.getHeight()) * appScale + 0.5f); - + final Intent intent = new Intent(); intent.setSourceBounds(rect); handler.onClickHandler(v, pendingIntent, intent); @@ -567,7 +567,7 @@ public class RemoteViews implements Parcelable, Filter { this.filterMode = mode; this.level = level; } - + public SetDrawableParameters(Parcel parcel) { viewId = parcel.readInt(); targetBackground = parcel.readInt() != 0; @@ -581,7 +581,7 @@ public class RemoteViews implements Parcelable, Filter { } level = parcel.readInt(); } - + public void writeToParcel(Parcel dest, int flags) { dest.writeInt(TAG); dest.writeInt(viewId); @@ -596,12 +596,12 @@ public class RemoteViews implements Parcelable, Filter { } dest.writeInt(level); } - + @Override public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { final View target = root.findViewById(viewId); if (target == null) return; - + // Pick the correct drawable to modify for this view Drawable targetDrawable = null; if (targetBackground) { @@ -610,7 +610,7 @@ public class RemoteViews implements Parcelable, Filter { ImageView imageView = (ImageView) target; targetDrawable = imageView.getDrawable(); } - + if (targetDrawable != null) { // Perform modifications only if values are set correctly if (alpha != -1) { @@ -634,7 +634,7 @@ public class RemoteViews implements Parcelable, Filter { public final static int TAG = 3; } - + private class ReflectionActionWithoutParams extends Action { int viewId; String methodName; @@ -938,7 +938,7 @@ public class RemoteViews implements Parcelable, Filter { out.writeString((String)this.value); break; case CHAR_SEQUENCE: - TextUtils.writeToParcel((CharSequence)this.value, out, flags); + TextUtils.writeToParcel((CharSequence)this.value, out, flags); break; case URI: out.writeInt(this.value != null ? 1 : 0); @@ -1314,7 +1314,7 @@ public class RemoteViews implements Parcelable, Filter { /** * Create a new RemoteViews object that will display the views contained * in the specified layout file. - * + * * @param packageName Name of the package that contains the layout resource * @param layoutId The id of the layout resource */ @@ -1364,7 +1364,7 @@ public class RemoteViews implements Parcelable, Filter { /** * Reads a RemoteViews object from a parcel. - * + * * @param parcel */ public RemoteViews(Parcel parcel) { @@ -1547,7 +1547,7 @@ public class RemoteViews implements Parcelable, Filter { /** * Add an action to be executed on the remote side when apply is called. - * + * * @param a The action to add */ private void addAction(Action a) { @@ -1619,7 +1619,7 @@ public class RemoteViews implements Parcelable, Filter { /** * Equivalent to calling View.setVisibility - * + * * @param viewId The id of the view whose visibility should change * @param visibility The new visibility for the view */ @@ -1629,7 +1629,7 @@ public class RemoteViews implements Parcelable, Filter { /** * Equivalent to calling TextView.setText - * + * * @param viewId The id of the view whose text should change * @param text The new text for the view */ @@ -1639,7 +1639,7 @@ public class RemoteViews implements Parcelable, Filter { /** * Equivalent to calling {@link TextView#setTextSize(int, float)} - * + * * @param viewId The id of the view whose text size should change * @param units The units of size (e.g. COMPLEX_UNIT_SP) * @param size The size of the text @@ -1649,33 +1649,29 @@ public class RemoteViews implements Parcelable, Filter { } /** - * Equivalent to calling + * Equivalent to calling * {@link TextView#setCompoundDrawablesWithIntrinsicBounds(int, int, int, int)}. * * @param viewId The id of the view whose text should change * @param left The id of a drawable to place to the left of the text, or 0 * @param top The id of a drawable to place above the text, or 0 * @param right The id of a drawable to place to the right of the text, or 0 - * @param bottom The id of a drawable to place below the text, or 0 + * @param bottom The id of a drawable to place below the text, or 0 */ public void setTextViewCompoundDrawables(int viewId, int left, int top, int right, int bottom) { addAction(new TextViewDrawableAction(viewId, false, left, top, right, bottom)); } /** - * Equivalent to calling {@link + * Equivalent to calling {@link * TextView#setCompoundDrawablesRelativeWithIntrinsicBounds(int, int, int, int)}. * * @param viewId The id of the view whose text should change - * @param start The id of a drawable to place before the text (relative to the + * @param start The id of a drawable to place before the text (relative to the * layout direction), or 0 * @param top The id of a drawable to place above the text, or 0 * @param end The id of a drawable to place after the text, or 0 -<<<<<<< HEAD - * @param bottom The id of a drawable to place below the text, or 0 -======= * @param bottom The id of a drawable to place below the text, or 0 ->>>>>>> 0a43f67e */ public void setTextViewCompoundDrawablesRelative(int viewId, int start, int top, int end, int bottom) { addAction(new TextViewDrawableAction(viewId, true, start, top, end, bottom)); @@ -1683,17 +1679,17 @@ public class RemoteViews implements Parcelable, Filter { /** * Equivalent to calling ImageView.setImageResource - * + * * @param viewId The id of the view whose drawable should change * @param srcId The new resource id for the drawable */ - public void setImageViewResource(int viewId, int srcId) { + public void setImageViewResource(int viewId, int srcId) { setInt(viewId, "setImageResource", srcId); } /** * Equivalent to calling ImageView.setImageURI - * + * * @param viewId The id of the view whose drawable should change * @param uri The Uri for the image */ @@ -1703,7 +1699,7 @@ public class RemoteViews implements Parcelable, Filter { /** * Equivalent to calling ImageView.setImageBitmap - * + * * @param viewId The id of the view whose bitmap should change * @param bitmap The new Bitmap for the drawable */ @@ -1726,7 +1722,7 @@ public class RemoteViews implements Parcelable, Filter { * {@link Chronometer#setFormat Chronometer.setFormat}, * and {@link Chronometer#start Chronometer.start()} or * {@link Chronometer#stop Chronometer.stop()}. - * + * * @param viewId The id of the {@link Chronometer} to change * @param base The time at which the timer would have read 0:00. This * time should be based off of @@ -1740,21 +1736,21 @@ public class RemoteViews implements Parcelable, Filter { setString(viewId, "setFormat", format); setBoolean(viewId, "setStarted", started); } - + /** * Equivalent to calling {@link ProgressBar#setMax ProgressBar.setMax}, * {@link ProgressBar#setProgress ProgressBar.setProgress}, and * {@link ProgressBar#setIndeterminate ProgressBar.setIndeterminate} * * If indeterminate is true, then the values for max and progress are ignored. - * + * * @param viewId The id of the {@link ProgressBar} to change * @param max The 100% value for the progress bar * @param progress The current value of the progress bar. - * @param indeterminate True if the progress bar is indeterminate, + * @param indeterminate True if the progress bar is indeterminate, * false if not. */ - public void setProgressBar(int viewId, int max, int progress, + public void setProgressBar(int viewId, int max, int progress, boolean indeterminate) { setBoolean(viewId, "setIndeterminate", indeterminate); if (!indeterminate) { @@ -1762,12 +1758,12 @@ public class RemoteViews implements Parcelable, Filter { setInt(viewId, "setProgress", progress); } } - + /** * Equivalent to calling * {@link android.view.View#setOnClickListener(android.view.View.OnClickListener)} * to launch the provided {@link PendingIntent}. - * + * * When setting the on-click action of items within collections (eg. {@link ListView}, * {@link StackView} etc.), this method will not work. Instead, use {@link * RemoteViews#setPendingIntentTemplate(int, PendingIntent) in conjunction with @@ -1827,7 +1823,7 @@ public class RemoteViews implements Parcelable, Filter { * view. * <p> * You can omit specific calls by marking their values with null or -1. - * + * * @param viewId The id of the view that contains the target * {@link Drawable} * @param targetBackground If true, apply these parameters to the @@ -1853,7 +1849,7 @@ public class RemoteViews implements Parcelable, Filter { /** * Equivalent to calling {@link android.widget.TextView#setTextColor(int)}. - * + * * @param viewId The id of the view whose text color should change * @param color Sets the text color for all the states (normal, selected, * focused) to be this color. @@ -2105,16 +2101,16 @@ public class RemoteViews implements Parcelable, Filter { /** * Inflates the view hierarchy represented by this object and applies * all of the actions. - * + * * <p><strong>Caller beware: this may throw</strong> - * + * * @param context Default context to use * @param parent Parent that the resulting view hierarchy will be attached to. This method * does <strong>not</strong> attach the hierarchy. The caller should do so when appropriate. * @return The inflated view hierarchy */ public View apply(Context context, ViewGroup parent) { - return apply(context, parent, DEFAULT_ON_CLICK_HANDLER); + return apply(context, parent, null); } /** @hide */ @@ -2142,12 +2138,12 @@ public class RemoteViews implements Parcelable, Filter { * Applies all of the actions to the provided view. * * <p><strong>Caller beware: this may throw</strong> - * + * * @param v The view to apply the actions to. This should be the result of * the {@link #apply(Context,ViewGroup)} call. */ public void reapply(Context context, View v) { - reapply(context, v, DEFAULT_ON_CLICK_HANDLER); + reapply(context, v, null); } /** @hide */ @@ -2170,6 +2166,7 @@ public class RemoteViews implements Parcelable, Filter { private void performApply(View v, ViewGroup parent, OnClickHandler handler) { if (mActions != null) { + handler = handler == null ? DEFAULT_ON_CLICK_HANDLER : handler; final int count = mActions.size(); for (int i = 0; i < count; i++) { Action a = mActions.get(i); @@ -2198,7 +2195,7 @@ public class RemoteViews implements Parcelable, Filter { /* (non-Javadoc) * Used to restrict the views which can be inflated - * + * * @see android.view.LayoutInflater.Filter#onLoadClass(java.lang.Class) */ public boolean onLoadClass(Class clazz) { diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java index 5d6491d..1f713d4 100644 --- a/core/java/android/widget/Switch.java +++ b/core/java/android/widget/Switch.java @@ -664,7 +664,7 @@ public class Switch extends CompoundButton { @Override public void setChecked(boolean checked) { super.setChecked(checked); - setThumbPosition(checked); + setThumbPosition(isChecked()); invalidate(); } diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java index 8bb9348..238dc55 100644 --- a/core/java/android/widget/TabHost.java +++ b/core/java/android/widget/TabHost.java @@ -48,6 +48,10 @@ import java.util.List; */ public class TabHost extends FrameLayout implements ViewTreeObserver.OnTouchModeChangeListener { + private static final int TABWIDGET_LOCATION_LEFT = 0; + private static final int TABWIDGET_LOCATION_TOP = 1; + private static final int TABWIDGET_LOCATION_RIGHT = 2; + private static final int TABWIDGET_LOCATION_BOTTOM = 3; private TabWidget mTabWidget; private FrameLayout mTabContent; private List<TabSpec> mTabSpecs = new ArrayList<TabSpec>(2); @@ -293,22 +297,73 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1"); return mTabContent; } + /** + * Get the location of the TabWidget. + * + * @return The TabWidget location. + */ + private int getTabWidgetLocation() { + int location = TABWIDGET_LOCATION_TOP; + + switch (mTabWidget.getOrientation()) { + case LinearLayout.VERTICAL: + location = (mTabContent.getLeft() < mTabWidget.getLeft()) ? TABWIDGET_LOCATION_RIGHT + : TABWIDGET_LOCATION_LEFT; + break; + case LinearLayout.HORIZONTAL: + default: + location = (mTabContent.getTop() < mTabWidget.getTop()) ? TABWIDGET_LOCATION_BOTTOM + : TABWIDGET_LOCATION_TOP; + break; + } + return location; + } + @Override public boolean dispatchKeyEvent(KeyEvent event) { final boolean handled = super.dispatchKeyEvent(event); - // unhandled key ups change focus to tab indicator for embedded activities - // when there is nothing that will take focus from default focus searching + // unhandled key events change focus to tab indicator for embedded + // activities when there is nothing that will take focus from default + // focus searching if (!handled && (event.getAction() == KeyEvent.ACTION_DOWN) - && (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP) && (mCurrentView != null) && (mCurrentView.isRootNamespace()) - && (mCurrentView.hasFocus()) - && (mCurrentView.findFocus().focusSearch(View.FOCUS_UP) == null)) { - mTabWidget.getChildTabViewAt(mCurrentTab).requestFocus(); - playSoundEffect(SoundEffectConstants.NAVIGATION_UP); - return true; + && (mCurrentView.hasFocus())) { + int keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_UP; + int directionShouldChangeFocus = View.FOCUS_UP; + int soundEffect = SoundEffectConstants.NAVIGATION_UP; + + switch (getTabWidgetLocation()) { + case TABWIDGET_LOCATION_LEFT: + keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_LEFT; + directionShouldChangeFocus = View.FOCUS_LEFT; + soundEffect = SoundEffectConstants.NAVIGATION_LEFT; + break; + case TABWIDGET_LOCATION_RIGHT: + keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_RIGHT; + directionShouldChangeFocus = View.FOCUS_RIGHT; + soundEffect = SoundEffectConstants.NAVIGATION_RIGHT; + break; + case TABWIDGET_LOCATION_BOTTOM: + keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_DOWN; + directionShouldChangeFocus = View.FOCUS_DOWN; + soundEffect = SoundEffectConstants.NAVIGATION_DOWN; + break; + case TABWIDGET_LOCATION_TOP: + default: + keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_UP; + directionShouldChangeFocus = View.FOCUS_UP; + soundEffect = SoundEffectConstants.NAVIGATION_UP; + break; + } + if (event.getKeyCode() == keyCodeShouldChangeFocus + && mCurrentView.findFocus().focusSearch(directionShouldChangeFocus) == null) { + mTabWidget.getChildTabViewAt(mCurrentTab).requestFocus(); + playSoundEffect(soundEffect); + return true; + } } return handled; } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 5be9899..f502de4 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -2203,6 +2203,27 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } /** + * Get the default {@link Locale} of the text in this TextView. + * @return the default {@link Locale} of the text in this TextView. + */ + public Locale getTextLocale() { + return mTextPaint.getTextLocale(); + } + + /** + * Set the default {@link Locale} of the text in this TextView to the given value. This value + * is used to choose appropriate typefaces for ambiguous characters. Typically used for CJK + * locales to disambiguate Hanzi/Kanji/Hanja characters. + * + * @param locale the {@link Locale} for drawing text, must not be null. + * + * @see Paint#setTextLocale + */ + public void setTextLocale(Locale locale) { + mTextPaint.setTextLocale(locale); + } + + /** * @return the size (in pixels) of the default text size in this TextView. */ @ViewDebug.ExportedProperty(category = "text") diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java index 7dcbc3e..053ade7 100644 --- a/core/java/android/widget/Toast.java +++ b/core/java/android/widget/Toast.java @@ -30,7 +30,6 @@ import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; -import android.view.WindowManagerImpl; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; @@ -331,7 +330,7 @@ public class Toast { View mView; View mNextView; - WindowManagerImpl mWM; + WindowManager mWM; TN() { // XXX This should be changed to use a Dialog, with a Theme.Toast @@ -371,7 +370,7 @@ public class Toast { // remove the old view if necessary handleHide(); mView = mNextView; - mWM = WindowManagerImpl.getDefault(); + mWM = (WindowManager)mView.getContext().getSystemService(Context.WINDOW_SERVICE); // We can resolve the Gravity here by using the Locale for getting // the layout direction final Configuration config = mView.getContext().getResources().getConfiguration(); diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index e63c57f..bffbe11 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -150,7 +150,8 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte resizeGrid(); } else if (count == 1) { - startActivity(mAdapter.intentForPosition(0)); + startActivityAsUser(mAdapter.intentForPosition(0), + new UserHandle(UserHandle.getUserId(mLaunchedFromUid))); mPackageMonitor.unregister(); mRegistered = false; finish(); @@ -363,12 +364,12 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte if (r.match > bestMatch) bestMatch = r.match; } getPackageManager().addPreferredActivity(filter, bestMatch, set, - intent.getComponent()); + intent.getComponent(), UserHandle.getUserId(mLaunchedFromUid)); } } if (intent != null) { - startActivity(intent); + startActivityAsUser(intent, new UserHandle(UserHandle.getUserId(mLaunchedFromUid))); } } @@ -376,7 +377,7 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte Intent in = new Intent().setAction("android.settings.APPLICATION_DETAILS_SETTINGS") .setData(Uri.fromParts("package", ri.activityInfo.packageName, null)) .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); - startActivity(in); + startActivityAsUser(in, new UserHandle(UserHandle.getUserId(mLaunchedFromUid))); } private final class DisplayResolveInfo { diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index b016e99..1e268c4 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -18,16 +18,14 @@ package com.android.internal.os; import android.net.Credentials; import android.net.LocalSocket; -import android.os.Build; import android.os.Process; +import android.os.SELinux; import android.os.SystemProperties; import android.util.Log; import dalvik.system.PathClassLoader; import dalvik.system.Zygote; -import android.os.SELinux; - import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -234,9 +232,9 @@ class ZygoteConnection { ZygoteInit.setCloseOnExec(serverPipeFd, true); } - pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, - parsedArgs.gids, parsedArgs.debugFlags, rlimits, - parsedArgs.seInfo, parsedArgs.niceName); + pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, + parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo, + parsedArgs.niceName); } catch (IOException ex) { logAndPrintError(newStderr, "Exception creating pipe", ex); } catch (ErrnoException ex) { @@ -341,6 +339,9 @@ class ZygoteConnection { */ int debugFlags; + /** From --mount-external */ + int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; + /** from --target-sdk-version. */ int targetSdkVersion; boolean targetSdkVersionSpecified; @@ -526,6 +527,10 @@ class ZygoteConnection { "Duplicate arg specified"); } niceName = arg.substring(arg.indexOf('=') + 1); + } else if (arg.equals("--mount-external-singleuser")) { + mountExternal = Zygote.MOUNT_EXTERNAL_SINGLEUSER; + } else if (arg.equals("--mount-external-multiuser")) { + mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; } else { break; } diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 6ad67c3..9e43749 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -16,16 +16,17 @@ package com.android.internal.os; +import static libcore.io.OsConstants.S_IRWXG; +import static libcore.io.OsConstants.S_IRWXO; + import android.content.pm.ActivityInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; import android.net.LocalServerSocket; import android.os.Debug; -import android.os.FileUtils; import android.os.Process; import android.os.SystemClock; -import android.os.SystemProperties; import android.util.EventLog; import android.util.Log; @@ -33,6 +34,7 @@ import dalvik.system.VMRuntime; import dalvik.system.Zygote; import libcore.io.IoUtils; +import libcore.io.Libcore; import java.io.BufferedReader; import java.io.FileDescriptor; @@ -452,7 +454,7 @@ public class ZygoteInit { closeServerSocket(); // set umask to 0077 so new files and directories will default to owner-only permissions. - FileUtils.setUMask(FileUtils.S_IRWXG | FileUtils.S_IRWXO); + Libcore.os.umask(S_IRWXG | S_IRWXO); if (parsedArgs.niceName != null) { Process.setArgV0(parsedArgs.niceName); diff --git a/core/java/com/android/internal/view/RotationPolicy.java b/core/java/com/android/internal/view/RotationPolicy.java index af512a3..98beadb 100644 --- a/core/java/com/android/internal/view/RotationPolicy.java +++ b/core/java/com/android/internal/view/RotationPolicy.java @@ -27,6 +27,7 @@ import android.provider.Settings; import android.util.Log; import android.view.IWindowManager; import android.view.Surface; +import android.view.WindowManagerGlobal; /** * Provides helper functions for configuring the display rotation policy. @@ -79,8 +80,7 @@ public final class RotationPolicy { @Override public void run() { try { - IWindowManager wm = IWindowManager.Stub.asInterface( - ServiceManager.getService(Context.WINDOW_SERVICE)); + IWindowManager wm = WindowManagerGlobal.getWindowManagerService(); if (enabled) { wm.freezeRotation(-1); } else { @@ -107,8 +107,7 @@ public final class RotationPolicy { @Override public void run() { try { - IWindowManager wm = IWindowManager.Stub.asInterface( - ServiceManager.getService(Context.WINDOW_SERVICE)); + IWindowManager wm = WindowManagerGlobal.getWindowManagerService(); if (enabled) { wm.freezeRotation(Surface.ROTATION_0); } else { diff --git a/core/jni/Android.mk b/core/jni/Android.mk index b1423ca..f950d3d 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -67,7 +67,6 @@ LOCAL_SRC_FILES:= \ android_os_ParcelFileDescriptor.cpp \ android_os_Parcel.cpp \ android_os_SELinux.cpp \ - android_os_StatFs.cpp \ android_os_SystemClock.cpp \ android_os_SystemProperties.cpp \ android_os_Trace.cpp \ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index c936b0b..0c88297 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -134,7 +134,6 @@ extern int register_android_os_MessageQueue(JNIEnv* env); extern int register_android_os_Parcel(JNIEnv* env); extern int register_android_os_ParcelFileDescriptor(JNIEnv *env); extern int register_android_os_SELinux(JNIEnv* env); -extern int register_android_os_StatFs(JNIEnv *env); extern int register_android_os_SystemProperties(JNIEnv *env); extern int register_android_os_SystemClock(JNIEnv* env); extern int register_android_os_Trace(JNIEnv* env); @@ -1142,7 +1141,6 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_os_MessageQueue), REG_JNI(register_android_os_ParcelFileDescriptor), REG_JNI(register_android_os_SELinux), - REG_JNI(register_android_os_StatFs), REG_JNI(register_android_os_Trace), REG_JNI(register_android_os_UEventObserver), REG_JNI(register_android_net_LocalSocketImpl), diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp index a65262c..edc9732 100644 --- a/core/jni/android/graphics/Paint.cpp +++ b/core/jni/android/graphics/Paint.cpp @@ -22,6 +22,7 @@ #include "jni.h" #include "GraphicsJNI.h" #include <android_runtime/AndroidRuntime.h> +#include <ScopedUtfChars.h> #include "SkBlurDrawLooper.h" #include "SkColorFilter.h" @@ -30,6 +31,7 @@ #include "SkShader.h" #include "SkTypeface.h" #include "SkXfermode.h" +#include "unicode/uloc.h" #include "unicode/ushape.h" #include "TextLayout.h" @@ -254,11 +256,51 @@ public: obj->setTextAlign(align); } + // generate bcp47 identifier for the supplied locale + static void toLanguageTag(char* output, size_t outSize, + const char* locale) { + if (output == NULL || outSize <= 0) { + return; + } + if (locale == NULL) { + output[0] = '\0'; + return; + } + char canonicalChars[ULOC_FULLNAME_CAPACITY]; + UErrorCode uErr = U_ZERO_ERROR; + uloc_canonicalize(locale, canonicalChars, ULOC_FULLNAME_CAPACITY, + &uErr); + if (U_SUCCESS(uErr)) { + char likelyChars[ULOC_FULLNAME_CAPACITY]; + uErr = U_ZERO_ERROR; + uloc_addLikelySubtags(canonicalChars, likelyChars, + ULOC_FULLNAME_CAPACITY, &uErr); + if (U_SUCCESS(uErr)) { + uErr = U_ZERO_ERROR; + uloc_toLanguageTag(likelyChars, output, outSize, FALSE, &uErr); + if (U_SUCCESS(uErr)) { + return; + } else { + ALOGD("uloc_toLanguageTag(\"%s\") failed: %s", likelyChars, + u_errorName(uErr)); + } + } else { + ALOGD("uloc_addLikelySubtags(\"%s\") failed: %s", + canonicalChars, u_errorName(uErr)); + } + } else { + ALOGD("uloc_canonicalize(\"%s\") failed: %s", locale, + u_errorName(uErr)); + } + // unable to build a proper language identifier + output[0] = '\0'; + } + static void setTextLocale(JNIEnv* env, jobject clazz, SkPaint* obj, jstring locale) { - const char* localeArray = env->GetStringUTFChars(locale, NULL); - SkString skLocale(localeArray); - obj->setTextLocale(skLocale); - env->ReleaseStringUTFChars(locale, localeArray); + ScopedUtfChars localeChars(env, locale); + char langTag[ULOC_FULLNAME_CAPACITY]; + toLanguageTag(langTag, ULOC_FULLNAME_CAPACITY, localeChars.c_str()); + obj->setLanguage(SkLanguage(langTag)); } static jfloat getTextSize(JNIEnv* env, jobject paint) { diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp index 9b9b991..7abfcf1 100644 --- a/core/jni/android/graphics/TextLayoutCache.cpp +++ b/core/jni/android/graphics/TextLayoutCache.cpp @@ -19,6 +19,7 @@ #include "TextLayoutCache.h" #include "TextLayout.h" #include "SkFontHost.h" +#include "SkTypeface_android.h" #include <unicode/unistr.h> #include <unicode/normlzr.h> #include <unicode/uchar.h> @@ -224,7 +225,7 @@ void TextLayoutCache::dumpCacheStats() { */ TextLayoutCacheKey::TextLayoutCacheKey(): text(NULL), start(0), count(0), contextCount(0), dirFlags(0), typeface(NULL), textSize(0), textSkewX(0), textScaleX(0), flags(0), - hinting(SkPaint::kNo_Hinting) { + hinting(SkPaint::kNo_Hinting), variant(SkPaint::kDefault_Variant), language() { } TextLayoutCacheKey::TextLayoutCacheKey(const SkPaint* paint, const UChar* text, @@ -237,6 +238,8 @@ TextLayoutCacheKey::TextLayoutCacheKey(const SkPaint* paint, const UChar* text, textScaleX = paint->getTextScaleX(); flags = paint->getFlags(); hinting = paint->getHinting(); + variant = paint->getFontVariant(); + language = paint->getLanguage(); } TextLayoutCacheKey::TextLayoutCacheKey(const TextLayoutCacheKey& other) : @@ -251,7 +254,9 @@ TextLayoutCacheKey::TextLayoutCacheKey(const TextLayoutCacheKey& other) : textSkewX(other.textSkewX), textScaleX(other.textScaleX), flags(other.flags), - hinting(other.hinting) { + hinting(other.hinting), + variant(other.variant), + language(other.language) { if (other.text) { textCopy.setTo(other.text, other.contextCount); } @@ -288,6 +293,12 @@ 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; + return memcmp(lhs.getText(), rhs.getText(), lhs.contextCount * sizeof(UChar)); } @@ -615,6 +626,8 @@ void TextLayoutShaper::computeRunValues(const SkPaint* paint, const UChar* chars mShapingPaint.setTextScaleX(paint->getTextScaleX()); mShapingPaint.setFlags(paint->getFlags()); mShapingPaint.setHinting(paint->getHinting()); + mShapingPaint.setFontVariant(paint->getFontVariant()); + mShapingPaint.setLanguage(paint->getLanguage()); // Split the BiDi run into Script runs. Harfbuzz will populate the pos, length and script // into the shaperItem diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h index f007f9a..64b33a0 100644 --- a/core/jni/android/graphics/TextLayoutCache.h +++ b/core/jni/android/graphics/TextLayoutCache.h @@ -32,7 +32,7 @@ #include <SkTemplates.h> #include <SkUtils.h> #include <SkAutoKern.h> -#include "SkTypeface_android.h" +#include <SkLanguage.h> #include <unicode/ubidi.h> #include <unicode/ushape.h> @@ -102,6 +102,8 @@ private: SkScalar textScaleX; uint32_t flags; SkPaint::Hinting hinting; + SkPaint::FontVariant variant; + SkLanguage language; inline const UChar* getText() const { return text ? text : textCopy.string(); } diff --git a/core/jni/android_os_FileUtils.cpp b/core/jni/android_os_FileUtils.cpp index 8d65cbc..a07f5b7 100644 --- a/core/jni/android_os_FileUtils.cpp +++ b/core/jni/android_os_FileUtils.cpp @@ -33,19 +33,6 @@ namespace android { -static jfieldID gFileStatusDevFieldID; -static jfieldID gFileStatusInoFieldID; -static jfieldID gFileStatusModeFieldID; -static jfieldID gFileStatusNlinkFieldID; -static jfieldID gFileStatusUidFieldID; -static jfieldID gFileStatusGidFieldID; -static jfieldID gFileStatusSizeFieldID; -static jfieldID gFileStatusBlksizeFieldID; -static jfieldID gFileStatusBlocksFieldID; -static jfieldID gFileStatusAtimeFieldID; -static jfieldID gFileStatusMtimeFieldID; -static jfieldID gFileStatusCtimeFieldID; - jint android_os_FileUtils_setPermissions(JNIEnv* env, jobject clazz, jstring file, jint mode, jint uid, jint gid) @@ -68,44 +55,6 @@ jint android_os_FileUtils_setPermissions(JNIEnv* env, jobject clazz, return chmod(file8.string(), mode) == 0 ? 0 : errno; } -jint android_os_FileUtils_getPermissions(JNIEnv* env, jobject clazz, - jstring file, jintArray outArray) -{ - const jchar* str = env->GetStringCritical(file, 0); - String8 file8; - if (str) { - file8 = String8(str, env->GetStringLength(file)); - env->ReleaseStringCritical(file, str); - } - if (file8.size() <= 0) { - return ENOENT; - } - struct stat st; - if (stat(file8.string(), &st) != 0) { - return errno; - } - jint* array = (jint*)env->GetPrimitiveArrayCritical(outArray, 0); - if (array) { - int len = env->GetArrayLength(outArray); - if (len >= 1) { - array[0] = st.st_mode; - } - if (len >= 2) { - array[1] = st.st_uid; - } - if (len >= 3) { - array[2] = st.st_gid; - } - } - env->ReleasePrimitiveArrayCritical(outArray, array, 0); - return 0; -} - -jint android_os_FileUtils_setUMask(JNIEnv* env, jobject clazz, jint mask) -{ - return umask(mask); -} - jint android_os_FileUtils_getFatVolumeId(JNIEnv* env, jobject clazz, jstring path) { if (path == NULL) { @@ -127,63 +76,15 @@ jint android_os_FileUtils_getFatVolumeId(JNIEnv* env, jobject clazz, jstring pat return result; } -jboolean android_os_FileUtils_getFileStatus(JNIEnv* env, jobject clazz, jstring path, jobject fileStatus) { - const char* pathStr = env->GetStringUTFChars(path, NULL); - jboolean ret = false; - - struct stat s; - int res = stat(pathStr, &s); - if (res == 0) { - ret = true; - if (fileStatus != NULL) { - env->SetIntField(fileStatus, gFileStatusDevFieldID, s.st_dev); - env->SetIntField(fileStatus, gFileStatusInoFieldID, s.st_ino); - env->SetIntField(fileStatus, gFileStatusModeFieldID, s.st_mode); - env->SetIntField(fileStatus, gFileStatusNlinkFieldID, s.st_nlink); - env->SetIntField(fileStatus, gFileStatusUidFieldID, s.st_uid); - env->SetIntField(fileStatus, gFileStatusGidFieldID, s.st_gid); - env->SetLongField(fileStatus, gFileStatusSizeFieldID, s.st_size); - env->SetIntField(fileStatus, gFileStatusBlksizeFieldID, s.st_blksize); - env->SetLongField(fileStatus, gFileStatusBlocksFieldID, s.st_blocks); - env->SetLongField(fileStatus, gFileStatusAtimeFieldID, s.st_atime); - env->SetLongField(fileStatus, gFileStatusMtimeFieldID, s.st_mtime); - env->SetLongField(fileStatus, gFileStatusCtimeFieldID, s.st_ctime); - } - } - - env->ReleaseStringUTFChars(path, pathStr); - - return ret; -} - static const JNINativeMethod methods[] = { {"setPermissions", "(Ljava/lang/String;III)I", (void*)android_os_FileUtils_setPermissions}, - {"getPermissions", "(Ljava/lang/String;[I)I", (void*)android_os_FileUtils_getPermissions}, - {"setUMask", "(I)I", (void*)android_os_FileUtils_setUMask}, {"getFatVolumeId", "(Ljava/lang/String;)I", (void*)android_os_FileUtils_getFatVolumeId}, - {"getFileStatusNative", "(Ljava/lang/String;Landroid/os/FileUtils$FileStatus;)Z", (void*)android_os_FileUtils_getFileStatus}, }; static const char* const kFileUtilsPathName = "android/os/FileUtils"; int register_android_os_FileUtils(JNIEnv* env) { - jclass fileStatusClass = env->FindClass("android/os/FileUtils$FileStatus"); - LOG_FATAL_IF(fileStatusClass == NULL, "Unable to find class android.os.FileUtils$FileStatus"); - - gFileStatusDevFieldID = env->GetFieldID(fileStatusClass, "dev", "I"); - gFileStatusInoFieldID = env->GetFieldID(fileStatusClass, "ino", "I"); - gFileStatusModeFieldID = env->GetFieldID(fileStatusClass, "mode", "I"); - gFileStatusNlinkFieldID = env->GetFieldID(fileStatusClass, "nlink", "I"); - gFileStatusUidFieldID = env->GetFieldID(fileStatusClass, "uid", "I"); - gFileStatusGidFieldID = env->GetFieldID(fileStatusClass, "gid", "I"); - gFileStatusSizeFieldID = env->GetFieldID(fileStatusClass, "size", "J"); - gFileStatusBlksizeFieldID = env->GetFieldID(fileStatusClass, "blksize", "I"); - gFileStatusBlocksFieldID = env->GetFieldID(fileStatusClass, "blocks", "J"); - gFileStatusAtimeFieldID = env->GetFieldID(fileStatusClass, "atime", "J"); - gFileStatusMtimeFieldID = env->GetFieldID(fileStatusClass, "mtime", "J"); - gFileStatusCtimeFieldID = env->GetFieldID(fileStatusClass, "ctime", "J"); - return AndroidRuntime::registerNativeMethods( env, kFileUtilsPathName, methods, NELEM(methods)); diff --git a/core/jni/android_os_SELinux.cpp b/core/jni/android_os_SELinux.cpp index 40443ff..e813c38 100644 --- a/core/jni/android_os_SELinux.cpp +++ b/core/jni/android_os_SELinux.cpp @@ -1,3 +1,19 @@ +/* + * 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. + */ + #define LOG_TAG "SELinuxJNI" #include <utils/Log.h> @@ -6,6 +22,7 @@ #include "android_runtime/AndroidRuntime.h" #ifdef HAVE_SELINUX #include "selinux/selinux.h" +#include "selinux/android.h" #endif #include <errno.h> @@ -458,6 +475,27 @@ namespace android { } /* + * Function: native_restorecon + * Purpose: restore default SELinux security context + * Parameters: pathname: the pathname for the file to be relabeled + * Returns: boolean: (true) file label successfully restored, (false) otherwise + * Exceptions: none + */ + static jboolean native_restorecon(JNIEnv *env, jobject clazz, jstring pathname) { +#ifdef HAVE_SELINUX + if (isSELinuxDisabled) + return true; + + const char *file = const_cast<char *>(env->GetStringUTFChars(pathname, NULL)); + int ret = selinux_android_restorecon(file); + env->ReleaseStringUTFChars(pathname, file); + return (ret == 0); +#else + return true; +#endif + } + + /* * JNI registration. */ static JNINativeMethod method_table[] = { @@ -472,6 +510,7 @@ namespace android { { "getPidContext" , "(I)Ljava/lang/String;" , (void*)getPidCon }, { "isSELinuxEnforced" , "()Z" , (void*)isSELinuxEnforced}, { "isSELinuxEnabled" , "()Z" , (void*)isSELinuxEnabled }, + { "native_restorecon" , "(Ljava/lang/String;)Z" , (void*)native_restorecon}, { "setBooleanValue" , "(Ljava/lang/String;Z)Z" , (void*)setBooleanValue }, { "setFileContext" , "(Ljava/lang/String;Ljava/lang/String;)Z" , (void*)setFileCon }, { "setFSCreateContext" , "(Ljava/lang/String;)Z" , (void*)setFSCreateCon }, diff --git a/core/jni/android_os_StatFs.cpp b/core/jni/android_os_StatFs.cpp deleted file mode 100644 index 79d8fef..0000000 --- a/core/jni/android_os_StatFs.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2007, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if INCLUDE_SYS_MOUNT_FOR_STATFS -#include <sys/mount.h> -#else -#include <sys/statfs.h> -#endif - -#include <errno.h> - -#include "jni.h" -#include "JNIHelp.h" -#include "android_runtime/AndroidRuntime.h" - - -namespace android -{ - -// ---------------------------------------------------------------------------- - -struct fields_t { - jfieldID context; -}; -static fields_t fields; - -// ---------------------------------------------------------------------------- - -static jint -android_os_StatFs_getBlockSize(JNIEnv *env, jobject thiz) -{ - struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context); - return stat->f_bsize; -} - -static jint -android_os_StatFs_getBlockCount(JNIEnv *env, jobject thiz) -{ - struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context); - return stat->f_blocks; -} - -static jint -android_os_StatFs_getFreeBlocks(JNIEnv *env, jobject thiz) -{ - struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context); - return stat->f_bfree; -} - -static jint -android_os_StatFs_getAvailableBlocks(JNIEnv *env, jobject thiz) -{ - struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context); - return stat->f_bavail; -} - -static void -android_os_StatFs_native_restat(JNIEnv *env, jobject thiz, jstring path) -{ - if (path == NULL) { - jniThrowException(env, "java/lang/IllegalArgumentException", NULL); - return; - } - - // get the object handle - struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context); - if (stat == NULL) { - jniThrowException(env, "java/lang/NoSuchFieldException", NULL); - return; - } - - const char* pathstr = env->GetStringUTFChars(path, NULL); - if (pathstr == NULL) { - jniThrowException(env, "java/lang/RuntimeException", "Out of memory"); - return; - } - - // note that stat will contain the new file data corresponding to - // pathstr - if (statfs(pathstr, stat) != 0) { - ALOGE("statfs %s failed, errno: %d", pathstr, errno); - delete stat; - env->SetIntField(thiz, fields.context, 0); - jniThrowException(env, "java/lang/IllegalArgumentException", NULL); - } - // Release pathstr - env->ReleaseStringUTFChars(path, pathstr); -} - -static void -android_os_StatFs_native_setup(JNIEnv *env, jobject thiz, jstring path) -{ - if (path == NULL) { - jniThrowException(env, "java/lang/IllegalArgumentException", NULL); - return; - } - - struct statfs* stat = new struct statfs; - if (stat == NULL) { - jniThrowException(env, "java/lang/RuntimeException", "Out of memory"); - return; - } - env->SetIntField(thiz, fields.context, (int)stat); - android_os_StatFs_native_restat(env, thiz, path); -} - -static void -android_os_StatFs_native_finalize(JNIEnv *env, jobject thiz) -{ - struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context); - if (stat != NULL) { - delete stat; - env->SetIntField(thiz, fields.context, 0); - } -} - -// ---------------------------------------------------------------------------- - -static JNINativeMethod gMethods[] = { - {"getBlockSize", "()I", (void *)android_os_StatFs_getBlockSize}, - {"getBlockCount", "()I", (void *)android_os_StatFs_getBlockCount}, - {"getFreeBlocks", "()I", (void *)android_os_StatFs_getFreeBlocks}, - {"getAvailableBlocks", "()I", (void *)android_os_StatFs_getAvailableBlocks}, - {"native_setup", "(Ljava/lang/String;)V", (void *)android_os_StatFs_native_setup}, - {"native_finalize", "()V", (void *)android_os_StatFs_native_finalize}, - {"native_restat", "(Ljava/lang/String;)V", (void *)android_os_StatFs_native_restat}, -}; - - -int register_android_os_StatFs(JNIEnv *env) -{ - jclass clazz; - - clazz = env->FindClass("android/os/StatFs"); - if (clazz == NULL) { - ALOGE("Can't find android/os/StatFs"); - return -1; - } - - fields.context = env->GetFieldID(clazz, "mNativeContext", "I"); - if (fields.context == NULL) { - ALOGE("Can't find StatFs.mNativeContext"); - return -1; - } - - return AndroidRuntime::registerNativeMethods(env, - "android/os/StatFs", gMethods, NELEM(gMethods)); -} - -} // namespace android diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index 3ad6406..bada329 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -221,7 +221,7 @@ void setSurface(JNIEnv* env, jobject clazz, const sp<Surface>& surface) static void Surface_init( JNIEnv* env, jobject clazz, jobject session, - jint, jstring jname, jint dpy, jint w, jint h, jint format, jint flags) + jint, jstring jname, jint layerStack, jint w, jint h, jint format, jint flags) { if (session == NULL) { doThrowNPE(env); @@ -233,12 +233,12 @@ static void Surface_init( sp<SurfaceControl> surface; if (jname == NULL) { - surface = client->createSurface(dpy, w, h, format, flags); + surface = client->createSurface(layerStack, w, h, format, flags); } else { const jchar* str = env->GetStringCritical(jname, 0); const String8 name(str, env->GetStringLength(jname)); env->ReleaseStringCritical(jname, str); - surface = client->createSurface(name, dpy, w, h, format, flags); + surface = client->createSurface(name, layerStack, w, h, format, flags); } if (surface == 0) { @@ -717,7 +717,7 @@ static void Surface_setWindowCrop(JNIEnv* env, jobject thiz, jobject crop) } } -static void Surface_setDisplayId(JNIEnv* env, jobject thiz, jint displayId) +static void Surface_setLayerStack(JNIEnv* env, jobject thiz, jint layerStack) { const sp<SurfaceControl>& surface(getSurfaceControl(env, thiz)); if (surface == 0) return; @@ -863,7 +863,7 @@ static JNINativeMethod gSurfaceMethods[] = { {"writeToParcel", "(Landroid/os/Parcel;I)V", (void*)Surface_writeToParcel }, {"isConsumerRunningBehind", "()Z", (void*)Surface_isConsumerRunningBehind }, {"setWindowCrop", "(Landroid/graphics/Rect;)V", (void*)Surface_setWindowCrop }, - {"setDisplayId", "(I)V", (void*)Surface_setDisplayId }, + {"setLayerStack", "(I)V", (void*)Surface_setLayerStack }, }; void nativeClassInit(JNIEnv* env, jclass clazz) diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 195b1ef..89be5cb 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -283,7 +283,7 @@ <!-- @hide --> <permission android:name="android.permission.BIND_DIRECTORY_SEARCH" android:permissionGroup="android.permission-group.PERSONAL_INFO" - android:protectionLevel="signature" /> + android:protectionLevel="signature|system" /> <!-- Allows an application to read the user's call log. --> <permission android:name="android.permission.READ_CALL_LOG" @@ -766,7 +766,6 @@ android:protectionLevel="dangerous" android:label="@string/permlab_getTasks" android:description="@string/permdesc_getTasks" /> - <!-- Allows an application to call APIs that allow it to do interactions across the users on the device, using singleton services and user-targeted broadcasts. This permission is not available to @@ -786,6 +785,15 @@ android:label="@string/permlab_interactAcrossUsersFull" android:description="@string/permdesc_interactAcrossUsersFull" /> + <!-- Allows an application to call APIs that allow it to query and manage + users on the device. This permission is not available to + third party applications. --> + <permission android:name="android.permission.MANAGE_USERS" + android:permissionGroup="android.permission-group.SYSTEM_TOOLS" + android:protectionLevel="signature" + android:label="@string/permlab_manageUsers" + android:description="@string/permdesc_manageUsers" /> + <!-- Allows an application to get full detailed information about recently running tasks, with full fidelity to the real state. @hide --> diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index db862c8..ad03dd2 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -224,6 +224,10 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Laat die program toe om aksies vir verskillende gebruikers op die toestel uit te voer. Kwaadwillige programme kan dit gebruik om die beskerming tussen gebruikers te skend."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"volle lisensie vir interaksie tussen gebruikers"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Laat alle moontlike interaksies tussen gebruikers toe."</string> + <!-- no translation found for permlab_manageUsers (1676150911672282428) --> + <skip /> + <!-- no translation found for permdesc_manageUsers (8409306667645355638) --> + <skip /> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"haal besonderhede van lopende programme op"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Laat die program toe om inligting op te haal oor huidige en onlangse lopende take. Kwaadwillige programme kan dalk private inligting oor ander programme ontdek."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"herrangskik lopende programme"</string> @@ -1309,4 +1313,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-oudio"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Klaar"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Media-uitvoer"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index ef8f604..fc6d4b8 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"መተግበሪያው በመሣሪያው ላይ በተለያዩ ተጠቃሚዎች ላይ እርምጃዎችን እንዲፈጽም ይፈቅድለታል። ተንኮል-አዘል መተግበሪያዎች ይህንን ተጠቅመው በተጠቃሚዎች መካከል ያለውን ጥበቃ ሊጥሱ ይችላሉ።"</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"በተለያዩ ተጠቃሚዎች መካከል መስተጋብር ለመፍጠር ሙሉ ፍቃድ"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"በተለያዩ ተጠቃሚዎች ላይ ሊኖሩ የሚችሉ መስተጋብሮችን ሁሉ ይፈቅዳል።"</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"ተጠቃሚዎችን ያስተዳድሩ"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"መተግበሪያዎች በመሣሪያዎች ላይ ያሉ ተጠቃሚዎችን እንዲያቀናብር ያስችለዋል፣ መጠየቅን፣ መፍጠርንና መሰረዝን ጨምሮ።"</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"እየሄዱ ስላሉ የመተግበሪያዎች ዝርዝሮች አምጣ"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"መተግበሪያው በአሁኑ ጊዜ እየተካሄዱ ስላሉና በቅርብ ጊዜ ስለተካሄዱ ተግባሮች መረጃ ዝርዝር እንዲያወጣ ይፈቅድለታል። ተንኮል-አዘል መተግበሪያዎች ስለ ሌሎች መተግበሪያዎች የግል መረጃ ሊያገኙ ይችላሉ።"</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"አሂድ ትግበራዎችን ድጋሚ ደርድር"</string> @@ -1309,4 +1311,5 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"የብሉቱዝ ድምጽ"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"ተከናውኗል"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"የሚዲያ ውጽዓት"</string> + <string name="display_manager_built_in_display" msgid="9042666544146043569">"ውስጥ የተሰራ ማያ ገጽ"</string> </resources> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 17f4dd1..14d95a5 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"للسماح للتطبيق بتنفيذ إجراءات بين مستخدمين مختلفين على الجهاز. قد تستخدم التطبيقات الضارة ذلك لانتهاك الحماية بين المستخدمين."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"الترخيص بالكامل للتعامل بين المستخدمين"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"للسماح بجميع التعاملات المحتملة بين المستخدمين."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"إدارة المستخدمين"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"لتمكين التطبيقات من إدارة المستخدمين على الجهاز، بما في ذلك طلب البحث والإنشاء والحذف."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"استرداد تفاصيل التطبيقات قيد التشغيل"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"يسمح للتطبيق باسترداد معلومات تفصيلية حول المهام قيد التشغيل حاليًا ومؤخرًا. قد تكتشف التطبيقات الضارة معلومات خاصة حول التطبيقات الأخرى."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"إعادة ترتيب التطبيقات قيد التشغيل"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"صوت بلوتوث"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"تم"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"المنفذ الإعلامي"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index b9b6cf3..d801628 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Дазваляе прыкладанню выконваць дзеяннi сярод розных карыстальнiкаў прылады. Шкоднасныя прыкладаннi могуць выкарыстоўваць гэта, каб парушыць абарону памiж карыстальнiкамi."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"поўная ліцэнзія для ўзаемадзеяння паміж карыстальнiкамi"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Дазваляе ўсе магчымыя ўзаемадзеяннi паміж карыстальнікамі."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"кіраванне дадзенымi карыстальнікаў"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Дазваляе прыкладанням кіраваць звесткамi карыстальнікаў на прыладзе, у тым ліку запытамi, працэсамi стварэння і выдалення."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"атрымаць падрабязныя дадзеныя пра запушчаныя прыкладаннi"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Дазваляе прыкладанню атрымліваць падрабязную інфармацыю пра бягучыя і нядаўна запушчаныя задачы. Шкоднасныя прыкладанні могуць атрымліваць асабістую інфармацыю пра іншыя прыкладаннi."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"змяніць парадак запушчаных прыкладанняў"</string> @@ -1309,4 +1311,5 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-аўдыё"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Гатова"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Мультымедыйны выхад"</string> + <string name="display_manager_built_in_display" msgid="9042666544146043569">"Убудаваны экран"</string> </resources> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 6370ed4..81ba8a7 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Разрешава на приложението да изпълнява действия за различни потребители на устройството. Злонамерените приложения може да използват това, за да нарушат защитата между потребителите."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"пълен лиценз за взаимодействие с потребителите"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Разрешава всички възможни взаимодействия с потребителите."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"управление на потребителите"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Разрешава на приложенията да управляват потребителите на устройството, включително изброяването, създаването и изтриването им."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"извличане на подробности за изпълняваните прилож."</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Разрешава на приложението да извлича подробна информация за задачите, изпълнявани понастоящем и неотдавна. Злонамерените приложения могат да открият поверителна информация за други приложения."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"пренареждане на изпълняваните приложения"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Звук през Bluetooth"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Готово"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Изходяща мултимедия"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 9c6cca1..0781217 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Permet que l\'aplicació dugui a terme accions en diferents usuaris del dispositiu. Les aplicacions malicioses poden fer servir aquest permís per infringir la protecció entre usuaris."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"llicència completa per interaccionar entre usuaris"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Permet totes les interaccions possibles entre usuaris."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"gestió d\'usuaris"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Permet que les aplicacions gestionin usuaris al dispositiu, incloses les consultes, la creació i la supressió."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"recupera els detalls d\'aplicacions en execució"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Permet que l\'aplicació recuperi informació detallada sobre les tasques que s\'estan executant actualment i que s\'han executat recentment. Les aplicacions malicioses poden descobrir informació privada sobre altres aplicacions."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"canvia l\'ordre de les aplicacions en execució"</string> @@ -1309,4 +1311,5 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Àudio per Bluetooth"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fet"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Sortida de contingut multimèdia"</string> + <string name="display_manager_built_in_display" msgid="9042666544146043569">"Pantalla integrada"</string> </resources> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 898fe14..4e7da84 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Umožňuje aplikaci provádět akce napříč různými uživateli zařízení. Škodlivé aplikace toto oprávnění mohou zneužít k obejití ochrany mezi uživateli."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"úplné oprávnění k interakcím napříč uživateli"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Povoluje všechny možné interakce napříč uživateli."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"správa uživatelů"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Umožňuje aplikacím spravovat uživatele v zařízení, včetně vytváření a mazání dotazů."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"získání podrobností o spuštěných aplikacích"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Umožňuje aplikaci získat podrobné informace o aktuálně a naposledy spuštěných úlohách. Škodlivé aplikace mohou odhalit soukromé informace o ostatních aplikacích."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"změna uspořádání spuštěných aplikací"</string> @@ -842,7 +844,7 @@ <item quantity="other" msgid="3903706804349556379">"před <xliff:g id="COUNT">%d</xliff:g> s"</item> </plurals> <plurals name="num_minutes_ago"> - <item quantity="one" msgid="3306787433088810191">"před 1 minutou"</item> + <item quantity="one" msgid="3306787433088810191">"před 1 min"</item> <item quantity="other" msgid="2176942008915455116">"před <xliff:g id="COUNT">%d</xliff:g> min"</item> </plurals> <plurals name="num_hours_ago"> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth Audio"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Hotovo"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Výstup médií"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 9ccf3f0..ea40879 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Tillader, at appen udfører handlinger på tværs af forskellige brugere på enheden. Ondsindede apps kan bruge dette til at krænke beskyttelsen mellem brugere."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"fuld licens til at kommunikere på tværs af brugere"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Tillader alle mulige former for kommunikation på tværs af brugere."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"administrer brugere"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Tillader, at apps administrerer brugere på enheden, herunder forespørgsler, oprettelser og sletninger."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"hente oplysninger om apps, der kører"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Tillader, at appen kan hente oplysninger om aktuelle og seneste opgaver. Ondsindede apps kan muligvis finde personlige oplysninger om andre apps."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"omorganisere kørende apps"</string> @@ -1309,4 +1311,5 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-lyd"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Udfør"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Medieudgang"</string> + <string name="display_manager_built_in_display" msgid="9042666544146043569">"Indbygget skærm"</string> </resources> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index f72d625..a0280c8 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Ermöglicht der App, auf dem Gerät nutzerübergreifend Aktionen durchzuführen. Schädliche Apps können so den zwischen den Nutzern bestehenden Schutz aufheben."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"Vollständige Lizenz zum nutzerübergreifenden Interagieren"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Ermöglicht alle möglichen nutzerübergreifenden Interaktionen"</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"Nutzer verwalten"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Ermöglicht Apps die Verwaltung der Nutzer auf dem Gerät, unter anderem das Abfragen, Erstellen und Löschen von Nutzern"</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"Details zu ausgeführten Apps abrufen"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Ermöglicht der App, detaillierte Informationen zu aktuellen und kürzlich ausgeführten Aufgaben abzurufen. Schädliche Apps können so geheime Informationen zu anderen Apps erhalten."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"Aktive Apps neu ordnen"</string> @@ -1309,4 +1311,5 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-Audio"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fertig"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Medienausgabe"</string> + <string name="display_manager_built_in_display" msgid="9042666544146043569">"Integrierter Bildschirm"</string> </resources> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 95717a2..82f0c62 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Δίνει στην εφαρμογή τη δυνατότητα να πραγματοποιεί ενέργειες σε όλους τους διαφορετικούς χρήστες στη συσκευή. Οι κακόβουλες εφαρμογές ενδέχεται να χρησιμοποιήσουν αυτή τη δυνατότητα για να παραβιάσουν την προστασία μεταξύ των χρηστών."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"πλήρης άδεια αλληλεπίδρασης στους χρήστες"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Επιτρέπει όλες τις πιθανές αλληλεπιδράσεις στους χρήστες."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"διαχείριση χρηστών"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Επιτρέπει στις εφαρμογές να διαχειρίζονται τους χρήστες της συσκευής, συμπεριλαμβανομένων των ερωτημάτων της δημιουργίας και της διαγραφής."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"ανάκτηση λεπτομερειών σχετικά με τις εκτελούμενες εφαρμογές"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Επιτρέπει στην εφαρμογή την ανάκτηση λεπτομερών πληροφοριών σχετικά με τις τρέχουσες εκτελούμενες εργασίες και τις εργασίες που έχουν εκτελεστεί πρόσφατα. Τυχόν κακόβουλες εφαρμογές ενδέχεται να ανακαλύψουν ιδιωτικές πληροφορίες σχετικά με άλλες εφαρμογές."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"αναδιάταξη εκτελούμενων εφαρμογών"</string> @@ -1309,4 +1311,5 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Ήχος Bluetooth"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Τέλος"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Έξοδος μέσων"</string> + <string name="display_manager_built_in_display" msgid="9042666544146043569">"Ενσωματωμένη οθόνη"</string> </resources> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index eaa3578..4f7b087 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Allows the app to perform actions across different users on the device. Malicious apps may use this to violate the protection between users."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"full license to interact across users"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Allows all possible interactions across users."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"manage users"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Allows apps to manage users on the device, including query, creation and deletion."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"retrieve details of running apps"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Allows the app to retrieve detailed information about currently and recently running tasks. Malicious apps may discover private information about other apps."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"re-order running apps"</string> @@ -1309,4 +1311,5 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth audio"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Done"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Media output"</string> + <string name="display_manager_built_in_display" msgid="9042666544146043569">"Built-in Screen"</string> </resources> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index b589afb..9108337 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Permite que la aplicación lleve a cabo acciones entre los diferentes usuarios del dispositivo. Las aplicaciones maliciosas pueden utilizar este permiso para infringir la protección entre usuarios."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"Licencia completa para interactuar con los usuarios"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Permite todas las interacciones posibles con los usuarios."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"Administrar usuarios"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Permite a las aplicaciones administrar a los usuarios del dispositivo, incluidas la creación y la eliminación de consultas."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"recuperar información sobre las aplicaciones en ejecución"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Permite que la aplicación recupere información detallada sobre tareas en ejecución y recientemente ejecutadas. Las aplicaciones malintencionadas pueden hallar información privada sobre otras aplicaciones."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"reorganizar aplicaciones en ejecución"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Listo"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Salida multimedia"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index ec7bbb2..c998ff6 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Permite que la aplicación lleve a cabo acciones entre los diferentes usuarios del dispositivo. Las aplicaciones maliciosas pueden utilizar este permiso para infringir la protección entre usuarios."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"licencia completa para interactuar con los usuarios"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Permite que la aplicación interactúe con los usuarios."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"administrar usuarios"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Permite a las aplicaciones administrar los usuarios del dispositivo, así como buscarlos, crearlos y eliminarlos."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"recuperar información de aplicaciones en ejecución"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Permite que la aplicación recupere información sobre tareas que se están ejecutando en este momento o que se han ejecutado recientemente. Las aplicaciones malintencionadas pueden usar este servicio para acceder a información privada sobre otras aplicaciones."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"reorganizar aplicaciones en ejecución"</string> @@ -1309,4 +1311,5 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fin"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Salida multimedia"</string> + <string name="display_manager_built_in_display" msgid="9042666544146043569">"Pantalla integrada"</string> </resources> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 957e941..872f485 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Lubab rakendusel teha toiminguid seadme erinevatel kasutajakontodel. Pahatahtlikud rakendused võivad kasutada seda kasutajatevahelise kaitse rikkumiseks."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"täielik litsents teha toiminguid erinevatel kasutajakontodel"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Lubab kõiki võimalikke toiminguid erinevatel kasutajakontodel."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"kasutajate haldamine"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Võimaldab rakendustel hallata seadme kasutajaid, sealhulgas päringuid, loomist ja kustutamist."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"töötavate rakenduste üksikasjade toomine"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Võimaldab rakendusel tuua üksikasjalikku teavet praegu töötavate ja hiljuti käitatud ülesannete kohta. Pahatahtlikud rakendused võivad tuvastada privaatset teavet muude rakenduste kohta."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"käitatud rakenduste ümberjärjestamine"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-heli"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Valmis"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Meediaväljund"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 6f99078..ecdebe8 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"به برنامه اجازه میدهد اقداماتی در بین کاربران مختلف در دستگاه انجام دهد. ممکن است برنامههای مخرب از این قابلیت برای نقض حفاظت موجود در بین کاربران استفاده کنند."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"مجوز کامل برای ارتباط بین کاربران"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"اجازه میدهد همه ارتباطات ممکن بین کاربران انجام شود."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"مدیریت کاربران"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"به برنامهها اجازه میدهد مدیریت کاربران، از قبیل پرسش، ایجاد و حذف کاربران، را در دستگاه انجام دهند."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"بازیابی جزئیات برنامههای در حال اجرا"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"به برنامه اجازه میدهد تا اطلاعات مفصلی مربوط به کارهایی که در حال حاضر و اخیراً اجرا میشوند را بازیابی کند. برنامههای مخرب میتوانند اطلاعات شخصی مربوط به برنامههای دیگر را پیدا کنند."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"تنظیم مجدد ترتیب برنامههای در حال اجرا"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"بلوتوثهای صوتی"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"انجام شد"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"خروجی رسانه"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index e06dfcc..f6ab9f8 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Antaa sovelluksen suorittaa käyttäjien välisiä toimintoja laitteessa. Haitalliset sovellukset voivat vahingoittaa käyttäjien välistä suojausta."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"lupa suorittaa käyttäjien välisiä toimintoja"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Sallii kaikki käyttäjien väliset toiminnot."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"hallinnoi käyttäjiä"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Antaa sovelluksien hallinnoida laitteen käyttäjiä esim. hakemalla, luomalla tai poistamalla käyttäjiä."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"hae tiedot suoritettavista sovelluksista"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Antaa sovellukselle oikeuden noutaa käynnissä oleviin ja käynnissä olleisiin tehtäviin liittyviä tietoja. Haitalliset sovellukset saattavat saada näin muihin sovelluksiin liittyviä yksityisiä tietoja."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"käynnissä olevien sovellusten järjesteleminen"</string> @@ -1309,4 +1311,5 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-ääni"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Valmis"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Median äänentoisto"</string> + <string name="display_manager_built_in_display" msgid="9042666544146043569">"Sisäänrakennettu näyttö"</string> </resources> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index e98000a..c35fe8d 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Permet à l\'application d\'effectuer des actions entre les différents utilisateurs de l\'appareil. Les applications malveillantes peuvent utiliser cette autorisation pour passer outre la protection entre les utilisateurs."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"autorisation totale d\'interagir entre les utilisateurs"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Permet toutes les interactions possibles entre les utilisateurs."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"Gérer les utilisateurs"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Permet aux applications de gérer les utilisateurs de l\'appareil, y compris la recherche, la création et la suppression d\'utilisateurs."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"récupérer les détails des applications en cours d\'exécution"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Permet à l\'application de récupérer des informations détaillées sur les tâches en cours d\'exécution ou récemment exécutées. Des applications malveillantes peuvent utiliser cette fonctionnalité pour obtenir des informations confidentielles relatives à d\'autres applications."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"réorganiser les applications en cours d\'exécution"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"OK"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Sortie multimédia"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index cf8fa01..6ea8f7b 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"एप्लिकेशन को उपकरण पर भिन्न उपयोगकर्ताओं के बीच कार्य निष्पादित करने देता है. दुर्भावनापूर्ण एप्लिकेशन उपयोगकर्ताओं के बीच सुरक्षा का उल्लंघन करने के लिए इसका उपयोग कर सकते हैं."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"उपयोगकर्ताओं के बीच सहभागिता करने के लिए पूर्ण लाइसेंस"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"उपयोगकर्ताओं के बीच सभी संभव सहभागिता करने देता है."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"उपयोगकर्ता प्रबंधित करें"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"एप्लिकेशन को उपकरण पर क्वेरी, निर्माण और हटाने सहित उपयोगकर्ताओं को प्रबंधित करने की सुविधा देता है."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"चल रहे एप्लिकेशन के विवरण प्राप्त करें"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"एप्लिकेशन को वर्तमान में और हाल ही में चल रहे कार्यों की जानकारी प्राप्त करने देता है. दुर्भावनापूर्ण एप्लिकेशन अन्य एप्लिकेशन के बारे में निजी जानकारी खोज सकते हैं."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"चल रहे एप्लिकेशन पुन: क्रमित करें"</string> @@ -722,7 +724,7 @@ <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"आपका सिम कार्ड स्थायी रूप से अक्षम कर दिया गया है."\n" दूसरे SIM कार्ड के लिए अपने वायरलेस सेवा प्रदाता से संपर्क करें."</string> <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"पिछला ट्रैक बटन"</string> <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"अगला ट्रैक बटन"</string> - <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"रोकें बटन"</string> + <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"पॉज़ करें बटन"</string> <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"चलाएं बटन"</string> <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"रोकें बटन"</string> <string name="emergency_calls_only" msgid="6733978304386365407">"केवल आपातकालीन कॉल"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth ऑडियो"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"पूर्ण"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"मीडिया आउटपुट"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 2029530..26bc6ec 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Omogućuje aplikaciji izvršavanje radnji među korisnicima na uređaju. Zlonamjerne aplikacije mogu to iskoristiti za narušavanje zaštite među korisnicima."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"dozvola za potpunu interakciju među korisnicima"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Omogućuje sve moguće interakcije među korisnicima."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"upravljanje korisnicima"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Omogućuje aplikacijama upravljanje korisnicima na uređaju, uključujući upit, izradu i brisanje."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"dohvaćanje pojedinosti o pokrenutim aplikacijama"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Aplikaciji omogućuje dohvaćanje detaljnih informacija o trenutačno i nedavno pokrenutim zadacima. Zlonamjerne aplikacije mogu otkriti privatne informacije o drugim aplikacijama."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"promjena redoslijeda pokrenutih aplikacija"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth zvuk"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Gotovo"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Medijski izlaz"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 421c5be..42e7888 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Lehetővé teszi az alkalmazás számára, hogy több felhasználó között végezzen különféle műveleteket az eszközön. A rosszindulatú alkalmazások arra használhatják ezt, hogy megsértsék a felhasználók biztonságát."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"teljes licenc a felhasználók közötti interakcióhoz"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Lehetővé teszi az összes lehetséges interakciót a felhasználók között."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"Felhasználók kezelése"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Lehetővé teszi az alkalmazások számára a készüléken beállított felhasználók kezelését, beleértve a lekérdezéseket, a létrehozásokat és törléseket."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"futó alkalmazások részleteinek lekérése"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Lehetővé teszi az alkalmazás számára a jelenleg és a nemrég futó feladatok részletes adatainak lekérését. A rosszindulatú alkalmazások más alkalmazásokkal kapcsolatos privát adatokhoz férhetnek hozzá."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"futó alkalmazások átrendezése"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth hang"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Kész"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Médiakimenet"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index ef759e0..34e6a96 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Mengizinkan aplikasi melakukan tindakan antar-pengguna yang berbeda pada perangkat. Aplikasi berbahaya dapat menggunakan ini untuk mengganggu perlindungan antar-pengguna."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"lisensi penuh untuk berinteraksi antar-pengguna"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Mengizinkan semua interaksi yang mungkin antar-pengguna."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"kelola pengguna"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Memungkinkan aplikasi mengelola pengguna pada perangkat, termasuk kueri, pembuatan, dan penghapusan."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"mengambil detail aplikasi yang sedang berjalan"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Izinkan aplikasi mengambil informasi mendetail tentang tugas yang saat ini dan baru-baru ini dijalankan. Aplikasi berbahaya dapat menemukan informasi pribadi tentang aplikasi lain."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"menyusun ulang apl yang berjalan"</string> @@ -1309,4 +1311,5 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Selesai"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Keluaran media"</string> + <string name="display_manager_built_in_display" msgid="9042666544146043569">"Layar Ada Di Dalamnya"</string> </resources> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 5f64c20..a693dc8 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Consente all\'applicazione di compiere azioni per diversi utenti sul dispositivo. Le applicazioni dannose potrebbero farne uso per violare la protezione tra utenti."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"licenza completa per l\'interazione tra utenti"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Consente tutte le interazioni possibili tra gli utenti."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"Gestione utenti"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Consente alle applicazioni di gestire gli utenti sul dispositivo, nonché query, creazione ed eliminazione."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"recupero dettagli applicazioni in esecuzione"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Consente all\'applicazione di recuperare informazioni dettagliate sulle attività attualmente e recentemente in esecuzione. Le applicazioni dannose potrebbero scoprire informazioni riservate su altre applicazioni."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"riordinamento applicazioni in esecuzione"</string> @@ -1309,4 +1311,5 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fine"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Uscita media"</string> + <string name="display_manager_built_in_display" msgid="9042666544146043569">"Schermo incorporato"</string> </resources> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 5432f26..a318907 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"מאפשר ליישום לבצע פעולות בין משתמשים שונים במכשיר. יישומים זדוניים עשויים להשתמש ביכולת זו כדי לפרוץ את ההגנה בין משתמשים."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"רישיון מלא לבצע אינטראקציה בין משתמשים"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"מאפשר את כל האינטראקציות האפשריות בין משתמשים."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"נהל משתמשים"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"מאפשר ליישומים לנהל משתמשים במכשיר, כולל שאילתה, יצירה ומחיקה."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"אחזור פרטי יישומים פועלים"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"מאפשר ליישום לאחזר מידע מפורט על המשימות הנוכחיות הפועלות ועל משימות שפעלו לאחרונה. יישומים זדוניים עלולים לגלות מידע אישי על יישומים אחרים."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"סידור מחדש של יישומים פעילים"</string> @@ -1309,4 +1311,5 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"אודיו Bluetooth"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"סיום"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"פלט מדיה"</string> + <string name="display_manager_built_in_display" msgid="9042666544146043569">"מסך מובנה"</string> </resources> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index f8ab2bf..dc0c139 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"端末上の各ユーザーに対して操作を実行することをアプリに許可します。この許可を悪意のあるアプリに利用されると、ユーザー間の保護が侵害される恐れがあります。"</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"ユーザー間で交流するための完全ライセンス"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"ユーザー間の交流をすべて許可します。"</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"ユーザーの管理"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"ユーザーの問い合わせ、作成、削除を含め、端末上のユーザーを管理することをアプリに許可します。"</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"実行中のアプリの詳細の取得"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"現在実行中のタスクまたは最近実行したタスクに関する情報の取得をアプリに許可します。この許可を悪意のあるアプリに利用されると、他のアプリに関する非公開情報が読み取られる恐れがあります。"</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"実行中のアプリの順序変更"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth音声"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"完了"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"メディア出力"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index ec301a4..f6ae2af 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"앱이 기기에서 다양한 사용자에 대한 작업을 수행할 수 있도록 허용합니다. 이 경우 악성 앱이 사용자 간의 보호를 위반할 수 있습니다."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"여러 사용자와의 상호작용을 위한 정식 라이센스"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"여러 사용자와의 가능한 모든 상호작용을 허용합니다."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"사용자 관리"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"앱이 기기에서 검색, 생성 및 삭제를 포함한 사용자 관리를 할 수 있도록 허용합니다."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"실행 중인 앱 세부정보 검색"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"앱이 현재 실행 중이거나 최근에 실행된 작업에 대한 상세한 정보를 검색할 수 있도록 허용합니다. 이 경우 악성 앱이 다른 앱에 대한 개인 정보를 검색할 수 있습니다."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"실행 중인 앱 순서 재지정"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"블루투스 오디오"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"완료"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"미디어 출력"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 7f44e81..7692620 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Leidžiama programai atlikti veiksmus skirtingų įrenginio naudotojų profiliuose. Kenkėjiškos programos gali pasinaudoti šiuo leidimu, kad pažeistų naudotojų saugumą."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"visa licencija, leidžianti sąveikauti su naudotojais"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Leidžiama bet kokia sąveika tarp naudotojų."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"tvarkyti naudotojus"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Leidžia tvarkyti įrenginio naudotojų duomenis, įskaitant užklausų teikimą, duomenų kūrimą ir ištrynimą."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"nuskaityti veikiančių programų išsamią informaciją"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Leidžiama programai nuskaityti išsamią informaciją apie šiuo ir pastaruoju metu vykdomas užduotis. Kenkėjiškos programos gali surasti privačios informacijos apie kitas programas."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"pertvarkyti vykdomas programas"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"„Bluetooth“ garsas"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Atlikta"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Medijos išvestis"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 1d46ccb..d63c45b 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Ļauj lietotnei veikt darbības vairāku ierīces lietotāju kontos. Ļaunprātīgas lietotnes var izmantot šo atļauju, lai apdraudētu lietotāju kontu drošību."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"pilna licence ar atļauju darboties visos lietotāju kontos"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Ļauj veikt jebkādas darbības visos lietotāju kontos."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"Lietotāju pārvaldība"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Ļauj lietotnēm pārvaldīt ierīces lietotājus, tostarp izveidot un dzēst lietotājus vai veidot vaicājumus."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"Informācijas izguve par izmantotajām lietotnēm"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Ļauj lietotnei izgūt informāciju par šobrīd un nesen veiktajiem uzdevumiem. Ļaunprātīgas lietotnes var atklāt privātu informāciju par citām lietotnēm."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"pārkārtot izmantotās lietotnes"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth audio"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Gatavs"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Multivides izeja"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 5bbebc5..a22ff51 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Membenarkan apl melakukan tindakan merentasi pengguna berbeza pada peranti. Apl hasad boleh menggunakan ini untuk melanggar perlindungan antara pengguna."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"lesen penuh untuk berinteraksi sesama pengguna"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Membenarkan semua interaksi yang mungkin sesama pengguna."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"urus pengguna"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Membenarkan apl mengurus pengguna pada peranti ini, termasuk pertanyaan, pembuatan dan pemadaman."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"dapatkan butiran apl yang berjalan"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Membenarkan apl untuk mendapatkan maklumat terperinci tentang tugasan yang sedang dan baru berjalan. Apl hasad boleh mendapat maklumat peribadi tentang apl lain."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"susun semula tertib apl yang dijalankan"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Selesai"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Output media"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 68f8918..3a4212b 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Tillater at appen utfører handlinger på tvers av ulike brukere på enheten. Skadelige apper kan utnytte dette til å bryte beskyttelsen mellom brukere."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"full lisens til å samhandle på tvers av brukere"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Tillater alle mulige samhandlinger på tvers av brukere."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"Administrere brukere"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Lar apper administrere brukere på enheten, herunder forespørsler, oppretting og sletting."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"hente informasjon om apper som kjører"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Tillater at appen henter ut informasjon om oppgaver som kjører eller nylig har kjørt. Skadelige apper kan bruke dette til å oppdage privat informasjon om andre apper."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"Endre rekkefølge på apper som kjører"</string> @@ -1309,4 +1311,5 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-lyd"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fullført"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Medieutgang"</string> + <string name="display_manager_built_in_display" msgid="9042666544146043569">"Innebygd skjerm"</string> </resources> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 985da7e..89e52a9 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Hiermee kan de app acties uitvoeren voor verschillende gebruikers van het apparaat. Schadelijke apps kunnen dit gebruiken om de beveiliging tussen gebruikers te schenden."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"volledige toestemming voor interactie tussen gebruikers"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Hiermee is alle mogelijke interactie tussen gebruikers toegestaan."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"gebruikers beheren"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Toestaan dat apps gebruikers op het apparaat beheren, inclusief het opvragen van gegevens en het maken en verwijderen van gebruikers."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"details van actieve apps ophalen"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Hiermee kan de app gedetailleerde informatie over huidige en recent uitgevoerde taken ophalen. Schadelijke apps kunnen op deze manier mogelijk privé-informatie over andere apps achterhalen."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"actieve apps opnieuw rangschikken"</string> @@ -1309,4 +1311,5 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-audio"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Gereed"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Media-uitvoer"</string> + <string name="display_manager_built_in_display" msgid="9042666544146043569">"Ingebouwd scherm"</string> </resources> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 19f317d..e16d308 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Umożliwia aplikacji wykonywanie działań dotyczących różnych użytkowników urządzenia. Złośliwe aplikacje mogą to wykorzystać do złamania zabezpieczeń na kontach użytkowników."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"pełna licencja na interakcje między użytkownikami"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Zezwala na wszystkie możliwe interakcje między użytkownikami."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"zarządzanie użytkownikami"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Pozwala aplikacjom na zarządzanie użytkownikami na urządzeniu, w tym na ich sprawdzanie, tworzenie i usuwanie."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"Pobieraj informacje o uruchomionych aplikacjach"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Zezwala aplikacji na pobieranie informacji o obecnie i ostatnio uruchomionych zadaniach. Złośliwe aplikacje mogą uzyskać dostęp do prywatnych informacji na temat innych aplikacji."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"zmienianie kolejności uruchomionych aplikacji"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Dźwięk Bluetooth"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Gotowe"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Wyjście multimediów"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 788d1a2..996be49 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Permite que a aplicação execute ações com diferentes utilizadores no dispositivo. Aplicações maliciosas poderão utilizar esta opção para violar a proteção entre utilizadores."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"licença completa para interagir entre utilizadores"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Permite todas as interações possíveis entre utilizadores."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"gerir utilizadores"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Permite às aplicações a gestão de utilizadores no dispositivo, incluindo a criação e eliminação de consultas."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"obter detalhes das aplicações em execução"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Permite à aplicação obter informações detalhadas sobre tarefas atualmente em execução e recentemente executadas. As aplicações maliciosas poderão descobrir informações privadas de outras aplicações."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"reordenar as aplicações em execução"</string> @@ -1132,7 +1134,7 @@ <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"O armazenamento USB foi removido. Insira um novo suporte de dados."</string> <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"Cartão SD removido. Insira um novo cartão."</string> <string name="activity_list_empty" msgid="1675388330786841066">"Não foi encontrada nenhuma atividade correspondente."</string> - <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"actualizar estatísticas de utilização de componentes"</string> + <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"atualizar estatísticas de utilização de componentes"</string> <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Permite que a aplicação modifique as estatísticas de utilização de componentes recolhidas. Não se destina a utilização por aplicações normais."</string> <string name="permlab_copyProtectedData" msgid="4341036311211406692">"copiar conteúdo"</string> <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> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Áudio Bluetooth"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Concluído"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Saída de som multimédia"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 9bdfcd8..7d7672f 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Permite que o aplicativo execute ações entre os diversos usuários do aparelho. Aplicativos mal-intencionados podem usar isto para violar a proteção entre os usuários."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"permissão total para interagir entre os usuários"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Permite todas as interações possíveis entre os usuários."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"gerenciar usuários"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Permite que os aplicativos gerenciem os usuários do dispositivo, incluindo a consulta, a criação e a exclusão de usuários."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"recuperar detalhes dos aplicativos em execução"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Permite que o aplicativo recupere informações detalhadas sobre tarefas executadas atual e recentemente. Aplicativos maliciosos podem descobrir informações privadas sobre outros aplicativos."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"reordenar os aplicativos em execução"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Áudio Bluetooth"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Concluído"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Saída de mídia"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml index 097d6de..a093bfb 100644 --- a/core/res/res/values-rm/strings.xml +++ b/core/res/res/values-rm/strings.xml @@ -303,6 +303,10 @@ <skip /> <!-- no translation found for permdesc_interactAcrossUsersFull (376841368395502366) --> <skip /> + <!-- no translation found for permlab_manageUsers (1676150911672282428) --> + <skip /> + <!-- no translation found for permdesc_manageUsers (8409306667645355638) --> + <skip /> <!-- no translation found for permlab_getDetailedTasks (6229468674753529501) --> <skip /> <!-- no translation found for permdesc_getDetailedTasks (153824741440717599) --> @@ -2066,4 +2070,6 @@ <skip /> <!-- no translation found for media_route_button_content_description (5758553567065145276) --> <skip /> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 7284dd7..6300a1f 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Permite aplicaţiei să efectueze acţiuni pentru diferiţi utilizatori pe dispozitiv. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a încălca protecţia între utilizatori."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"licenţă completă pentru interacţiune între utilizatori"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Permite toate interacţiunile posibile între utilizatori."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"gestionează utilizatorii"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Permite aplicaţiilor să gestioneze utilizatorii de pe dispozitiv, inclusiv interogarea, crearea şi ştergerea acestora."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"preia detalii despre aplicaţiile care rulează"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Permite aplicaţiei să preia informaţii detaliate despre activităţile rulate curent şi recent. Aplicaţiile rău intenţionate pot să descopere informaţii private despre alte aplicaţii."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"reordonare aplicaţii care rulează"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Terminat"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Rezultate media"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index c32f93a..004b2b6 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Приложение сможет выполнять действия во всех аккаунтах на этом устройстве. При этом защита от вредоносных приложений может быть недостаточной."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"разрешить полное взаимодействие со всеми аккаунтами"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Приложение сможет выполнять любые действия во всех аккаунтах на этом устройстве."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"Управлять аккаунтами"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Приложения смогут управлять аккаунтами на этом устройстве (выполнять поиск, создавать и удалять их)"</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"получение сведений о работающих приложениях"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Приложение сможет получать подробные сведения о недавно запущенных и выполняемых задачах. При этом конфиденциальная информация о других приложениях не будет защищена от вредоносных программ."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"Упорядочивание запущенных приложений"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Воспроизведение звука через Bluetooth"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Готово"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Перенаправлять поток мультимедиа"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 3464faa..15c359c 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Umožňuje aplikácii vykonávať akcie naprieč rôznymi používateľmi zariadenia. Škodlivé aplikácie môžu toto povolenie zneužiť na obídenie ochrany medzi používateľmi."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"plná licencia na interakcie naprieč používateľmi"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Umožňuje všetky možné interakcie naprieč používateľmi."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"správa používateľov"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Umožňuje aplikáciám spravovať používateľov v zariadení, vrátane vyhľadávania dopytov, vytvorenia a odstránenia."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"načítať podrobnosti o spustených aplikáciách"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Umožňuje aplikácii načítať podrobné informácie o aktuálnych a nedávno spustených úlohách. Škodlivé aplikácie môžu odhaliť súkromné informácie o iných aplikáciách."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"zmeniť poradie spustených aplikácií"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth audio"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Hotovo"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Výstup médií"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 35246b1..1ede6b7 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Aplikaciji omogoča izvajanje dejanj za različne uporabnike v napravi. Zlonamerne aplikacije lahko to uporabijo za kršitev zaščite med uporabniki."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"polna licenca za interakcijo z uporabniki"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Dovoli vso mogočo interakcijo z uporabniki"</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"upravljanje uporabnikov"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Aplikacijam omogoča upravljanje uporabnikov v napravi, vključno z iskanjem, ustvarjanjem in brisanjem."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"prejemanje podrobnosti o aplikacijah, ki se izvajajo"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Aplikaciji omogoča, da dobi podatke o trenutnih in nedavno izvajajočih se opravilih. Zlonamerne aplikacije lahko odkrijejo zasebne podatke o drugih aplikacijah."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"preurejanje programov, ki se izvajajo"</string> @@ -1309,4 +1311,5 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Zvok prek Bluetootha"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Končano"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Izhod predstavnosti"</string> + <string name="display_manager_built_in_display" msgid="9042666544146043569">"Vgrajen zaslon"</string> </resources> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index d5c0561..e4cf347 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Дозвољава апликацији да обавља радње између различитих корисника на уређају. Злонамерне апликације могу да користе ово да би угрозиле заштиту између корисника."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"пуна лиценца за интеракцију између корисника"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Дозвољава све могуће интеракције између корисника."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"управљање корисницима"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Дозвољава апликацијама да управљају корисницима на уређају, укључујући постављање упита, прављење и брисање."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"преузимање детаља о покренутим апликацијама"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Дозвољава апликацији да преузима детаљне информације о актуелним и недавно покренутим задацима. Злонамерне апликације могу да открију приватне информације о другим апликацијама."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"промена редоследа покренутих апликација"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth аудио"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Готово"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Излаз медија"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 89c0796..493a0bb 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Tillåter att appen utför åtgärder mellan användare på enheten. Skadliga appar kan använda detta som ett sätt att kringgå skyddet mellan användare."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"fullständig behörighet att interagera mellan användare"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Tillåter all slags interaktion mellan användare."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"hantera användare"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Tillåter att appen hanterar användare på enheten, inklusive att söka efter, skapa och radera användarinformation."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"hämta information om aktiva appar"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Tillåter att appen hämtar detaljerad information om uppgifter som körs och har körts. Skadliga appar kan upptäcka personliga uppgifter om andra appar."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"byt ordning på appar som körs"</string> @@ -1309,4 +1311,5 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-ljud"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Klar"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Medieuppspelning"</string> + <string name="display_manager_built_in_display" msgid="9042666544146043569">"Inbyggd skärm"</string> </resources> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 3fd7af0..759000d 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Inaruhusu programu kutenda vitendo kwa watumiaji tofauti kwenye kifaa. Programu hasidi huenda zikatumia hii ili kukiuka ulinzi kati ya watumiaji."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"leseni kamili ili kutagusana na watumiaji"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Inaruhusu miingialiano yote inayowezekana kwa watumiaji."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"dhibiti watumiaji"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Inaruhusu programu kudhibiti watumiaji kwenye kifaa, pamoja na hoji, uundaji na ufutaji."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"epua maelezo ya programu zinazoendeshwa"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Huruhusu programu kuepua maelezo tondoti kuhusu kazi za sasa na zinazoendelea hivi karibuni. Programu hasidi huenda zikagundua maelezo ya kibinafsi kuhusu programu zingine."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"Agiza tena programu za kuendeshwa"</string> @@ -1309,4 +1311,5 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Sauti ya Bluetooth"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Kwisha"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Towe la midia"</string> + <string name="display_manager_built_in_display" msgid="9042666544146043569">"Skrini Iliyojengewa ndani"</string> </resources> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 61e25b2..c25e6db 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"อนุญาตให้แอปพลิเคชันทำงานได้กับผู้ใช้หลายรายบนอุปกรณ์นี้ แอปพลิเคชันที่เป็นอันตรายอาจใช้การทำงานนี้ในการบุกรุกการป้องกันระหว่างผู้ใช้"</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"ใบอนุญาตฉบับเต็มสำหรับการโต้ตอบระหว่างผู้ใช้"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"อนุญาตให้ทำการโต้ตอบทุกชนิดที่เป็นไปได้กับผู้ใช้ต่างๆ"</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"จัดการผู้ใช้"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"อนุญาตให้แอปพลิเคชันจัดการผู้ใช้บนอุปกรณ์ รวมทั้งการถามคำถาม การสร้าง และการลบ"</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"ดึงรายละเอียดของแอปที่ทำงานอยู่"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"อนุญาตให้แอปพลิเคชันดึงข้อมูลเกี่ยวกับงานที่กำลังเรียกใช้อยู่ในปัจจุบันและงานล่าสุด แอปพลิเคชันที่เป็นอันตรายอาจค้นพบข้อมูลเฉพาะตัวเกี่ยวกับแอปพลิเคชันอื่นๆ"</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"จัดลำดับแอปพลิเคชันที่ทำงานอยู่ใหม่"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"เสียงบลูทูธ"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"เสร็จสิ้น"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"เอาต์พุตสื่อ"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index adf7ef2..ab4ff29 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Binibigyang-daan ang app upang magsagawa ng mga pagkilos sa kabuuan ng iba\'t ibang mga user sa device. Maaari itong gamitin ng nakakahamak na apps upang lumabag sa proteksyon sa pagitan ng mga user."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"ganap na lisensya upang makipag-ugnayan sa kabuuan ng mga user"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Pinapayagan ang lahat ng posibleng pakikipag-ugnayan sa kabuuan ng mga user."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"pamahalaan ang mga user"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Binibigyang-daan ang apps na mamahala ng mga user sa device, kabilang ang query, paglikha at pagtanggal."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"bawiin ang mga detalye ng gumaganang apps"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Binibigyang-daan ang app na bawiin ang detalyadong impormasyon tungkol sa mga kasalukuyan at kamakailang gumaganang gawain. Maaaring makatuklas ang nakakahamak na apps ng pribadong impormasyon tungkol sa iba pang apps."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"muling isaayos ang tumatakbong apps"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio sa Bluetooth"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Tapos na"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Output ng media"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index e15402a..95637dc 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Uygulamaya cihazdaki farklı kullanıcılar arasında işlem gerçekleştirme izni verir. Kötü amaçlı uygulamalar bu izinle kullanıcılar arasındaki korumayı ihlal edebilir."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"kullanıcılar arasında etkileşim kurmak için tam izin"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Kullanıcılar arasında tüm etkileşime izin verir."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"kullanıcıları yönet"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Uygulamalara, sorgulama, oluşturma ve silme işlemleri de dahil olmak üzere cihazdaki kullanıcıları yönetme izni verir."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"çalışan uygulamaların ayrıntılarını al"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Uygulamaya, şu anda çalışmakta olan ve son çalışan işlemler hakkında ayrıntılı bilgi alma izni verir. Kötü amaçlı uygulamalar diğer uygulamalar hakkında gizli bilgileri ele geçirebilir."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"çalışan uygulamaları yeniden sırala"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth ses"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Tamamlandı"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Medya çıkışı"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index d37cbd8..a8633e8 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Дозволяє програмі виконувати дії щодо різних користувачів на пристрої. Шкідливі програми можуть використовувати це для порушення захисту окремих користувачів."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"повна ліцензія на взаємодію між користувачами"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Дозволяє всі можливі взаємодії щодо користувачів."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"керувати користувачами"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Дозволяє програмам керувати користувачами на пристрої, зокрема надсилати запити про користувачів, створювати й видаляти їх."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"отримувати дані про запущені програми"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Дозволяє програмі отримувати інформацію про поточні й останні запущені завдання. Шкідливі програми можуть виявляти особисту інформацію про інші програми."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"змінювати порядок запущених програм"</string> @@ -1309,4 +1311,5 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Аудіо Bluetooth"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Готово"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Вивід медіа-даних"</string> + <string name="display_manager_built_in_display" msgid="9042666544146043569">"Вбудований екран"</string> </resources> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 8ce6f4e..384a1ee 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Cho phép ứng dụng thực hiện hành động giữa những người dùng khác trên thiết bị. Ứng dụng độc hại có thể sử dụng quyền này để vi phạm khả năng bảo vệ giữa người dùng."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"cấp phép đầy đủ để tương tác giữa người dùng"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Cho phép tất cả các tương tác giữa người dùng."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"quản lý người dùng"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Cho phép ứng dụng quản lý người dùng trên thiết bị, bao gồm truy vấn, tạo và xóa."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"truy xuất chi tiết về các ứng dụng đang chạy"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Cho phép ứng dụng truy xuất thông tin chi tiết về các tác vụ đã và đang chạy gần đây. Ứng dụng độc hại có thể phát hiện thông tin riêng tư về các ứng dụng khác."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"sắp xếp lại những ứng dụng đang chạy"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Âm thanh Bluetooth"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Xong"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Đầu ra phương tiện"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 4a9cd5a..289dcf8 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -155,7 +155,7 @@ <string name="global_action_lock" msgid="2844945191792119712">"屏幕锁定"</string> <string name="global_action_power_off" msgid="4471879440839879722">"关机"</string> <string name="global_action_bug_report" msgid="7934010578922304799">"错误报告"</string> - <string name="bugreport_title" msgid="2667494803742548533">"获取错误报告"</string> + <string name="bugreport_title" msgid="2667494803742548533">"提交错误报告"</string> <string name="bugreport_message" msgid="398447048750350456">"这会收集有关当前设备状态的信息,并以电子邮件的形式进行发送。从开始生成错误报告到准备好发送需要一点时间,请耐心等待。"</string> <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"静音模式"</string> <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"声音已关闭"</string> @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"允许该应用在设备上跨多个用户执行操作。恶意应用可能会借此破坏用户之间的保护措施。"</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"完全允许在用户之间进行互动"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"允许在用户之间进行所有可能的互动。"</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"管理用户"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"允许应用管理设备上的用户(包括查询、创建和删除用户)。"</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"检索正在运行的应用的详细信息"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"允许该应用检索当前正在运行和近期运行的任务的详细信息。恶意应用可能会发现有关其他应用的私密信息。"</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"对正在运行的应用重新排序"</string> @@ -1068,13 +1070,13 @@ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff900000">"新增:"</font></string> <string name="perms_description_app" msgid="5139836143293299417">"由“<xliff:g id="APP_NAME">%1$s</xliff:g>”提供。"</string> <string name="usb_storage_activity_title" msgid="4465055157209648641">"USB 大容量存储设备"</string> - <string name="usb_storage_title" msgid="5901459041398751495">"USB 已连接"</string> + <string name="usb_storage_title" msgid="5901459041398751495">"已连接 USB"</string> <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"您已通过 USB 连接至计算机。如果您要在计算机与 Android 设备的 USB 存储设备之间复制文件,请触摸下面的按钮。"</string> <string name="usb_storage_message" product="default" msgid="805351000446037811">"您已通过 USB 连接至计算机。如果您要在计算机和 Android 设备的 SD 卡之间复制文件,请触摸下面的按钮。"</string> <string name="usb_storage_button_mount" msgid="1052259930369508235">"打开 USB 存储设备"</string> <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"使用 USB 存储设备作为 USB 大容量存储设备时出现问题。"</string> <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"使用 SD 卡作为 USB 大容量存储设备时出现问题。"</string> - <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB 已连接"</string> + <string name="usb_storage_notification_title" msgid="8175892554757216525">"已连接 USB"</string> <string name="usb_storage_notification_message" msgid="939822783828183763">"触摸可将文件复制到计算机或从计算机复制到存储设备。"</string> <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"关闭 USB 存储设备"</string> <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"触摸可关闭 USB 存储设备。"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"蓝牙音频"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"完成"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"媒体输出线路"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 20a15d1..96ba8c1 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"允許應用程式對裝置上的所有使用者執行各種動作。請注意,惡意應用程式可能利用此功能侵害使用者之間的保護機制。"</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"完整授權對所有使用者執行各種動作"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"允許對所有使用者執行各種可能的動作。"</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"管理使用者"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"允許應用程式管理裝置上的使用者,包括查詢、建立及刪除使用者。"</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"擷取執行中應用程式的詳細資訊"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"允許應用程式擷取目前及最近所執行任務的詳細資訊。請注意,惡意應用程式可能會找出其他應用程式的不公開資訊。"</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"重新排序正在執行的應用程式"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"藍牙音訊"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"完成"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"媒體輸出"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 8978e52..2a17f8f 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -224,6 +224,8 @@ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Ivumela uhlelo lokusebenza ukwenza izenzo kubasebenzisi bonke kudivayisi. Izinhlelo zokusebenza ezingalungile zingasebenzisa lokhu ukwephula ukuvikela phakathi kwabasebenzisi."</string> <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"ilayisensi egcwele yokuhlanganyela kubasebenzisi"</string> <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Ivumela konke ukuhlanganyela phakathi kwabasebenzisi."</string> + <string name="permlab_manageUsers" msgid="1676150911672282428">"phatha abasebenzisi"</string> + <string name="permdesc_manageUsers" msgid="8409306667645355638">"Ivumela izinhlelo zokusebenza ukuphatha abasebenzisi kudivayisi, kufaka phakathi umbuzo, ukudala nokususa."</string> <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"thola kabusha imininingwane yezinhlelo zokusebenza ezisebenzayo"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Ivumela uhlelo lokusebenza ukuthola kabusha ulwazi mayelana nezinto ezenzeka manje nezisanda kwenzeka. Izinhlelo zokusebenza ezingalungile zingathola imininingwane eyimfihlo mayelana nezinye izinhlelo zokusebenza."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"misa kabusha izinsiza ezisebenzayo"</string> @@ -1309,4 +1311,6 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Umsindo we-Bluetooth"</string> <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Qedile"</string> <string name="media_route_button_content_description" msgid="5758553567065145276">"Okukhiphayo kwemidiya"</string> + <!-- no translation found for display_manager_built_in_display (9042666544146043569) --> + <skip /> </resources> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 38a431f..0d190ee 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -479,6 +479,7 @@ <java-symbol type="string" name="decline" /> <java-symbol type="string" name="default_text_encoding" /> <java-symbol type="string" name="description_target_unlock_tablet" /> + <java-symbol type="string" name="display_manager_built_in_display" /> <java-symbol type="string" name="double_tap_toast" /> <java-symbol type="string" name="elapsed_time_short_format_h_mm_ss" /> <java-symbol type="string" name="elapsed_time_short_format_mm_ss" /> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 352c409..b7ad1e9 100755 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -567,6 +567,11 @@ <string name="permdesc_interactAcrossUsersFull">Allows all possible interactions across users.</string> + <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to create/remove/query users. [CHAR LIMIT=none] --> + <string name="permlab_manageUsers">manage users</string> + <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to create/remove/query users. [CHAR LIMIT=NONE] --> + <string name="permdesc_manageUsers">Allows apps to manage users on the device, including query, creation and deletion.</string> + <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=50] --> <string name="permlab_getDetailedTasks">retrieve details of running apps</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] --> @@ -3634,4 +3639,9 @@ <!-- Content description of a MediaRouteButton for accessibility support --> <string name="media_route_button_content_description">Media output</string> + <!-- Display manager service --> + + <!-- Name of the built-in display. [CHAR LIMIT=50] --> + <string name="display_manager_built_in_display">Built-in Screen</string> + </resources> diff --git a/core/tests/coretests/src/android/content/pm/AppCacheTest.java b/core/tests/coretests/src/android/content/pm/AppCacheTest.java index 8d53db9..aae55e8 100755 --- a/core/tests/coretests/src/android/content/pm/AppCacheTest.java +++ b/core/tests/coretests/src/android/content/pm/AppCacheTest.java @@ -570,7 +570,7 @@ public class AppCacheTest extends AndroidTestCase { PackageStatsObserver observer = new PackageStatsObserver(); //wait on observer synchronized(observer) { - getPm().getPackageSizeInfo(packageName, observer); + getPm().getPackageSizeInfo(packageName, UserHandle.myUserId(), observer); long waitTime = 0; while((!observer.isDone()) || (waitTime > MAX_WAIT_TIME) ) { observer.wait(WAIT_TIME_INCR); diff --git a/core/tests/coretests/src/android/content/pm/VerificationParamsTest.java b/core/tests/coretests/src/android/content/pm/VerificationParamsTest.java new file mode 100644 index 0000000..b814e2d --- /dev/null +++ b/core/tests/coretests/src/android/content/pm/VerificationParamsTest.java @@ -0,0 +1,171 @@ +/* + * 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.content.pm.ManifestDigest; +import android.content.pm.VerificationParams; +import android.net.Uri; +import android.os.Parcel; +import android.test.AndroidTestCase; + +/** + * Tests the android.content.pm.VerificationParams class + * + * To test run: + * ./development/testrunner/runtest.py frameworks-core -c android.content.pm.VerificationParamsTest + */ +public class VerificationParamsTest extends AndroidTestCase { + + private final static String VERIFICATION_URI_STRING = "http://verification.uri/path"; + private final static String ORIGINATING_URI_STRING = "http://originating.uri/path"; + private final static String REFERRER_STRING = "http://referrer.uri/path"; + private final static byte[] DIGEST_BYTES = "fake digest".getBytes(); + + private final static Uri VERIFICATION_URI = Uri.parse(VERIFICATION_URI_STRING); + private final static Uri ORIGINATING_URI = Uri.parse(ORIGINATING_URI_STRING); + private final static Uri REFERRER = Uri.parse(REFERRER_STRING); + + private final static ManifestDigest MANIFEST_DIGEST = new ManifestDigest(DIGEST_BYTES); + + public void testParcel() throws Exception { + VerificationParams expected = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI, + REFERRER, MANIFEST_DIGEST); + + Parcel parcel = Parcel.obtain(); + expected.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + + VerificationParams actual = VerificationParams.CREATOR.createFromParcel(parcel); + + assertEquals(VERIFICATION_URI, actual.getVerificationURI()); + + assertEquals(ORIGINATING_URI, actual.getOriginatingURI()); + + assertEquals(REFERRER, actual.getReferrer()); + + assertEquals(MANIFEST_DIGEST, actual.getManifestDigest()); + } + + public void testEquals_Success() throws Exception { + VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI, + REFERRER, MANIFEST_DIGEST); + + VerificationParams params2 = new VerificationParams( + Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING), + Uri.parse(REFERRER_STRING), new ManifestDigest(DIGEST_BYTES)); + + assertEquals(params1, params2); + } + + public void testEquals_VerificationUri_Failure() throws Exception { + VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI, + REFERRER, MANIFEST_DIGEST); + + VerificationParams params2 = new VerificationParams( + Uri.parse("http://a.different.uri/"), Uri.parse(ORIGINATING_URI_STRING), + Uri.parse(REFERRER_STRING), new ManifestDigest(DIGEST_BYTES)); + + assertFalse(params1.equals(params2)); + } + + public void testEquals_OriginatingUri_Failure() throws Exception { + VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI, + REFERRER, MANIFEST_DIGEST); + + VerificationParams params2 = new VerificationParams( + Uri.parse(VERIFICATION_URI_STRING), Uri.parse("http://a.different.uri/"), + Uri.parse(REFERRER_STRING), new ManifestDigest(DIGEST_BYTES)); + + assertFalse(params1.equals(params2)); + } + + public void testEquals_Referrer_Failure() throws Exception { + VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI, + REFERRER, MANIFEST_DIGEST); + + VerificationParams params2 = new VerificationParams( + Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING), + Uri.parse("http://a.different.uri/"), new ManifestDigest(DIGEST_BYTES)); + + assertFalse(params1.equals(params2)); + } + + public void testEquals_ManifestDigest_Failure() throws Exception { + VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI, + REFERRER, MANIFEST_DIGEST); + + VerificationParams params2 = new VerificationParams( + Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING), + Uri.parse(REFERRER_STRING), new ManifestDigest("a different digest".getBytes())); + + assertFalse(params1.equals(params2)); + } + + public void testHashCode_Success() throws Exception { + VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI, + REFERRER, MANIFEST_DIGEST); + + VerificationParams params2 = new VerificationParams( + Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING), + Uri.parse(REFERRER_STRING), new ManifestDigest(DIGEST_BYTES)); + + assertEquals(params1.hashCode(), params2.hashCode()); + } + + public void testHashCode_VerificationUri_Failure() throws Exception { + VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI, + REFERRER, MANIFEST_DIGEST); + + VerificationParams params2 = new VerificationParams(null, Uri.parse(ORIGINATING_URI_STRING), + Uri.parse(REFERRER_STRING), new ManifestDigest(DIGEST_BYTES)); + + assertFalse(params1.hashCode() == params2.hashCode()); + } + + public void testHashCode_OriginatingUri_Failure() throws Exception { + VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI, + REFERRER, MANIFEST_DIGEST); + + VerificationParams params2 = new VerificationParams( + Uri.parse(VERIFICATION_URI_STRING), Uri.parse("http://a.different.uri/"), + Uri.parse(REFERRER_STRING), new ManifestDigest(DIGEST_BYTES)); + + assertFalse(params1.hashCode() == params2.hashCode()); + } + + public void testHashCode_Referrer_Failure() throws Exception { + VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI, + REFERRER, MANIFEST_DIGEST); + + VerificationParams params2 = new VerificationParams( + Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING), null, + new ManifestDigest(DIGEST_BYTES)); + + assertFalse(params1.hashCode() == params2.hashCode()); + } + + public void testHashCode_ManifestDigest_Failure() throws Exception { + VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI, + REFERRER, MANIFEST_DIGEST); + + VerificationParams params2 = new VerificationParams( + Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING), + Uri.parse(REFERRER_STRING), new ManifestDigest("a different digest".getBytes())); + + assertFalse(params1.hashCode() == params2.hashCode()); + } +} diff --git a/core/tests/coretests/src/android/os/FileUtilsTest.java b/core/tests/coretests/src/android/os/FileUtilsTest.java index f12cbe1..4d0b892 100644 --- a/core/tests/coretests/src/android/os/FileUtilsTest.java +++ b/core/tests/coretests/src/android/os/FileUtilsTest.java @@ -17,21 +17,13 @@ package android.os; import android.content.Context; -import android.os.FileUtils; -import android.os.FileUtils.FileStatus; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.LargeTest; import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.SmallTest; import java.io.ByteArrayInputStream; import java.io.File; -import java.io.FileWriter; -import java.io.FileNotFoundException; import java.io.FileOutputStream; -import java.io.IOException; - -import junit.framework.Assert; +import java.io.FileWriter; public class FileUtilsTest extends AndroidTestCase { private static final String TEST_DATA = @@ -60,60 +52,6 @@ public class FileUtilsTest extends AndroidTestCase { if (mCopyFile.exists()) mCopyFile.delete(); } - @LargeTest - public void testGetFileStatus() { - final byte[] MAGIC = { 0xB, 0xE, 0x0, 0x5 }; - - try { - // truncate test file and write MAGIC (4 bytes) to it. - FileOutputStream os = new FileOutputStream(mTestFile, false); - os.write(MAGIC, 0, 4); - os.flush(); - os.close(); - } catch (FileNotFoundException e) { - Assert.fail("File was removed durning test" + e); - } catch (IOException e) { - Assert.fail("Unexpected IOException: " + e); - } - - Assert.assertTrue(mTestFile.exists()); - Assert.assertTrue(FileUtils.getFileStatus(mTestFile.getPath(), null)); - - FileStatus status1 = new FileStatus(); - FileUtils.getFileStatus(mTestFile.getPath(), status1); - - Assert.assertEquals(4, status1.size); - - // Sleep for at least one second so that the modification time will be different. - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - } - - try { - // append so we don't change the creation time. - FileOutputStream os = new FileOutputStream(mTestFile, true); - os.write(MAGIC, 0, 4); - os.flush(); - os.close(); - } catch (FileNotFoundException e) { - Assert.fail("File was removed durning test" + e); - } catch (IOException e) { - Assert.fail("Unexpected IOException: " + e); - } - - FileStatus status2 = new FileStatus(); - FileUtils.getFileStatus(mTestFile.getPath(), status2); - - Assert.assertEquals(8, status2.size); - Assert.assertTrue(status2.mtime > status1.mtime); - - mTestFile.delete(); - - Assert.assertFalse(mTestFile.exists()); - Assert.assertFalse(FileUtils.getFileStatus(mTestFile.getPath(), null)); - } - // TODO: test setPermissions(), getPermissions() @MediumTest |