diff options
196 files changed, 5442 insertions, 2961 deletions
diff --git a/api/current.txt b/api/current.txt index 180ac91..ee964f7 100644 --- a/api/current.txt +++ b/api/current.txt @@ -102,6 +102,7 @@ package android { field public static final java.lang.String SET_ALWAYS_FINISH = "android.permission.SET_ALWAYS_FINISH"; field public static final java.lang.String SET_ANIMATION_SCALE = "android.permission.SET_ANIMATION_SCALE"; field public static final java.lang.String SET_DEBUG_APP = "android.permission.SET_DEBUG_APP"; + field public static final java.lang.String SET_KEYBOARD_LAYOUT = "android.permission.SET_KEYBOARD_LAYOUT"; field public static final java.lang.String SET_ORIENTATION = "android.permission.SET_ORIENTATION"; field public static final java.lang.String SET_POINTER_SPEED = "android.permission.SET_POINTER_SPEED"; field public static final deprecated java.lang.String SET_PREFERRED_APPLICATIONS = "android.permission.SET_PREFERRED_APPLICATIONS"; @@ -2881,14 +2882,10 @@ package android.app { public class ActivityOptions { method public void join(android.app.ActivityOptions); method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int); - method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int, android.app.ActivityOptions.OnAnimationStartedListener); + method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int); method public android.os.Bundle toBundle(); } - public static abstract interface ActivityOptions.OnAnimationStartedListener { - method public abstract void onAnimationStarted(); - } - public class AlarmManager { method public void cancel(android.app.PendingIntent); method public void set(int, long, android.app.PendingIntent); @@ -22272,6 +22269,7 @@ package android.view { method public java.util.List<android.view.InputDevice.MotionRange> getMotionRanges(); method public java.lang.String getName(); method public int getSources(); + method public boolean isVirtual(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; field public static final int KEYBOARD_TYPE_ALPHABETIC = 2; // 0x2 @@ -22331,7 +22329,8 @@ package android.view { method public abstract void onInputQueueDestroyed(android.view.InputQueue); } - public class KeyCharacterMap { + public class KeyCharacterMap implements android.os.Parcelable { + method public int describeContents(); method public static boolean deviceHasKey(int); method public static boolean[] deviceHasKeys(int[]); method public int get(int, int); @@ -22346,10 +22345,12 @@ package android.view { method public char getNumber(int); method public boolean isPrintingKey(int); method public static android.view.KeyCharacterMap load(int); + method public void writeToParcel(android.os.Parcel, int); field public static final int ALPHA = 3; // 0x3 field public static final deprecated int BUILT_IN_KEYBOARD = 0; // 0x0 field public static final int COMBINING_ACCENT = -2147483648; // 0x80000000 field public static final int COMBINING_ACCENT_MASK = 2147483647; // 0x7fffffff + field public static final android.os.Parcelable.Creator CREATOR; field public static final int FULL = 4; // 0x4 field public static final char HEX_INPUT = 61184; // 0xef00 '\uef00' field public static final int MODIFIER_BEHAVIOR_CHORDED = 0; // 0x0 @@ -23533,6 +23534,10 @@ package android.view { method public void postInvalidate(int, int, int, int); method public void postInvalidateDelayed(long); method public void postInvalidateDelayed(long, int, int, int, int); + method public void postInvalidateOnAnimation(); + method public void postInvalidateOnAnimation(int, int, int, int); + method public void postOnAnimation(java.lang.Runnable); + method public void postOnAnimationDelayed(java.lang.Runnable, long); method public void refreshDrawableState(); method public boolean removeCallbacks(java.lang.Runnable); method public void removeOnAttachStateChangeListener(android.view.View.OnAttachStateChangeListener); diff --git a/cmds/input/src/com/android/commands/input/Input.java b/cmds/input/src/com/android/commands/input/Input.java index 3037881..fcf3c7e 100755 --- a/cmds/input/src/com/android/commands/input/Input.java +++ b/cmds/input/src/com/android/commands/input/Input.java @@ -145,13 +145,15 @@ public class Input { private void injectKeyEvent(KeyEvent event) { Log.i(TAG, "InjectKeyEvent: " + event); - InputManager.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH); + InputManager.getInstance().injectInputEvent(event, + InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH); } private void injectPointerEvent(MotionEvent event) { event.setSource(InputDevice.SOURCE_TOUCHSCREEN); Log.i("Input", "InjectPointerEvent: " + event); - InputManager.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH); + InputManager.getInstance().injectInputEvent(event, + InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH); } private static final float lerp(float a, float b, float alpha) { diff --git a/core/java/android/accounts/AccountAndUser.java b/core/java/android/accounts/AccountAndUser.java new file mode 100644 index 0000000..04157cc --- /dev/null +++ b/core/java/android/accounts/AccountAndUser.java @@ -0,0 +1,49 @@ +/* + * 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.accounts; + +/** + * Used to store the Account and the UserId this account is associated with. + * + * @hide + */ +public class AccountAndUser { + public Account account; + public int userId; + + public AccountAndUser(Account account, int userId) { + this.account = account; + this.userId = userId; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof AccountAndUser)) return false; + final AccountAndUser other = (AccountAndUser) o; + return this.account.equals(other.account) + && this.userId == other.userId; + } + + @Override + public int hashCode() { + return account.hashCode() + userId; + } + + public String toString() { + return account.toString() + " u" + userId; + } +} diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java index 3d5bbd4..2b643c2 100644 --- a/core/java/android/accounts/AccountManagerService.java +++ b/core/java/android/accounts/AccountManagerService.java @@ -1488,6 +1488,31 @@ public class AccountManagerService } } + /** + * Returns all the accounts qualified by user. + * @hide + */ + public AccountAndUser[] getAllAccounts() { + ArrayList<AccountAndUser> allAccounts = new ArrayList<AccountAndUser>(); + List<UserInfo> users = getAllUsers(); + if (users == null) return new AccountAndUser[0]; + + synchronized(mUsers) { + for (UserInfo user : users) { + UserAccounts userAccounts = getUserAccounts(user.id); + if (userAccounts == null) continue; + synchronized (userAccounts.cacheLock) { + Account[] accounts = getAccountsFromCacheLocked(userAccounts, null); + for (int a = 0; a < accounts.length; a++) { + allAccounts.add(new AccountAndUser(accounts[a], user.id)); + } + } + } + } + AccountAndUser[] accountsArray = new AccountAndUser[allAccounts.size()]; + return allAccounts.toArray(accountsArray); + } + public Account[] getAccounts(String type) { if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "getAccounts: accountType " + type diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 7207e29..227900e 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -55,6 +55,7 @@ import android.text.method.TextKeyListener; import android.util.AttributeSet; import android.util.EventLog; import android.util.Log; +import android.util.Slog; import android.util.SparseArray; import android.view.ActionMode; import android.view.ContextMenu; @@ -642,6 +643,7 @@ public class Activity extends ContextThemeWrapper Window.Callback, KeyEvent.Callback, OnCreateContextMenuListener, ComponentCallbacks2 { private static final String TAG = "Activity"; + private static final boolean DEBUG_LIFECYCLE = false; /** Standard activity result: operation canceled. */ public static final int RESULT_CANCELED = 0; @@ -865,6 +867,7 @@ public class Activity extends ContextThemeWrapper * @see #onPostCreate */ protected void onCreate(Bundle savedInstanceState) { + if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState); if (mLastNonConfigurationInstances != null) { mAllLoaderManagers = mLastNonConfigurationInstances.loaders; } @@ -1013,6 +1016,7 @@ public class Activity extends ContextThemeWrapper * @see #onResume */ protected void onStart() { + if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStart " + this); mCalled = true; if (!mLoadersStarted) { @@ -1073,6 +1077,7 @@ public class Activity extends ContextThemeWrapper * @see #onPause */ protected void onResume() { + if (DEBUG_LIFECYCLE) Slog.v(TAG, "onResume " + this); getApplication().dispatchActivityResumed(this); mCalled = true; } @@ -1131,6 +1136,7 @@ public class Activity extends ContextThemeWrapper final void performSaveInstanceState(Bundle outState) { onSaveInstanceState(outState); saveManagedDialogs(outState); + if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState); } /** @@ -1261,6 +1267,7 @@ public class Activity extends ContextThemeWrapper * @see #onStop */ protected void onPause() { + if (DEBUG_LIFECYCLE) Slog.v(TAG, "onPause " + this); getApplication().dispatchActivityPaused(this); mCalled = true; } @@ -1347,6 +1354,7 @@ public class Activity extends ContextThemeWrapper * @see #onDestroy */ protected void onStop() { + if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStop " + this); if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(false); getApplication().dispatchActivityStopped(this); mCalled = true; @@ -1381,6 +1389,7 @@ public class Activity extends ContextThemeWrapper * @see #isFinishing */ protected void onDestroy() { + if (DEBUG_LIFECYCLE) Slog.v(TAG, "onDestroy " + this); mCalled = true; // dismiss any dialogs we are managing. @@ -1432,6 +1441,7 @@ public class Activity extends ContextThemeWrapper * @param newConfig The new device configuration. */ public void onConfigurationChanged(Configuration newConfig) { + if (DEBUG_LIFECYCLE) Slog.v(TAG, "onConfigurationChanged " + this + ": " + newConfig); mCalled = true; mFragments.dispatchConfigurationChanged(newConfig); @@ -1613,11 +1623,13 @@ public class Activity extends ContextThemeWrapper } public void onLowMemory() { + if (DEBUG_LIFECYCLE) Slog.v(TAG, "onLowMemory " + this); mCalled = true; mFragments.dispatchLowMemory(); } public void onTrimMemory(int level) { + if (DEBUG_LIFECYCLE) Slog.v(TAG, "onTrimMemory " + this + ": " + level); mCalled = true; mFragments.dispatchTrimMemory(level); } diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index c637df0..c3cceaf 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -21,7 +21,6 @@ import android.graphics.Bitmap; import android.os.Bundle; import android.os.Handler; import android.os.IRemoteCallback; -import android.os.Message; import android.os.RemoteException; import android.view.View; @@ -121,6 +120,7 @@ public class ActivityOptions { /** * Callback for use with {@link ActivityOptions#makeThumbnailScaleUpAnimation} * to find out when the given animation has started running. + * @hide */ public interface OnAnimationStartedListener { void onAnimationStarted(); @@ -137,11 +137,31 @@ public class ActivityOptions { * of the animation. * @param startX The x starting location of the bitmap, in screen coordiantes. * @param startY The y starting location of the bitmap, in screen coordinates. + * @return Returns a new ActivityOptions object that you can use to + * supply these options as the options Bundle when starting an activity. + */ + public static ActivityOptions makeThumbnailScaleUpAnimation(View source, + Bitmap thumbnail, int startX, int startY) { + return makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY, null); + } + + /** + * Create an ActivityOptions specifying an animation where a thumbnail + * is scaled from a given position to the new activity window that is + * being started. + * + * @param source The View that this thumbnail is animating from. 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 + * of the animation. + * @param startX The x starting location of the bitmap, in screen coordiantes. + * @param startY The y starting location of the bitmap, in screen coordinates. * @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. * @return Returns a new ActivityOptions object that you can use to * supply these options as the options Bundle when starting an activity. + * @hide */ public static ActivityOptions makeThumbnailScaleUpAnimation(View source, Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) { diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 98c4e10..1489b2c 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -138,6 +138,7 @@ public final class ActivityThread { private static final boolean DEBUG_BACKUP = true; private static final boolean DEBUG_CONFIGURATION = false; private static final boolean DEBUG_SERVICE = false; + private static final boolean DEBUG_MEMORY_TRIM = false; private static final long MIN_TIME_BETWEEN_GCS = 5*1000; private static final Pattern PATTERN_SEMICOLON = Pattern.compile(";"); private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003; @@ -2779,9 +2780,21 @@ public final class ActivityThread { performStopActivityInner(r, null, false, saveState); } - private static class StopInfo { + private static class StopInfo implements Runnable { + ActivityClientRecord activity; + Bundle state; Bitmap thumbnail; CharSequence description; + + @Override public void run() { + // Tell activity manager we have been stopped. + try { + if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity); + ActivityManagerNative.getDefault().activityStopped( + activity.token, state, thumbnail, description); + } catch (RemoteException ex) { + } + } } private static final class ProviderRefCount { @@ -2911,12 +2924,14 @@ public final class ActivityThread { QueuedWork.waitToFinish(); } - // Tell activity manager we have been stopped. - try { - ActivityManagerNative.getDefault().activityStopped( - r.token, r.state, info.thumbnail, info.description); - } catch (RemoteException ex) { - } + // Schedule the call to tell the activity manager we have + // stopped. We don't do this immediately, because we want to + // have a chance for any other pending work (in particular memory + // trim requests) to complete before you tell the activity + // manager to proceed and allow us to go fully into the background. + info.activity = r; + info.state = r.state; + mH.post(info); } final void performRestartActivity(IBinder token) { @@ -3749,6 +3764,7 @@ public final class ActivityThread { } final void handleTrimMemory(int level) { + if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level); WindowManagerImpl.getDefault().trimMemory(level); ArrayList<ComponentCallbacks2> callbacks; diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index c5d7b91..138a88f 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -325,9 +325,9 @@ class ContextImpl extends Context { return createDropBoxManager(); }}); - registerService(INPUT_SERVICE, new ServiceFetcher() { - public Object createService(ContextImpl ctx) { - return new InputManager(ctx); + registerService(INPUT_SERVICE, new StaticServiceFetcher() { + public Object createStaticService() { + return InputManager.getInstance(); }}); registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() { diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java index f955713..75c6e11 100644 --- a/core/java/android/app/Instrumentation.java +++ b/core/java/android/app/Instrumentation.java @@ -883,7 +883,7 @@ public class Instrumentation { } KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState, deviceId, scancode, flags | KeyEvent.FLAG_FROM_SYSTEM, source); - InputManager.injectInputEvent(newEvent, + InputManager.getInstance().injectInputEvent(newEvent, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH); } @@ -926,7 +926,8 @@ public class Instrumentation { if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) { event.setSource(InputDevice.SOURCE_TOUCHSCREEN); } - InputManager.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH); + InputManager.getInstance().injectInputEvent(event, + InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH); } /** @@ -945,7 +946,8 @@ public class Instrumentation { if ((event.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) { event.setSource(InputDevice.SOURCE_TRACKBALL); } - InputManager.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH); + InputManager.getInstance().injectInputEvent(event, + InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH); } /** diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java index 06dfe90..6219de7 100644 --- a/core/java/android/content/SyncManager.java +++ b/core/java/android/content/SyncManager.java @@ -22,6 +22,7 @@ import com.google.android.collect.Lists; import com.google.android.collect.Maps; import android.accounts.Account; +import android.accounts.AccountAndUser; import android.accounts.AccountManager; import android.accounts.AccountManagerService; import android.accounts.OnAccountsUpdateListener; @@ -237,22 +238,14 @@ public class SyncManager implements OnAccountsUpdateListener { int count = 0; - // For all known users on the system, get their accounts and add them to the list + // Get accounts from AccountManager for all the users on the system // TODO: Limit this to active users, when such a concept exists. + AccountAndUser[] allAccounts = AccountManagerService.getSingleton().getAllAccounts(); for (UserInfo user : users) { - accounts = AccountManagerService.getSingleton().getAccounts(user.id); - count += accounts.length; - } - - AccountAndUser[] allAccounts = new AccountAndUser[count]; - int index = 0; - for (UserInfo user : users) { - accounts = AccountManagerService.getSingleton().getAccounts(user.id); - for (Account account : accounts) { - allAccounts[index++] = new AccountAndUser(account, user.id); - } if (mBootCompleted) { - mSyncStorageEngine.doDatabaseCleanup(accounts, user.id); + Account[] accountsForUser = + AccountManagerService.getSingleton().getAccounts(user.id); + mSyncStorageEngine.doDatabaseCleanup(accountsForUser, user.id); } } @@ -338,33 +331,6 @@ public class SyncManager implements OnAccountsUpdateListener { private volatile boolean mBootCompleted = false; - static class AccountAndUser { - Account account; - int userId; - - AccountAndUser(Account account, int userId) { - this.account = account; - this.userId = userId; - } - - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof AccountAndUser)) return false; - final AccountAndUser other = (AccountAndUser) o; - return this.account.equals(other.account) - && this.userId == other.userId; - } - - @Override - public int hashCode() { - return account.hashCode() + userId; - } - - public String toString() { - return account.toString() + " u" + userId; - } - } - private ConnectivityManager getConnectivityManager() { synchronized (this) { if (mConnManagerDoNotUseDirectly == null) { diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java index 9c81c9e..d3baf70 100644 --- a/core/java/android/content/SyncStorageEngine.java +++ b/core/java/android/content/SyncStorageEngine.java @@ -25,7 +25,7 @@ import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; import android.accounts.Account; -import android.content.SyncManager.AccountAndUser; +import android.accounts.AccountAndUser; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl index c2abce5..47e0d1e 100644 --- a/core/java/android/hardware/input/IInputManager.aidl +++ b/core/java/android/hardware/input/IInputManager.aidl @@ -16,6 +16,7 @@ package android.hardware.input; +import android.hardware.input.KeyboardLayout; import android.view.InputDevice; import android.view.InputEvent; @@ -34,4 +35,11 @@ interface IInputManager { // Injects an input event into the system. To inject into windows owned by other // applications, the caller must have the INJECT_EVENTS permission. boolean injectInputEvent(in InputEvent ev, int mode); + + // Keyboard layouts configuration. + KeyboardLayout[] getKeyboardLayouts(); + KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor); + String getKeyboardLayoutForInputDevice(String inputDeviceDescriptor); + void setKeyboardLayoutForInputDevice(String inputDeviceDescriptor, + String keyboardLayoutDescriptor); } diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java index 5ead1f4..3b3c237 100755 --- a/core/java/android/hardware/input/InputManager.java +++ b/core/java/android/hardware/input/InputManager.java @@ -16,37 +16,18 @@ package android.hardware.input; -import com.android.internal.util.XmlUtils; - import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; -import android.content.ComponentName; import android.content.Context; -import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.content.res.XmlResourceParser; -import android.os.Bundle; import android.os.IBinder; -import android.os.Parcel; -import android.os.Parcelable; import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import android.util.Log; +import android.util.SparseArray; import android.view.InputDevice; import android.view.InputEvent; -import android.view.KeyCharacterMap; -import android.view.KeyCharacterMap.UnavailableException; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; /** * Provides information about input devices and available key layouts. @@ -60,13 +41,10 @@ import java.util.List; public final class InputManager { private static final String TAG = "InputManager"; - private static final IInputManager sIm; - - private final Context mContext; + private static InputManager sInstance; - // Used to simulate a persistent data store. - // TODO: Replace with the real thing. - private static final HashMap<String, String> mFakeRegistry = new HashMap<String, String>(); + private final IInputManager mIm; + private final SparseArray<InputDevice> mInputDevices = new SparseArray<InputDevice>(); /** * Broadcast Action: Query available keyboard layouts. @@ -169,14 +147,25 @@ public final class InputManager { */ public static final int INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH = 2; // see InputDispatcher.h - static { - IBinder b = ServiceManager.getService(Context.INPUT_SERVICE); - sIm = IInputManager.Stub.asInterface(b); + private InputManager(IInputManager im) { + mIm = im; } - /** @hide */ - public InputManager(Context context) { - mContext = context; + /** + * Gets an instance of the input manager. + * + * @return The input manager instance. + * + * @hide + */ + public static InputManager getInstance() { + synchronized (InputManager.class) { + if (sInstance == null) { + IBinder b = ServiceManager.getService(Context.INPUT_SERVICE); + sInstance = new InputManager(IInputManager.Stub.asInterface(b)); + } + return sInstance; + } } /** @@ -188,18 +177,16 @@ public final class InputManager { * </p> * * @return A list of all supported keyboard layouts. + * * @hide */ - public List<KeyboardLayout> getKeyboardLayouts() { - ArrayList<KeyboardLayout> list = new ArrayList<KeyboardLayout>(); - - final PackageManager pm = mContext.getPackageManager(); - Intent intent = new Intent(ACTION_QUERY_KEYBOARD_LAYOUTS); - for (ResolveInfo resolveInfo : pm.queryBroadcastReceivers(intent, - PackageManager.GET_META_DATA)) { - loadKeyboardLayouts(pm, resolveInfo.activityInfo, list, null); + public KeyboardLayout[] getKeyboardLayouts() { + try { + return mIm.getKeyboardLayouts(); + } catch (RemoteException ex) { + Log.w(TAG, "Could not get list of keyboard layout informations.", ex); + return new KeyboardLayout[0]; } - return list; } /** @@ -216,20 +203,10 @@ public final class InputManager { throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null"); } - KeyboardLayoutDescriptor d = parseKeyboardLayoutDescriptor(keyboardLayoutDescriptor); - if (d == null) { - return null; - } - - final PackageManager pm = mContext.getPackageManager(); try { - ActivityInfo receiver = pm.getReceiverInfo( - new ComponentName(d.packageName, d.receiverName), - PackageManager.GET_META_DATA); - return loadKeyboardLayouts(pm, receiver, null, d.keyboardLayoutName); - } catch (NameNotFoundException ex) { - Log.w(TAG, "Could not load keyboard layout '" + d.keyboardLayoutName - + "' from receiver " + d.packageName + "/" + d.receiverName, ex); + return mIm.getKeyboardLayout(keyboardLayoutDescriptor); + } catch (RemoteException ex) { + Log.w(TAG, "Could not get keyboard layout information.", ex); return null; } } @@ -243,12 +220,17 @@ public final class InputManager { * * @hide */ - public String getInputDeviceKeyboardLayoutDescriptor(String inputDeviceDescriptor) { + public String getKeyboardLayoutForInputDevice(String inputDeviceDescriptor) { if (inputDeviceDescriptor == null) { throw new IllegalArgumentException("inputDeviceDescriptor must not be null"); } - return mFakeRegistry.get(inputDeviceDescriptor); + try { + return mIm.getKeyboardLayoutForInputDevice(inputDeviceDescriptor); + } catch (RemoteException ex) { + Log.w(TAG, "Could not get keyboard layout for input device.", ex); + return null; + } } /** @@ -264,92 +246,17 @@ public final class InputManager { * * @hide */ - public void setInputDeviceKeyboardLayoutDescriptor(String inputDeviceDescriptor, + public void setKeyboardLayoutForInputDevice(String inputDeviceDescriptor, String keyboardLayoutDescriptor) { if (inputDeviceDescriptor == null) { throw new IllegalArgumentException("inputDeviceDescriptor must not be null"); } - mFakeRegistry.put(inputDeviceDescriptor, keyboardLayoutDescriptor); - } - - private KeyboardLayout loadKeyboardLayouts( - PackageManager pm, ActivityInfo receiver, - List<KeyboardLayout> list, String keyboardName) { - Bundle metaData = receiver.metaData; - if (metaData == null) { - return null; - } - - int configResId = metaData.getInt(META_DATA_KEYBOARD_LAYOUTS); - if (configResId == 0) { - Log.w(TAG, "Missing meta-data '" + META_DATA_KEYBOARD_LAYOUTS + "' on receiver " - + receiver.packageName + "/" + receiver.name); - return null; - } - try { - Resources resources = pm.getResourcesForApplication(receiver.applicationInfo); - XmlResourceParser parser = resources.getXml(configResId); - try { - XmlUtils.beginDocument(parser, "keyboard-layouts"); - - for (;;) { - XmlUtils.nextElement(parser); - String element = parser.getName(); - if (element == null) { - break; - } - if (element.equals("keyboard-layout")) { - TypedArray a = resources.obtainAttributes( - parser, com.android.internal.R.styleable.KeyboardLayout); - try { - String name = a.getString( - com.android.internal.R.styleable.KeyboardLayout_name); - String label = a.getString( - com.android.internal.R.styleable.KeyboardLayout_label); - int kcmResId = a.getResourceId( - com.android.internal.R.styleable.KeyboardLayout_kcm, 0); - if (name == null || label == null || kcmResId == 0) { - Log.w(TAG, "Missing required 'name', 'label' or 'kcm' " - + "attributes in keyboard layout " - + "resource from receiver " - + receiver.packageName + "/" + receiver.name); - } else { - String descriptor = makeKeyboardLayoutDescriptor( - receiver.packageName, receiver.name, name); - KeyboardLayout c = new KeyboardLayout( - descriptor, label, kcmResId); - if (keyboardName != null && name.equals(keyboardName)) { - return c; - } - if (list != null) { - list.add(c); - } - } - } finally { - a.recycle(); - } - } else { - Log.w(TAG, "Skipping unrecognized element '" + element - + "' in keyboard layout resource from receiver " - + receiver.packageName + "/" + receiver.name); - } - } - } finally { - parser.close(); - } - } catch (Exception ex) { - Log.w(TAG, "Could not load keyboard layout resource from receiver " - + receiver.packageName + "/" + receiver.name, ex); - return null; - } - if (keyboardName != null) { - Log.w(TAG, "Could not load keyboard layout '" + keyboardName - + "' from receiver " + receiver.packageName + "/" + receiver.name - + " because it was not declared in the keyboard layout resource."); + mIm.setKeyboardLayoutForInputDevice(inputDeviceDescriptor, keyboardLayoutDescriptor); + } catch (RemoteException ex) { + Log.w(TAG, "Could not set keyboard layout for input device.", ex); } - return null; } /** @@ -359,15 +266,16 @@ public final class InputManager { * speed set by {@link #tryPointerSpeed}. * </p> * + * @param context The application context. * @return The pointer speed as a value between {@link #MIN_POINTER_SPEED} and * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. * * @hide */ - public int getPointerSpeed() { + public int getPointerSpeed(Context context) { int speed = DEFAULT_POINTER_SPEED; try { - speed = Settings.System.getInt(mContext.getContentResolver(), + speed = Settings.System.getInt(context.getContentResolver(), Settings.System.POINTER_SPEED); } catch (SettingNotFoundException snfe) { } @@ -380,17 +288,18 @@ public final class InputManager { * Requires {@link android.Manifest.permissions.WRITE_SETTINGS}. * </p> * + * @param context The application context. * @param speed The pointer speed as a value between {@link #MIN_POINTER_SPEED} and * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. * * @hide */ - public void setPointerSpeed(int speed) { + public void setPointerSpeed(Context context, int speed) { if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) { throw new IllegalArgumentException("speed out of range"); } - Settings.System.putInt(mContext.getContentResolver(), + Settings.System.putInt(context.getContentResolver(), Settings.System.POINTER_SPEED, speed); } @@ -411,7 +320,7 @@ public final class InputManager { } try { - sIm.tryPointerSpeed(speed); + mIm.tryPointerSpeed(speed); } catch (RemoteException ex) { Log.w(TAG, "Could not set temporary pointer speed.", ex); } @@ -424,12 +333,27 @@ public final class InputManager { * * @hide */ - public static InputDevice getInputDevice(int id) { + public InputDevice getInputDevice(int id) { + synchronized (mInputDevices) { + InputDevice inputDevice = mInputDevices.get(id); + if (inputDevice != null) { + return inputDevice; + } + } + final InputDevice newInputDevice; try { - return sIm.getInputDevice(id); + newInputDevice = mIm.getInputDevice(id); } catch (RemoteException ex) { throw new RuntimeException("Could not get input device information.", ex); } + synchronized (mInputDevices) { + InputDevice inputDevice = mInputDevices.get(id); + if (inputDevice != null) { + return inputDevice; + } + mInputDevices.put(id, newInputDevice); + return newInputDevice; + } } /** @@ -438,9 +362,9 @@ public final class InputManager { * * @hide */ - public static int[] getInputDeviceIds() { + public int[] getInputDeviceIds() { try { - return sIm.getInputDeviceIds(); + return mIm.getInputDeviceIds(); } catch (RemoteException ex) { throw new RuntimeException("Could not get input device ids.", ex); } @@ -458,10 +382,10 @@ public final class InputManager { * * @hide */ - public static boolean[] deviceHasKeys(int[] keyCodes) { + public boolean[] deviceHasKeys(int[] keyCodes) { boolean[] ret = new boolean[keyCodes.length]; try { - sIm.hasKeys(-1, InputDevice.SOURCE_ANY, keyCodes, ret); + mIm.hasKeys(-1, InputDevice.SOURCE_ANY, keyCodes, ret); } catch (RemoteException e) { // no fallback; just return the empty array } @@ -489,7 +413,7 @@ public final class InputManager { * * @hide */ - public static boolean injectInputEvent(InputEvent event, int mode) { + public boolean injectInputEvent(InputEvent event, int mode) { if (event == null) { throw new IllegalArgumentException("event must not be null"); } @@ -500,152 +424,9 @@ public final class InputManager { } try { - return sIm.injectInputEvent(event, mode); + return mIm.injectInputEvent(event, mode); } catch (RemoteException ex) { return false; } } - - private static String makeKeyboardLayoutDescriptor(String packageName, - String receiverName, String keyboardName) { - return packageName + "/" + receiverName + "/" + keyboardName; - } - - private static KeyboardLayoutDescriptor parseKeyboardLayoutDescriptor(String descriptor) { - int pos = descriptor.indexOf('/'); - if (pos < 0 || pos + 1 == descriptor.length()) { - return null; - } - int pos2 = descriptor.indexOf('/', pos + 1); - if (pos2 < pos + 2 || pos2 + 1 == descriptor.length()) { - return null; - } - - KeyboardLayoutDescriptor result = new KeyboardLayoutDescriptor(); - result.packageName = descriptor.substring(0, pos); - result.receiverName = descriptor.substring(pos + 1, pos2); - result.keyboardLayoutName = descriptor.substring(pos2 + 1); - return result; - } - - /** - * Describes a keyboard layout. - * - * @hide - */ - public static final class KeyboardLayout implements Parcelable, - Comparable<KeyboardLayout> { - private final String mDescriptor; - private final String mLabel; - private final int mKeyCharacterMapResId; - - private KeyCharacterMap mKeyCharacterMap; - - public static final Parcelable.Creator<KeyboardLayout> CREATOR = - new Parcelable.Creator<KeyboardLayout>() { - public KeyboardLayout createFromParcel(Parcel source) { - return new KeyboardLayout(source); - } - public KeyboardLayout[] newArray(int size) { - return new KeyboardLayout[size]; - } - }; - - private KeyboardLayout(String descriptor, - String label, int keyCharacterMapResId) { - mDescriptor = descriptor; - mLabel = label; - mKeyCharacterMapResId = keyCharacterMapResId; - } - - private KeyboardLayout(Parcel source) { - mDescriptor = source.readString(); - mLabel = source.readString(); - mKeyCharacterMapResId = source.readInt(); - } - - /** - * Gets the keyboard layout descriptor, which can be used to retrieve - * the keyboard layout again later using - * {@link InputManager#getKeyboardLayout(String)}. - * - * @return The keyboard layout descriptor. - */ - public String getDescriptor() { - return mDescriptor; - } - - /** - * Gets the keyboard layout descriptive label to show in the user interface. - * @return The keyboard layout descriptive label. - */ - public String getLabel() { - return mLabel; - } - - /** - * Loads the key character map associated with the keyboard layout. - * - * @param pm The package manager. - * @return The key character map, or null if it could not be loaded for any reason. - */ - public KeyCharacterMap loadKeyCharacterMap(PackageManager pm) { - if (pm == null) { - throw new IllegalArgumentException("pm must not be null"); - } - - if (mKeyCharacterMap == null) { - KeyboardLayoutDescriptor d = parseKeyboardLayoutDescriptor(mDescriptor); - if (d == null) { - Log.e(TAG, "Could not load key character map '" + mDescriptor - + "' because the descriptor could not be parsed."); - return null; - } - - CharSequence cs = pm.getText(d.packageName, mKeyCharacterMapResId, null); - if (cs == null) { - Log.e(TAG, "Could not load key character map '" + mDescriptor - + "' because its associated resource could not be loaded."); - return null; - } - - try { - mKeyCharacterMap = KeyCharacterMap.load(cs); - } catch (UnavailableException ex) { - Log.e(TAG, "Could not load key character map '" + mDescriptor - + "' due to an error while parsing.", ex); - return null; - } - } - return mKeyCharacterMap; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(mDescriptor); - dest.writeString(mLabel); - dest.writeInt(mKeyCharacterMapResId); - } - - @Override - public int compareTo(KeyboardLayout another) { - return mLabel.compareToIgnoreCase(another.mLabel); - } - - @Override - public String toString() { - return mLabel; - } - } - - private static final class KeyboardLayoutDescriptor { - public String packageName; - public String receiverName; - public String keyboardLayoutName; - } } diff --git a/core/java/android/hardware/input/KeyboardLayout.aidl b/core/java/android/hardware/input/KeyboardLayout.aidl new file mode 100644 index 0000000..226e384 --- /dev/null +++ b/core/java/android/hardware/input/KeyboardLayout.aidl @@ -0,0 +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. + */ + +package android.hardware.input; + +parcelable KeyboardLayout; diff --git a/core/java/android/hardware/input/KeyboardLayout.java b/core/java/android/hardware/input/KeyboardLayout.java new file mode 100644 index 0000000..e75a6dc --- /dev/null +++ b/core/java/android/hardware/input/KeyboardLayout.java @@ -0,0 +1,91 @@ +/* + * 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.hardware.input; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Describes a keyboard layout. + * + * @hide + */ +public final class KeyboardLayout implements Parcelable, + Comparable<KeyboardLayout> { + private final String mDescriptor; + private final String mLabel; + + public static final Parcelable.Creator<KeyboardLayout> CREATOR = + new Parcelable.Creator<KeyboardLayout>() { + public KeyboardLayout createFromParcel(Parcel source) { + return new KeyboardLayout(source); + } + public KeyboardLayout[] newArray(int size) { + return new KeyboardLayout[size]; + } + }; + + public KeyboardLayout(String descriptor, String label) { + mDescriptor = descriptor; + mLabel = label; + } + + private KeyboardLayout(Parcel source) { + mDescriptor = source.readString(); + mLabel = source.readString(); + } + + /** + * Gets the keyboard layout descriptor, which can be used to retrieve + * the keyboard layout again later using + * {@link InputManager#getKeyboardLayout(String)}. + * + * @return The keyboard layout descriptor. + */ + public String getDescriptor() { + return mDescriptor; + } + + /** + * Gets the keyboard layout descriptive label to show in the user interface. + * @return The keyboard layout descriptive label. + */ + public String getLabel() { + return mLabel; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(mDescriptor); + dest.writeString(mLabel); + } + + @Override + public int compareTo(KeyboardLayout another) { + return mLabel.compareToIgnoreCase(another.mLabel); + } + + @Override + public String toString() { + return mLabel; + } +}
\ No newline at end of file diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java index 0f8efd1..6056c75 100644 --- a/core/java/android/text/SpannableStringBuilder.java +++ b/core/java/android/text/SpannableStringBuilder.java @@ -18,6 +18,7 @@ package android.text; import android.graphics.Canvas; import android.graphics.Paint; +import android.util.Log; import com.android.internal.util.ArrayUtils; @@ -485,15 +486,12 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable // 0-length Spanned.SPAN_EXCLUSIVE_EXCLUSIVE if (flagsStart == POINT && flagsEnd == MARK && start == end) { - if (send) { - throw new IllegalArgumentException( - "SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length"); - } else { - // Silently ignore invalid spans when they are created from this class. - // This avoids the duplication of the above test code before all the - // calls to setSpan that are done in this class - return; - } + if (send) Log.e("SpannableStringBuilder", + "SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length"); + // Silently ignore invalid spans when they are created from this class. + // This avoids the duplication of the above test code before all the + // calls to setSpan that are done in this class + return; } int nstart = start; diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java index 6f8d09b..75b2c746 100755 --- a/core/java/android/view/InputDevice.java +++ b/core/java/android/view/InputDevice.java @@ -39,13 +39,12 @@ import java.util.List; * </p> */ public final class InputDevice implements Parcelable { - private int mId; - private String mName; - private String mDescriptor; - private int mSources; - private int mKeyboardType; - private String mKeyCharacterMapFile; - + private final int mId; + private final String mName; + private final String mDescriptor; + private final int mSources; + private final int mKeyboardType; + private final KeyCharacterMap mKeyCharacterMap; private final ArrayList<MotionRange> mMotionRanges = new ArrayList<MotionRange>(); /** @@ -292,8 +291,43 @@ public final class InputDevice implements Parcelable { */ public static final int KEYBOARD_TYPE_ALPHABETIC = 2; + public static final Parcelable.Creator<InputDevice> CREATOR = + new Parcelable.Creator<InputDevice>() { + public InputDevice createFromParcel(Parcel in) { + return new InputDevice(in); + } + public InputDevice[] newArray(int size) { + return new InputDevice[size]; + } + }; + // Called by native code. - private InputDevice() { + private InputDevice(int id, String name, String descriptor, int sources, + int keyboardType, KeyCharacterMap keyCharacterMap) { + mId = id; + mName = name; + mDescriptor = descriptor; + mSources = sources; + mKeyboardType = keyboardType; + mKeyCharacterMap = keyCharacterMap; + } + + private InputDevice(Parcel in) { + mId = in.readInt(); + mName = in.readString(); + mDescriptor = in.readString(); + mSources = in.readInt(); + mKeyboardType = in.readInt(); + mKeyCharacterMap = KeyCharacterMap.CREATOR.createFromParcel(in); + + for (;;) { + int axis = in.readInt(); + if (axis < 0) { + break; + } + addMotionRange(axis, in.readInt(), + in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat()); + } } /** @@ -302,7 +336,7 @@ public final class InputDevice implements Parcelable { * @return The input device or null if not found. */ public static InputDevice getDevice(int id) { - return InputManager.getInputDevice(id); + return InputManager.getInstance().getInputDevice(id); } /** @@ -310,7 +344,7 @@ public final class InputDevice implements Parcelable { * @return The input device ids. */ public static int[] getDeviceIds() { - return InputManager.getInputDeviceIds(); + return InputManager.getInstance().getInputDeviceIds(); } /** @@ -356,6 +390,22 @@ public final class InputDevice implements Parcelable { } /** + * Returns true if the device is a virtual input device rather than a real one, + * such as the virtual keyboard (see {@link KeyCharacterMap#VIRTUAL_KEYBOARD}). + * <p> + * Virtual input devices are provided to implement system-level functionality + * and should not be seen or configured by users. + * </p> + * + * @return True if the device is virtual. + * + * @see KeyCharacterMap#VIRTUAL_KEYBOARD + */ + public boolean isVirtual() { + return mId < 0; + } + + /** * Gets the name of this input device. * @return The input device name. */ @@ -384,11 +434,7 @@ public final class InputDevice implements Parcelable { * @return The key character map. */ public KeyCharacterMap getKeyCharacterMap() { - return KeyCharacterMap.load(mId); - } - - String getKeyCharacterMapFile() { - return mKeyCharacterMapFile; + return mKeyCharacterMap; } /** @@ -453,6 +499,7 @@ public final class InputDevice implements Parcelable { return mMotionRanges; } + // Called from native code. private void addMotionRange(int axis, int source, float min, float max, float flat, float fuzz) { mMotionRanges.add(new MotionRange(axis, source, min, max, flat, fuzz)); @@ -545,37 +592,6 @@ public final class InputDevice implements Parcelable { } } - public static final Parcelable.Creator<InputDevice> CREATOR - = new Parcelable.Creator<InputDevice>() { - public InputDevice createFromParcel(Parcel in) { - InputDevice result = new InputDevice(); - result.readFromParcel(in); - return result; - } - - public InputDevice[] newArray(int size) { - return new InputDevice[size]; - } - }; - - private void readFromParcel(Parcel in) { - mId = in.readInt(); - mName = in.readString(); - mDescriptor = in.readString(); - mSources = in.readInt(); - mKeyboardType = in.readInt(); - mKeyCharacterMapFile = in.readString(); - - for (;;) { - int axis = in.readInt(); - if (axis < 0) { - break; - } - addMotionRange(axis, in.readInt(), - in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat()); - } - } - @Override public void writeToParcel(Parcel out, int flags) { out.writeInt(mId); @@ -583,7 +599,7 @@ public final class InputDevice implements Parcelable { out.writeString(mDescriptor); out.writeInt(mSources); out.writeInt(mKeyboardType); - out.writeString(mKeyCharacterMapFile); + mKeyCharacterMap.writeToParcel(out, flags); final int numRanges = mMotionRanges.size(); for (int i = 0; i < numRanges; i++) { @@ -623,8 +639,6 @@ public final class InputDevice implements Parcelable { } description.append("\n"); - description.append(" Key Character Map: ").append(mKeyCharacterMapFile).append("\n"); - description.append(" Sources: 0x").append(Integer.toHexString(mSources)).append(" ("); appendSourceDescriptionIfApplicable(description, SOURCE_KEYBOARD, "keyboard"); appendSourceDescriptionIfApplicable(description, SOURCE_DPAD, "dpad"); diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java index b03f086..3d165ea 100644 --- a/core/java/android/view/KeyCharacterMap.java +++ b/core/java/android/view/KeyCharacterMap.java @@ -16,18 +16,21 @@ package android.view; +import android.os.Parcel; +import android.os.Parcelable; import android.text.method.MetaKeyKeyListener; import android.util.AndroidRuntimeException; import android.util.SparseIntArray; import android.hardware.input.InputManager; import android.util.SparseArray; +import android.view.InputDevice.MotionRange; import java.lang.Character; /** * Describes the keys provided by a keyboard device and their associated labels. */ -public class KeyCharacterMap { +public class KeyCharacterMap implements Parcelable { /** * The id of the device's primary built in keyboard is always 0. * @@ -134,12 +137,20 @@ public class KeyCharacterMap { */ public static final int MODIFIER_BEHAVIOR_CHORDED_OR_TOGGLED = 1; - private static SparseArray<KeyCharacterMap> sInstances = new SparseArray<KeyCharacterMap>(); + public static final Parcelable.Creator<KeyCharacterMap> CREATOR = + new Parcelable.Creator<KeyCharacterMap>() { + public KeyCharacterMap createFromParcel(Parcel in) { + return new KeyCharacterMap(in); + } + public KeyCharacterMap[] newArray(int size) { + return new KeyCharacterMap[size]; + } + }; - private final int mDeviceId; private int mPtr; - private static native int nativeLoad(String file); + private static native int nativeReadFromParcel(Parcel in); + private static native void nativeWriteToParcel(int ptr, Parcel out); private static native void nativeDispose(int ptr); private static native char nativeGetCharacter(int ptr, int keyCode, int metaState); @@ -149,10 +160,20 @@ public class KeyCharacterMap { private static native char nativeGetMatch(int ptr, int keyCode, char[] chars, int metaState); private static native char nativeGetDisplayLabel(int ptr, int keyCode); private static native int nativeGetKeyboardType(int ptr); - private static native KeyEvent[] nativeGetEvents(int ptr, int deviceId, char[] chars); + private static native KeyEvent[] nativeGetEvents(int ptr, char[] chars); + + private KeyCharacterMap(Parcel in) { + if (in == null) { + throw new IllegalArgumentException("parcel must not be null"); + } + mPtr = nativeReadFromParcel(in); + if (mPtr == 0) { + throw new RuntimeException("Could not read KeyCharacterMap from parcel."); + } + } - private KeyCharacterMap(int deviceId, int ptr) { - mDeviceId = deviceId; + // Called from native + private KeyCharacterMap(int ptr) { mPtr = ptr; } @@ -174,33 +195,16 @@ public class KeyCharacterMap { * is missing from the system. */ public static KeyCharacterMap load(int deviceId) { - synchronized (sInstances) { - KeyCharacterMap map = sInstances.get(deviceId); - if (map == null) { - String kcm = null; - if (deviceId != VIRTUAL_KEYBOARD) { - InputDevice device = InputDevice.getDevice(deviceId); - if (device != null) { - kcm = device.getKeyCharacterMapFile(); - } - } - if (kcm == null || kcm.length() == 0) { - kcm = "/system/usr/keychars/Virtual.kcm"; - } - int ptr = nativeLoad(kcm); // might throw - map = new KeyCharacterMap(deviceId, ptr); - sInstances.put(deviceId, map); + final InputManager im = InputManager.getInstance(); + InputDevice inputDevice = im.getInputDevice(deviceId); + if (inputDevice == null) { + inputDevice = im.getInputDevice(VIRTUAL_KEYBOARD); + if (inputDevice == null) { + throw new UnavailableException( + "Could not load key character map for device " + deviceId); } - return map; } - } - - /** - * TODO implement this - * @hide - */ - public static KeyCharacterMap load(CharSequence contents) { - return null; + return inputDevice.getKeyCharacterMap(); } /** @@ -437,7 +441,7 @@ public class KeyCharacterMap { if (chars == null) { throw new IllegalArgumentException("chars must not be null."); } - return nativeGetEvents(mPtr, mDeviceId, chars); + return nativeGetEvents(mPtr, chars); } /** @@ -527,7 +531,7 @@ public class KeyCharacterMap { * @return True if at least one attached keyboard supports the specified key code. */ public static boolean deviceHasKey(int keyCode) { - return InputManager.deviceHasKeys(new int[] { keyCode })[0]; + return InputManager.getInstance().deviceHasKeys(new int[] { keyCode })[0]; } /** @@ -541,7 +545,20 @@ public class KeyCharacterMap { * at the same index in the key codes array. */ public static boolean[] deviceHasKeys(int[] keyCodes) { - return InputManager.deviceHasKeys(keyCodes); + return InputManager.getInstance().deviceHasKeys(keyCodes); + } + + @Override + public void writeToParcel(Parcel out, int flags) { + if (out == null) { + throw new IllegalArgumentException("parcel must not be null"); + } + nativeWriteToParcel(mPtr, out); + } + + @Override + public int describeContents() { + return 0; } /** diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java index 77fd8d2..e51ba3d 100644 --- a/core/java/android/view/MotionEvent.java +++ b/core/java/android/view/MotionEvent.java @@ -2715,6 +2715,67 @@ public final class MotionEvent extends InputEvent implements Parcelable { } /** + * Adds all of the movement samples of the specified event to this one if + * it is compatible. To be compatible, the event must have the same device id, + * source, action, flags, pointer count, pointer properties. + * + * Only applies to {@link #ACTION_MOVE} or {@link #ACTION_HOVER_MOVE} events. + * + * @param event The event whose movements samples should be added to this one + * if possible. + * @return True if batching was performed or false if batching was not possible. + * @hide + */ + public final boolean addBatch(MotionEvent event) { + final int action = nativeGetAction(mNativePtr); + if (action != ACTION_MOVE && action != ACTION_HOVER_MOVE) { + return false; + } + if (action != nativeGetAction(event.mNativePtr)) { + return false; + } + + if (nativeGetDeviceId(mNativePtr) != nativeGetDeviceId(event.mNativePtr) + || nativeGetSource(mNativePtr) != nativeGetSource(event.mNativePtr) + || nativeGetFlags(mNativePtr) != nativeGetFlags(event.mNativePtr)) { + return false; + } + + final int pointerCount = nativeGetPointerCount(mNativePtr); + if (pointerCount != nativeGetPointerCount(event.mNativePtr)) { + return false; + } + + synchronized (gSharedTempLock) { + ensureSharedTempPointerCapacity(Math.max(pointerCount, 2)); + final PointerProperties[] pp = gSharedTempPointerProperties; + final PointerCoords[] pc = gSharedTempPointerCoords; + + for (int i = 0; i < pointerCount; i++) { + nativeGetPointerProperties(mNativePtr, i, pp[0]); + nativeGetPointerProperties(event.mNativePtr, i, pp[1]); + if (!pp[0].equals(pp[1])) { + return false; + } + } + + final int metaState = nativeGetMetaState(event.mNativePtr); + final int historySize = nativeGetHistorySize(event.mNativePtr); + for (int h = 0; h <= historySize; h++) { + final int historyPos = (h == historySize ? HISTORY_CURRENT : h); + + for (int i = 0; i < pointerCount; i++) { + nativeGetPointerCoords(event.mNativePtr, i, historyPos, pc[i]); + } + + final long eventTimeNanos = nativeGetEventTimeNanos(event.mNativePtr, historyPos); + nativeAddBatch(mNativePtr, eventTimeNanos, pc, metaState); + } + } + return true; + } + + /** * Returns true if all points in the motion event are completely within the specified bounds. * @hide */ @@ -3416,5 +3477,22 @@ public final class MotionEvent extends InputEvent implements Parcelable { id = other.id; toolType = other.toolType; } + + @Override + public boolean equals(Object other) { + if (other instanceof PointerProperties) { + return equals((PointerProperties)other); + } + return false; + } + + private boolean equals(PointerProperties other) { + return other != null && id == other.id && toolType == other.toolType; + } + + @Override + public int hashCode() { + return id | (toolType << 8); + } } } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index d62e32f..0be7a87 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -8698,7 +8698,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal invalidateParentCaches(); onScrollChanged(mScrollX, mScrollY, oldX, oldY); if (!awakenScrollBars()) { - invalidate(true); + postInvalidateOnAnimation(); } } } @@ -8852,7 +8852,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal if (invalidate) { // Invalidate to show the scrollbars - invalidate(true); + postInvalidateOnAnimation(); } if (scrollCache.state == ScrollabilityCache.OFF) { @@ -9212,6 +9212,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * @return Returns true if the Runnable was successfully placed in to the * message queue. Returns false on failure, usually because the * looper processing the message queue is exiting. + * + * @see #postDelayed + * @see #removeCallbacks */ public boolean post(Runnable action) { final AttachInfo attachInfo = mAttachInfo; @@ -9241,6 +9244,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * result of true does not mean the Runnable will be processed -- * if the looper is quit before the delivery time of the message * occurs then the message will be dropped. + * + * @see #post + * @see #removeCallbacks */ public boolean postDelayed(Runnable action, long delayMillis) { final AttachInfo attachInfo = mAttachInfo; @@ -9261,7 +9267,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * * @param action The Runnable that will be executed. * - * @hide + * @see #postOnAnimationDelayed + * @see #removeCallbacks */ public void postOnAnimation(Runnable action) { final AttachInfo attachInfo = mAttachInfo; @@ -9286,7 +9293,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * @param delayMillis The delay (in milliseconds) until the Runnable * will be executed. * - * @hide + * @see #postOnAnimation + * @see #removeCallbacks */ public void postOnAnimationDelayed(Runnable action, long delayMillis) { final AttachInfo attachInfo = mAttachInfo; @@ -9311,6 +9319,11 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * false otherwise. When the returned value is true, the Runnable * may or may not have been actually removed from the message queue * (for instance, if the Runnable was not in the queue already.) + * + * @see #post + * @see #postDelayed + * @see #postOnAnimation + * @see #postOnAnimationDelayed */ public boolean removeCallbacks(Runnable action) { if (action != null) { @@ -9335,6 +9348,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * only when this View is attached to a window.</p> * * @see #invalidate() + * @see #postInvalidateDelayed(long) */ public void postInvalidate() { postInvalidateDelayed(0); @@ -9354,6 +9368,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * * @see #invalidate(int, int, int, int) * @see #invalidate(Rect) + * @see #postInvalidateDelayed(long, int, int, int, int) */ public void postInvalidate(int left, int top, int right, int bottom) { postInvalidateDelayed(0, left, top, right, bottom); @@ -9368,6 +9383,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * * @param delayMilliseconds the duration in milliseconds to delay the * invalidation by + * + * @see #invalidate() + * @see #postInvalidate() */ public void postInvalidateDelayed(long delayMilliseconds) { // We try only with the AttachInfo because there's no point in invalidating @@ -9391,6 +9409,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * @param top The top coordinate of the rectangle to invalidate. * @param right The right coordinate of the rectangle to invalidate. * @param bottom The bottom coordinate of the rectangle to invalidate. + * + * @see #invalidate(int, int, int, int) + * @see #invalidate(Rect) + * @see #postInvalidate(int, int, int, int) */ public void postInvalidateDelayed(long delayMilliseconds, int left, int top, int right, int bottom) { @@ -9417,7 +9439,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * <p>This method can be invoked from outside of the UI thread * only when this View is attached to a window.</p> * - * @hide + * @see #invalidate() */ public void postInvalidateOnAnimation() { // We try only with the AttachInfo because there's no point in invalidating @@ -9440,7 +9462,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * @param right The right coordinate of the rectangle to invalidate. * @param bottom The bottom coordinate of the rectangle to invalidate. * - * @hide + * @see #invalidate(int, int, int, int) + * @see #invalidate(Rect) */ public void postInvalidateOnAnimation(int left, int top, int right, int bottom) { // We try only with the AttachInfo because there's no point in invalidating diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java index a45a87e..52bd860 100644 --- a/core/java/android/view/WindowManagerImpl.java +++ b/core/java/android/view/WindowManagerImpl.java @@ -432,23 +432,24 @@ public class WindowManagerImpl implements WindowManager { */ public void trimMemory(int level) { if (HardwareRenderer.isAvailable()) { - // On low and medium end gfx devices - if (!ActivityManager.isHighEndGfx(getDefaultDisplay())) { - if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) { - // 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(); - } + // 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(getDefaultDisplay()))) { + // 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 - HardwareRenderer.trimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE); - mNeedsEglTerminate = true; - return; } + // Force a full memory flush + HardwareRenderer.trimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE); + mNeedsEglTerminate = true; + return; } HardwareRenderer.trimMemory(level); } diff --git a/core/java/android/webkit/AutoCompletePopup.java b/core/java/android/webkit/AutoCompletePopup.java index b26156c..21d5e02 100644 --- a/core/java/android/webkit/AutoCompletePopup.java +++ b/core/java/android/webkit/AutoCompletePopup.java @@ -129,13 +129,13 @@ class AutoCompletePopup implements OnItemClickListener, Filter.FilterListener { } public void resetRect() { - int left = mWebView.contentToViewX(mWebView.mEditTextBounds.left); - int right = mWebView.contentToViewX(mWebView.mEditTextBounds.right); + int left = mWebView.contentToViewX(mWebView.mEditTextContentBounds.left); + int right = mWebView.contentToViewX(mWebView.mEditTextContentBounds.right); int width = right - left; mPopup.setWidth(width); - int bottom = mWebView.contentToViewY(mWebView.mEditTextBounds.bottom); - int top = mWebView.contentToViewY(mWebView.mEditTextBounds.top); + int bottom = mWebView.contentToViewY(mWebView.mEditTextContentBounds.bottom); + int top = mWebView.contentToViewY(mWebView.mEditTextContentBounds.top); int height = bottom - top; AbsoluteLayout.LayoutParams lp = diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java index 8dc3b7e..5dc2681 100644 --- a/core/java/android/webkit/WebViewClassic.java +++ b/core/java/android/webkit/WebViewClassic.java @@ -57,6 +57,7 @@ import android.net.http.SslCertificate; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; +import android.os.Looper; import android.os.Message; import android.os.SystemClock; import android.provider.Settings; @@ -100,7 +101,6 @@ import android.webkit.WebView.PictureListener; import android.webkit.WebViewCore.DrawData; import android.webkit.WebViewCore.EventHub; import android.webkit.WebViewCore.TextFieldInitData; -import android.webkit.WebViewCore.TouchEventData; import android.webkit.WebViewCore.TouchHighlightData; import android.webkit.WebViewCore.WebKitHitTest; import android.widget.AbsoluteLayout; @@ -847,7 +847,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc private int mFieldPointer; private PastePopupWindow mPasteWindow; private AutoCompletePopup mAutoCompletePopup; - Rect mEditTextBounds = new Rect(); + Rect mEditTextContentBounds = new Rect(); Rect mEditTextContent = new Rect(); int mEditTextLayerId; boolean mIsEditingText = false; @@ -886,7 +886,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc // the existing GL resources for the html5 video will be destroyed // at native side. // Here we just need to clean up the Surface Texture which is static. - HTML5VideoInline.cleanupSurfaceTexture(); + if (level >= TRIM_MEMORY_UI_HIDDEN) { + HTML5VideoInline.cleanupSurfaceTexture(); + } WebViewClassic.nativeOnTrimMemory(level); } @@ -979,6 +981,8 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc /** * Touch mode + * TODO: Some of this is now unnecessary as it is handled by + * WebInputTouchDispatcher (such as click, long press, and double tap). */ private int mTouchMode = TOUCH_DONE_MODE; private static final int TOUCH_INIT_MODE = 1; @@ -992,35 +996,10 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc private static final int TOUCH_DRAG_LAYER_MODE = 9; private static final int TOUCH_DRAG_TEXT_MODE = 10; - // Whether to forward the touch events to WebCore - // Can only be set by WebKit via JNI. - private boolean mForwardTouchEvents = false; - - // Whether to prevent default during touch. The initial value depends on - // mForwardTouchEvents. If WebCore wants all the touch events, it says yes - // for touch down. Otherwise UI will wait for the answer of the first - // confirmed move before taking over the control. - private static final int PREVENT_DEFAULT_NO = 0; - private static final int PREVENT_DEFAULT_MAYBE_YES = 1; - private static final int PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN = 2; - private static final int PREVENT_DEFAULT_YES = 3; - private static final int PREVENT_DEFAULT_IGNORE = 4; - private int mPreventDefault = PREVENT_DEFAULT_IGNORE; - // true when the touch movement exceeds the slop private boolean mConfirmMove; private boolean mTouchInEditText; - // if true, touch events will be first processed by WebCore, if prevent - // default is not set, the UI will continue handle them. - private boolean mDeferTouchProcess; - - // to avoid interfering with the current touch events, track them - // separately. Currently no snapping or fling in the deferred process mode - private int mDeferTouchMode = TOUCH_DONE_MODE; - private float mLastDeferTouchX; - private float mLastDeferTouchY; - // Whether or not to draw the cursor ring. private boolean mDrawCursorRing = true; @@ -1231,6 +1210,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc static final int ANIMATE_TEXT_SCROLL = 149; static final int EDIT_TEXT_SIZE_CHANGED = 150; static final int SHOW_CARET_HANDLE = 151; + static final int UPDATE_CONTENT_BOUNDS = 152; private static final int FIRST_PACKAGE_MSG_ID = SCROLL_TO_MSG_ID; private static final int LAST_PACKAGE_MSG_ID = HIT_TEST_RESULT; @@ -1407,7 +1387,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc private boolean mSentAutoScrollMessage = false; // used for serializing asynchronously handled touch events. - private final TouchEventQueue mTouchEventQueue = new TouchEventQueue(); + private WebViewInputDispatcher mInputDispatcher; // Used to track whether picture updating was paused due to a window focus change. private boolean mPictureUpdatePausedForFocusChange = false; @@ -1497,6 +1477,68 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } + private void onHandleUiEvent(MotionEvent event, int eventType, int flags) { + switch (eventType) { + case WebViewInputDispatcher.EVENT_TYPE_LONG_PRESS: + HitTestResult hitTest = getHitTestResult(); + if (hitTest != null + && hitTest.getType() != HitTestResult.UNKNOWN_TYPE) { + performLongClick(); + } + break; + case WebViewInputDispatcher.EVENT_TYPE_DOUBLE_TAP: + mZoomManager.handleDoubleTap(event.getX(), event.getY()); + break; + case WebViewInputDispatcher.EVENT_TYPE_TOUCH: + onHandleUiTouchEvent(event); + break; + } + } + + private void onHandleUiTouchEvent(MotionEvent ev) { + final ScaleGestureDetector detector = + mZoomManager.getMultiTouchGestureDetector(); + + float x = ev.getX(); + float y = ev.getY(); + + if (detector != null) { + detector.onTouchEvent(ev); + if (detector.isInProgress()) { + mLastTouchTime = ev.getEventTime(); + x = detector.getFocusX(); + y = detector.getFocusY(); + + mWebView.cancelLongPress(); + mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS); + if (!mZoomManager.supportsPanDuringZoom()) { + return; + } + mTouchMode = TOUCH_DRAG_MODE; + if (mVelocityTracker == null) { + mVelocityTracker = VelocityTracker.obtain(); + } + } + } + + int action = ev.getActionMasked(); + if (action == MotionEvent.ACTION_POINTER_DOWN) { + cancelTouch(); + action = MotionEvent.ACTION_DOWN; + } else if (action == MotionEvent.ACTION_POINTER_UP && ev.getPointerCount() >= 2) { + // set mLastTouchX/Y to the remaining points for multi-touch. + mLastTouchX = Math.round(x); + mLastTouchY = Math.round(y); + } else if (action == MotionEvent.ACTION_MOVE) { + // negative x or y indicate it is on the edge, skip it. + if (x < 0 || y < 0) { + return; + } + } + + handleTouchEventCommon(ev, action, Math.round(x), Math.round(y)); + } + // The webview that is bound to this WebViewClassic instance. Primarily needed for supplying // as the first param in the WebViewClient and WebChromeClient callbacks. final private WebView mWebView; @@ -2866,7 +2908,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc if (rect.width() < mFocusedNode.mHitTestSlop) { // ignore bounding boxes that are too small continue; - } else if (left != NO_LEFTEDGE && rect.width() > readingWidth) { + } else if (rect.width() > readingWidth) { // stop when bounding box doesn't fit the screen width // at reading scale break; @@ -3866,7 +3908,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } if (mAutoCompletePopup != null && mCurrentScrollingLayerId == mEditTextLayerId) { - mEditTextBounds.offset(dx, dy); + mEditTextContentBounds.offset(dx, dy); mAutoCompletePopup.resetRect(); } nativeScrollLayer(mCurrentScrollingLayerId, x, y); @@ -4369,8 +4411,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc boolean animateScroll = ((!mScroller.isFinished() || mVelocityTracker != null) && (mTouchMode != TOUCH_DRAG_MODE || - mHeldMotionless != MOTIONLESS_TRUE)) - || mDeferTouchMode == TOUCH_DRAG_MODE; + mHeldMotionless != MOTIONLESS_TRUE)); if (mTouchMode == TOUCH_DRAG_MODE) { if (mHeldMotionless == MOTIONLESS_PENDING) { mPrivateHandler.removeMessages(DRAG_HELD_MOTIONLESS); @@ -5570,7 +5611,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc addAccessibilityApisToJavaScript(); - mTouchEventQueue.reset(); updateHwAccelerated(); } @@ -5819,20 +5859,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc */ private static final float MMA_WEIGHT_N = 5; - private boolean hitFocusedPlugin(int contentX, int contentY) { - // TODO: Figure out what to do with this (b/6111517) - return false; - } - - private boolean shouldForwardTouchEvent() { - if (mFullScreenHolder != null) return true; - if (mBlockWebkitViewMessages) return false; - return mForwardTouchEvents - && !mSelectingText - && mPreventDefault != PREVENT_DEFAULT_IGNORE - && mPreventDefault != PREVENT_DEFAULT_NO; - } - private boolean inFullScreenMode() { return mFullScreenHolder != null; } @@ -5902,23 +5928,17 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc mWebView.requestFocus(); } - if (DebugFlags.WEB_VIEW) { - Log.v(LOGTAG, ev + " at " + ev.getEventTime() - + " mTouchMode=" + mTouchMode - + " numPointers=" + ev.getPointerCount()); + if (mInputDispatcher == null) { + return false; } - // If WebKit wasn't interested in this multitouch gesture, enqueue - // the event for handling directly rather than making the round trip - // to WebKit and back. - if (ev.getPointerCount() > 1 && mPreventDefault != PREVENT_DEFAULT_NO) { - passMultiTouchToWebKit(ev, mTouchEventQueue.nextTouchSequence()); + if (mInputDispatcher.postPointerEvent(ev, getScrollX(), + getScrollY() - getTitleHeight(), mZoomManager.getInvScale())) { + return true; } else { - mTouchEventQueue.enqueueTouchEvent(ev); + Log.w(LOGTAG, "mInputDispatcher rejected the event!"); + return false; } - - // Since all events are handled asynchronously, we always want the gesture stream. - return true; } private float calculateDragAngle(int dx, int dy) { @@ -5928,12 +5948,14 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } /* - * Common code for single touch and multi-touch. - * (x, y) denotes current focus point, which is the touch point for single touch - * and the middle point for multi-touch. - */ - private boolean handleTouchEventCommon(MotionEvent ev, int action, int x, int y) { - long eventTime = ev.getEventTime(); + * Common code for single touch and multi-touch. + * (x, y) denotes current focus point, which is the touch point for single touch + * and the middle point for multi-touch. + */ + private void handleTouchEventCommon(MotionEvent event, int action, int x, int y) { + ScaleGestureDetector detector = mZoomManager.getMultiTouchGestureDetector(); + + long eventTime = event.getEventTime(); // Due to the touch screen edge effect, a touch closer to the edge // always snapped to the edge. As getViewWidth() can be different from @@ -5949,7 +5971,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc switch (action) { case MotionEvent.ACTION_DOWN: { - mPreventDefault = PREVENT_DEFAULT_NO; mConfirmMove = false; mInitialHitTestResult = null; if (!mEditTextScroller.isFinished()) { @@ -5969,20 +5990,11 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc if (deltaX * deltaX + deltaY * deltaY < mDoubleTapSlopSquare) { mTouchMode = TOUCH_DOUBLE_TAP_MODE; } else { - // commit the short press action for the previous tap - doShortPress(); mTouchMode = TOUCH_INIT_MODE; - mDeferTouchProcess = !mBlockWebkitViewMessages - && (!inFullScreenMode() && mForwardTouchEvents) - ? hitFocusedPlugin(contentX, contentY) - : false; } } else { // the normal case mTouchMode = TOUCH_INIT_MODE; - mDeferTouchProcess = !mBlockWebkitViewMessages - && (!inFullScreenMode() && mForwardTouchEvents) - ? hitFocusedPlugin(contentX, contentY) - : false; + // TODO: Have WebViewInputDispatch handle this TouchHighlightData data = new TouchHighlightData(); data.mX = contentX; data.mY = contentY; @@ -5996,19 +6008,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc mWebViewCore.sendMessageAtFrontOfQueue( EventHub.HIT_TEST, data); } - if (DEBUG_TOUCH_HIGHLIGHT) { - if (getSettings().getNavDump()) { - mTouchHighlightX = x + getScrollX(); - mTouchHighlightY = y + getScrollY(); - mPrivateHandler.postDelayed(new Runnable() { - @Override - public void run() { - mTouchHighlightX = mTouchHighlightY = 0; - invalidate(); - } - }, TOUCH_HIGHLIGHT_ELAPSE_TIME); - } - } if (mLogEvent && eventTime - mLastTouchUpTime < 1000) { EventLog.writeEvent(EventLogTags.BROWSER_DOUBLE_TAP_DURATION, (eventTime - mLastTouchUpTime), eventTime); @@ -6055,58 +6054,20 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc SWITCH_TO_SHORTPRESS, TAP_TIMEOUT); mPrivateHandler.sendEmptyMessageDelayed( SWITCH_TO_LONGPRESS, LONG_PRESS_TIMEOUT); - if (inFullScreenMode() || mDeferTouchProcess) { - mPreventDefault = PREVENT_DEFAULT_YES; - } else if (!mBlockWebkitViewMessages && mForwardTouchEvents) { - mPreventDefault = PREVENT_DEFAULT_MAYBE_YES; - } else { - mPreventDefault = PREVENT_DEFAULT_NO; - } - // pass the touch events from UI thread to WebCore thread - if (shouldForwardTouchEvent()) { - TouchEventData ted = new TouchEventData(); - ted.mAction = action; - ted.mIds = new int[1]; - ted.mIds[0] = ev.getPointerId(0); - ted.mPoints = new Point[1]; - ted.mPoints[0] = new Point(contentX, contentY); - ted.mPointsInView = new Point[1]; - ted.mPointsInView[0] = new Point(x, y); - ted.mMetaState = ev.getMetaState(); - ted.mReprocess = mDeferTouchProcess; - ted.mNativeLayer = nativeScrollableLayer( - contentX, contentY, ted.mNativeLayerRect, null); - ted.mSequence = mTouchEventQueue.nextTouchSequence(); - mTouchEventQueue.preQueueTouchEventData(ted); - mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted); - if (mDeferTouchProcess) { - // still needs to set them for compute deltaX/Y - mLastTouchX = x; - mLastTouchY = y; - break; - } - if (!inFullScreenMode()) { - mPrivateHandler.removeMessages(PREVENT_DEFAULT_TIMEOUT); - mPrivateHandler.sendMessageDelayed(mPrivateHandler - .obtainMessage(PREVENT_DEFAULT_TIMEOUT, - action, 0), TAP_TIMEOUT); - } - } } startTouch(x, y, eventTime); if (mIsEditingText) { - mTouchInEditText = mEditTextBounds.contains(contentX, contentY); + mTouchInEditText = mEditTextContentBounds + .contains(contentX, contentY); } break; } case MotionEvent.ACTION_MOVE: { - boolean firstMove = false; if (!mConfirmMove && (deltaX * deltaX + deltaY * deltaY) >= mTouchSlopSquare) { mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS); mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS); mConfirmMove = true; - firstMove = true; if (mTouchMode == TOUCH_DOUBLE_TAP_MODE) { mTouchMode = TOUCH_INIT_MODE; } @@ -6121,8 +6082,23 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc parent.requestDisallowInterceptTouchEvent(true); } if (deltaX != 0 || deltaY != 0) { - snapDraggingCursor(contentX, contentY); + int handleX = contentX + + viewToContentDimension(mSelectDraggingOffset.x); + int handleY = contentY + + viewToContentDimension(mSelectDraggingOffset.y); + mSelectDraggingCursor.set(handleX, handleY); + boolean inCursorText = + mSelectDraggingTextQuad.containsPoint(handleX, handleY); + boolean inEditBounds = mEditTextContentBounds + .contains(handleX, handleY); + if (inCursorText || (mIsEditingText && !inEditBounds)) { + snapDraggingCursor(); + } updateWebkitSelection(); + if (!inCursorText && mIsEditingText && inEditBounds) { + // Visually snap even if we have moved the handle. + snapDraggingCursor(); + } mLastTouchX = x; mLastTouchY = y; invalidate(); @@ -6130,48 +6106,16 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc break; } - // pass the touch events from UI thread to WebCore thread - if (shouldForwardTouchEvent() && mConfirmMove && (firstMove - || eventTime - mLastSentTouchTime > mCurrentTouchInterval)) { - TouchEventData ted = new TouchEventData(); - ted.mAction = action; - ted.mIds = new int[1]; - ted.mIds[0] = ev.getPointerId(0); - ted.mPoints = new Point[1]; - ted.mPoints[0] = new Point(contentX, contentY); - ted.mPointsInView = new Point[1]; - ted.mPointsInView[0] = new Point(x, y); - ted.mMetaState = ev.getMetaState(); - ted.mReprocess = mDeferTouchProcess; - ted.mNativeLayer = mCurrentScrollingLayerId; - ted.mNativeLayerRect.set(mScrollingLayerRect); - ted.mMotionEvent = MotionEvent.obtain(ev); - ted.mSequence = mTouchEventQueue.nextTouchSequence(); - mTouchEventQueue.preQueueTouchEventData(ted); - mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted); - mLastSentTouchTime = eventTime; - if (mDeferTouchProcess) { - break; - } - if (firstMove && !inFullScreenMode()) { - mPrivateHandler.sendMessageDelayed(mPrivateHandler - .obtainMessage(PREVENT_DEFAULT_TIMEOUT, - action, 0), TAP_TIMEOUT); - } - } - if (mTouchMode == TOUCH_DONE_MODE - || mPreventDefault == PREVENT_DEFAULT_YES) { + if (mTouchMode == TOUCH_DONE_MODE) { // no dragging during scroll zoom animation, or when prevent // default is yes break; } if (mVelocityTracker == null) { Log.e(LOGTAG, "Got null mVelocityTracker when " - + "mPreventDefault = " + mPreventDefault - + " mDeferTouchProcess = " + mDeferTouchProcess + " mTouchMode = " + mTouchMode); } else { - mVelocityTracker.addMovement(ev); + mVelocityTracker.addMovement(event); } if (mTouchMode != TOUCH_DRAG_MODE && @@ -6182,19 +6126,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc break; } - if (mPreventDefault == PREVENT_DEFAULT_MAYBE_YES - || mPreventDefault == PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN) { - // track mLastTouchTime as we may need to do fling at - // ACTION_UP - mLastTouchTime = eventTime; - break; - } - // Only lock dragging to one axis if we don't have a scale in progress. // Scaling implies free-roaming movement. Note this is only ever a question // if mZoomManager.supportsPanDuringZoom() is true. - final ScaleGestureDetector detector = - mZoomManager.getMultiTouchGestureDetector(); mAverageAngle = calculateDragAngle(deltaX, deltaY); if (detector == null || !detector.isInProgress()) { // if it starts nearly horizontal or vertical, enforce it @@ -6220,10 +6154,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } // do pan - boolean done = false; boolean keepScrollBarsVisible = false; if (deltaX == 0 && deltaY == 0) { - keepScrollBarsVisible = done = true; + keepScrollBarsVisible = true; } else { mAverageAngle += (calculateDragAngle(deltaX, deltaY) - mAverageAngle) @@ -6300,7 +6233,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc ViewConfiguration.getScrollDefaultDelay()); // return false to indicate that we can't pan out of the // view space - return !done; + return; } else { mPrivateHandler.removeMessages(AWAKEN_SCROLL_BARS); } @@ -6313,24 +6246,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc stopTouch(); break; } - // pass the touch events from UI thread to WebCore thread - if (shouldForwardTouchEvent()) { - TouchEventData ted = new TouchEventData(); - ted.mIds = new int[1]; - ted.mIds[0] = ev.getPointerId(0); - ted.mAction = action; - ted.mPoints = new Point[1]; - ted.mPoints[0] = new Point(contentX, contentY); - ted.mPointsInView = new Point[1]; - ted.mPointsInView[0] = new Point(x, y); - ted.mMetaState = ev.getMetaState(); - ted.mReprocess = mDeferTouchProcess; - ted.mNativeLayer = mCurrentScrollingLayerId; - ted.mNativeLayerRect.set(mScrollingLayerRect); - ted.mSequence = mTouchEventQueue.nextTouchSequence(); - mTouchEventQueue.preQueueTouchEventData(ted); - mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted); - } mLastTouchUpTime = eventTime; if (mSentAutoScrollMessage) { mAutoScrollX = mAutoScrollY = 0; @@ -6339,66 +6254,14 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc case TOUCH_DOUBLE_TAP_MODE: // double tap mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS); mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS); - if (inFullScreenMode() || mDeferTouchProcess) { - TouchEventData ted = new TouchEventData(); - ted.mIds = new int[1]; - ted.mIds[0] = ev.getPointerId(0); - ted.mAction = WebViewCore.ACTION_DOUBLETAP; - ted.mPoints = new Point[1]; - ted.mPoints[0] = new Point(contentX, contentY); - ted.mPointsInView = new Point[1]; - ted.mPointsInView[0] = new Point(x, y); - ted.mMetaState = ev.getMetaState(); - ted.mReprocess = mDeferTouchProcess; - ted.mNativeLayer = nativeScrollableLayer( - contentX, contentY, - ted.mNativeLayerRect, null); - ted.mSequence = mTouchEventQueue.nextTouchSequence(); - mTouchEventQueue.preQueueTouchEventData(ted); - mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted); - } else if (mPreventDefault != PREVENT_DEFAULT_YES){ - mZoomManager.handleDoubleTap(mLastTouchX, mLastTouchY); - mTouchMode = TOUCH_DONE_MODE; - } + mTouchMode = TOUCH_DONE_MODE; break; case TOUCH_INIT_MODE: // tap case TOUCH_SHORTPRESS_START_MODE: case TOUCH_SHORTPRESS_MODE: mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS); mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS); - if (mConfirmMove) { - Log.w(LOGTAG, "Miss a drag as we are waiting for" + - " WebCore's response for touch down."); - if (mPreventDefault != PREVENT_DEFAULT_YES - && (computeMaxScrollX() > 0 - || computeMaxScrollY() > 0)) { - // If the user has performed a very quick touch - // sequence it is possible that we may get here - // before WebCore has had a chance to process the events. - // In this case, any call to preventDefault in the - // JS touch handler will not have been executed yet. - // Hence we will see both the UI (now) and WebCore - // (when context switches) handling the event, - // regardless of whether the web developer actually - // doeses preventDefault in their touch handler. This - // is the nature of our asynchronous touch model. - - // we will not rewrite drag code here, but we - // will try fling if it applies. - WebViewCore.reducePriority(); - // to get better performance, pause updating the - // picture - WebViewCore.pauseUpdatePicture(mWebViewCore); - // fall through to TOUCH_DRAG_MODE - } else { - // WebKit may consume the touch event and modify - // DOM. drawContentPicture() will be called with - // animateSroll as true for better performance. - // Force redraw in high-quality. - invalidate(); - break; - } - } else { + if (!mConfirmMove) { if (mSelectingText) { // tapping on selection or controls does nothing if (!mSelectionStarted) { @@ -6413,8 +6276,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc mPrivateHandler.sendEmptyMessageDelayed( RELEASE_SINGLE_TAP, ViewConfiguration .getDoubleTapTimeout()); - } else { - doShortPress(); } break; } @@ -6427,13 +6288,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc // up, we don't want to do a fling if (eventTime - mLastTouchTime <= MIN_FLING_TIME) { if (mVelocityTracker == null) { - Log.e(LOGTAG, "Got null mVelocityTracker when " - + "mPreventDefault = " - + mPreventDefault - + " mDeferTouchProcess = " - + mDeferTouchProcess); + Log.e(LOGTAG, "Got null mVelocityTracker"); } else { - mVelocityTracker.addMovement(ev); + mVelocityTracker.addMovement(event); } // set to MOTIONLESS_IGNORE so that it won't keep // removing and sending message in @@ -6472,128 +6329,10 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc computeMaxScrollX(), 0, computeMaxScrollY()); invalidate(); } - cancelWebCoreTouchEvent(contentX, contentY, false); cancelTouch(); break; } } - return true; - } - - private void passMultiTouchToWebKit(MotionEvent ev, long sequence) { - TouchEventData ted = new TouchEventData(); - ted.mAction = ev.getActionMasked(); - final int count = ev.getPointerCount(); - ted.mIds = new int[count]; - ted.mPoints = new Point[count]; - ted.mPointsInView = new Point[count]; - for (int c = 0; c < count; c++) { - ted.mIds[c] = ev.getPointerId(c); - int x = viewToContentX((int) ev.getX(c) + getScrollX()); - int y = viewToContentY((int) ev.getY(c) + getScrollY()); - ted.mPoints[c] = new Point(x, y); - ted.mPointsInView[c] = new Point((int) ev.getX(c), (int) ev.getY(c)); - } - if (ted.mAction == MotionEvent.ACTION_POINTER_DOWN - || ted.mAction == MotionEvent.ACTION_POINTER_UP) { - ted.mActionIndex = ev.getActionIndex(); - } - ted.mMetaState = ev.getMetaState(); - ted.mReprocess = true; - ted.mMotionEvent = MotionEvent.obtain(ev); - ted.mSequence = sequence; - mTouchEventQueue.preQueueTouchEventData(ted); - mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted); - mWebView.cancelLongPress(); - mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS); - } - - void handleMultiTouchInWebView(MotionEvent ev) { - if (DebugFlags.WEB_VIEW) { - Log.v(LOGTAG, "multi-touch: " + ev + " at " + ev.getEventTime() - + " mTouchMode=" + mTouchMode - + " numPointers=" + ev.getPointerCount() - + " scrolloffset=(" + getScrollX() + "," + getScrollY() + ")"); - } - - final ScaleGestureDetector detector = - mZoomManager.getMultiTouchGestureDetector(); - - // A few apps use WebView but don't instantiate gesture detector. - // We don't need to support multi touch for them. - if (detector == null) return; - - float x = ev.getX(); - float y = ev.getY(); - - if (mPreventDefault != PREVENT_DEFAULT_YES) { - detector.onTouchEvent(ev); - - if (detector.isInProgress()) { - if (DebugFlags.WEB_VIEW) { - Log.v(LOGTAG, "detector is in progress"); - } - mLastTouchTime = ev.getEventTime(); - x = detector.getFocusX(); - y = detector.getFocusY(); - - mWebView.cancelLongPress(); - mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS); - if (!mZoomManager.supportsPanDuringZoom()) { - return; - } - mTouchMode = TOUCH_DRAG_MODE; - if (mVelocityTracker == null) { - mVelocityTracker = VelocityTracker.obtain(); - } - } - } - - int action = ev.getActionMasked(); - if (action == MotionEvent.ACTION_POINTER_DOWN) { - cancelTouch(); - action = MotionEvent.ACTION_DOWN; - } else if (action == MotionEvent.ACTION_POINTER_UP && ev.getPointerCount() >= 2) { - // set mLastTouchX/Y to the remaining points for multi-touch. - mLastTouchX = Math.round(x); - mLastTouchY = Math.round(y); - } else if (action == MotionEvent.ACTION_MOVE) { - // negative x or y indicate it is on the edge, skip it. - if (x < 0 || y < 0) { - return; - } - } - - handleTouchEventCommon(ev, action, Math.round(x), Math.round(y)); - } - - private void cancelWebCoreTouchEvent(int x, int y, boolean removeEvents) { - if (shouldForwardTouchEvent()) { - if (removeEvents) { - mWebViewCore.removeMessages(EventHub.TOUCH_EVENT); - } - TouchEventData ted = new TouchEventData(); - ted.mIds = new int[1]; - ted.mIds[0] = 0; - ted.mPoints = new Point[1]; - ted.mPoints[0] = new Point(x, y); - ted.mPointsInView = new Point[1]; - int viewX = contentToViewX(x) - getScrollX(); - int viewY = contentToViewY(y) - getScrollY(); - ted.mPointsInView[0] = new Point(viewX, viewY); - ted.mAction = MotionEvent.ACTION_CANCEL; - ted.mNativeLayer = nativeScrollableLayer( - x, y, ted.mNativeLayerRect, null); - ted.mSequence = mTouchEventQueue.nextTouchSequence(); - mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted); - mPreventDefault = PREVENT_DEFAULT_IGNORE; - - if (removeEvents) { - // Mark this after sending the message above; we should - // be willing to ignore the cancel event that we just sent. - mTouchEventQueue.ignoreCurrentlyMissingEvents(); - } - } } private void startTouch(float x, float y, long eventTime) { @@ -6736,23 +6475,22 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc mTouchMode = TOUCH_DONE_MODE; } - private void snapDraggingCursor(int x, int y) { - x += viewToContentDimension(mSelectDraggingOffset.x); - y += viewToContentDimension(mSelectDraggingOffset.y); - if (mSelectDraggingTextQuad.containsPoint(x, y)) { - float scale = scaleAlongSegment(x, y, - mSelectDraggingTextQuad.p4, mSelectDraggingTextQuad.p3); - // clamp scale to ensure point is on the bottom segment - scale = Math.max(0.0f, scale); - scale = Math.min(scale, 1.0f); - float newX = scaleCoordinate(scale, - mSelectDraggingTextQuad.p4.x, mSelectDraggingTextQuad.p3.x); - float newY = scaleCoordinate(scale, - mSelectDraggingTextQuad.p4.y, mSelectDraggingTextQuad.p3.y); - mSelectDraggingCursor.set(Math.round(newX), Math.round(newY)); - } else { - mSelectDraggingCursor.set(x, y); - } + private void snapDraggingCursor() { + float scale = scaleAlongSegment( + mSelectDraggingCursor.x, mSelectDraggingCursor.y, + mSelectDraggingTextQuad.p4, mSelectDraggingTextQuad.p3); + // clamp scale to ensure point is on the bottom segment + scale = Math.max(0.0f, scale); + scale = Math.min(scale, 1.0f); + float newX = scaleCoordinate(scale, + mSelectDraggingTextQuad.p4.x, mSelectDraggingTextQuad.p3.x); + float newY = scaleCoordinate(scale, + mSelectDraggingTextQuad.p4.y, mSelectDraggingTextQuad.p3.y); + int x = Math.max(mEditTextContentBounds.left, + Math.min(mEditTextContentBounds.right, Math.round(newX))); + int y = Math.max(mEditTextContentBounds.top, + Math.min(mEditTextContentBounds.bottom, Math.round(newY))); + mSelectDraggingCursor.set(x, y); } private static float scaleCoordinate(float scale, float coord1, float coord2) { @@ -7231,39 +6969,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc return mZoomManager.zoomOut(); } - private void doShortPress() { - if (mNativeClass == 0) { - return; - } - if (mPreventDefault == PREVENT_DEFAULT_YES) { - return; - } - mTouchMode = TOUCH_DONE_MODE; - switchOutDrawHistory(); - if (!mTouchHighlightRegion.isEmpty()) { - // set mTouchHighlightRequested to 0 to cause an immediate - // drawing of the touch rings - mTouchHighlightRequested = 0; - mWebView.invalidate(mTouchHighlightRegion.getBounds()); - mPrivateHandler.postDelayed(new Runnable() { - @Override - public void run() { - removeTouchHighlight(); - } - }, ViewConfiguration.getPressedStateDuration()); - } - if (mFocusedNode != null && mFocusedNode.mIntentUrl != null) { - mWebView.playSoundEffect(SoundEffectConstants.CLICK); - overrideLoading(mFocusedNode.mIntentUrl); - } else { - WebViewCore.TouchUpData touchUpData = new WebViewCore.TouchUpData(); - // use "0" as generation id to inform WebKit to use the same x/y as - // it used when processing GET_TOUCH_HIGHLIGHT_RECTS - touchUpData.mMoveGeneration = 0; - mWebViewCore.sendMessage(EventHub.TOUCH_UP, touchUpData); - } - } - /* * Return true if the rect (e.g. plugin) is fully visible and maximized * inside the WebView. @@ -7544,490 +7249,11 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } private int getMaxTextScrollX() { - return Math.max(0, mEditTextContent.width() - mEditTextBounds.width()); + return Math.max(0, mEditTextContent.width() - mEditTextContentBounds.width()); } private int getMaxTextScrollY() { - return Math.max(0, mEditTextContent.height() - mEditTextBounds.height()); - } - - /** - * Used only by TouchEventQueue to store pending touch events. - */ - private static class QueuedTouch { - long mSequence; - MotionEvent mEvent; // Optional - TouchEventData mTed; // Optional - - QueuedTouch mNext; - - public QueuedTouch set(TouchEventData ted) { - mSequence = ted.mSequence; - mTed = ted; - mEvent = null; - mNext = null; - return this; - } - - public QueuedTouch set(MotionEvent ev, long sequence) { - mEvent = MotionEvent.obtain(ev); - mSequence = sequence; - mTed = null; - mNext = null; - return this; - } - - public QueuedTouch add(QueuedTouch other) { - if (other.mSequence < mSequence) { - other.mNext = this; - return other; - } - - QueuedTouch insertAt = this; - while (insertAt.mNext != null && insertAt.mNext.mSequence < other.mSequence) { - insertAt = insertAt.mNext; - } - other.mNext = insertAt.mNext; - insertAt.mNext = other; - return this; - } - } - - /** - * WebView handles touch events asynchronously since some events must be passed to WebKit - * for potentially slower processing. TouchEventQueue serializes touch events regardless - * of which path they take to ensure that no events are ever processed out of order - * by WebView. - */ - private class TouchEventQueue { - private long mNextTouchSequence = Long.MIN_VALUE + 1; - private long mLastHandledTouchSequence = Long.MIN_VALUE; - private long mIgnoreUntilSequence = Long.MIN_VALUE + 1; - - // Events waiting to be processed. - private QueuedTouch mTouchEventQueue; - - // Known events that are waiting on a response before being enqueued. - private QueuedTouch mPreQueue; - - // Pool of QueuedTouch objects saved for later use. - private QueuedTouch mQueuedTouchRecycleBin; - private int mQueuedTouchRecycleCount; - - private long mLastEventTime = Long.MAX_VALUE; - private static final int MAX_RECYCLED_QUEUED_TOUCH = 15; - - // milliseconds until we abandon hope of getting all of a previous gesture - private static final int QUEUED_GESTURE_TIMEOUT = 1000; - - private QueuedTouch obtainQueuedTouch() { - if (mQueuedTouchRecycleBin != null) { - QueuedTouch result = mQueuedTouchRecycleBin; - mQueuedTouchRecycleBin = result.mNext; - mQueuedTouchRecycleCount--; - return result; - } - return new QueuedTouch(); - } - - /** - * Allow events with any currently missing sequence numbers to be skipped in processing. - */ - public void ignoreCurrentlyMissingEvents() { - mIgnoreUntilSequence = mNextTouchSequence; - - // Run any events we have available and complete, pre-queued or otherwise. - runQueuedAndPreQueuedEvents(); - } - - private void runQueuedAndPreQueuedEvents() { - QueuedTouch qd = mPreQueue; - boolean fromPreQueue = true; - while (qd != null && qd.mSequence == mLastHandledTouchSequence + 1) { - handleQueuedTouch(qd); - QueuedTouch recycleMe = qd; - if (fromPreQueue) { - mPreQueue = qd.mNext; - } else { - mTouchEventQueue = qd.mNext; - } - recycleQueuedTouch(recycleMe); - mLastHandledTouchSequence++; - - long nextPre = mPreQueue != null ? mPreQueue.mSequence : Long.MAX_VALUE; - long nextQueued = mTouchEventQueue != null ? - mTouchEventQueue.mSequence : Long.MAX_VALUE; - fromPreQueue = nextPre < nextQueued; - qd = fromPreQueue ? mPreQueue : mTouchEventQueue; - } - } - - /** - * Add a TouchEventData to the pre-queue. - * - * An event in the pre-queue is an event that we know about that - * has been sent to webkit, but that we haven't received back and - * enqueued into the normal touch queue yet. If webkit ever times - * out and we need to ignore currently missing events, we'll run - * events from the pre-queue to patch the holes. - * - * @param ted TouchEventData to pre-queue - */ - public void preQueueTouchEventData(TouchEventData ted) { - QueuedTouch newTouch = obtainQueuedTouch().set(ted); - if (mPreQueue == null) { - mPreQueue = newTouch; - } else { - QueuedTouch insertionPoint = mPreQueue; - while (insertionPoint.mNext != null && - insertionPoint.mNext.mSequence < newTouch.mSequence) { - insertionPoint = insertionPoint.mNext; - } - newTouch.mNext = insertionPoint.mNext; - insertionPoint.mNext = newTouch; - } - } - - private void recycleQueuedTouch(QueuedTouch qd) { - if (mQueuedTouchRecycleCount < MAX_RECYCLED_QUEUED_TOUCH) { - qd.mNext = mQueuedTouchRecycleBin; - mQueuedTouchRecycleBin = qd; - mQueuedTouchRecycleCount++; - } - } - - /** - * Reset the touch event queue. This will dump any pending events - * and reset the sequence numbering. - */ - public void reset() { - mNextTouchSequence = Long.MIN_VALUE + 1; - mLastHandledTouchSequence = Long.MIN_VALUE; - mIgnoreUntilSequence = Long.MIN_VALUE + 1; - while (mTouchEventQueue != null) { - QueuedTouch recycleMe = mTouchEventQueue; - mTouchEventQueue = mTouchEventQueue.mNext; - recycleQueuedTouch(recycleMe); - } - while (mPreQueue != null) { - QueuedTouch recycleMe = mPreQueue; - mPreQueue = mPreQueue.mNext; - recycleQueuedTouch(recycleMe); - } - } - - /** - * Return the next valid sequence number for tagging incoming touch events. - * @return The next touch event sequence number - */ - public long nextTouchSequence() { - return mNextTouchSequence++; - } - - /** - * Enqueue a touch event in the form of TouchEventData. - * The sequence number will be read from the mSequence field of the argument. - * - * If the touch event's sequence number is the next in line to be processed, it will - * be handled before this method returns. Any subsequent events that have already - * been queued will also be processed in their proper order. - * - * @param ted Touch data to be processed in order. - * @return true if the event was processed before returning, false if it was just enqueued. - */ - public boolean enqueueTouchEvent(TouchEventData ted) { - // Remove from the pre-queue if present - QueuedTouch preQueue = mPreQueue; - if (preQueue != null) { - // On exiting this block, preQueue is set to the pre-queued QueuedTouch object - // if it was present in the pre-queue, and removed from the pre-queue itself. - if (preQueue.mSequence == ted.mSequence) { - mPreQueue = preQueue.mNext; - } else { - QueuedTouch prev = preQueue; - preQueue = null; - while (prev.mNext != null) { - if (prev.mNext.mSequence == ted.mSequence) { - preQueue = prev.mNext; - prev.mNext = preQueue.mNext; - break; - } else { - prev = prev.mNext; - } - } - } - } - - if (ted.mSequence < mLastHandledTouchSequence) { - // Stale event and we already moved on; drop it. (Should not be common.) - Log.w(LOGTAG, "Stale touch event " + MotionEvent.actionToString(ted.mAction) + - " received from webcore; ignoring"); - return false; - } - - if (dropStaleGestures(ted.mMotionEvent, ted.mSequence)) { - return false; - } - - // dropStaleGestures above might have fast-forwarded us to - // an event we have already. - runNextQueuedEvents(); - - if (mLastHandledTouchSequence + 1 == ted.mSequence) { - if (preQueue != null) { - recycleQueuedTouch(preQueue); - preQueue = null; - } - handleQueuedTouchEventData(ted); - - mLastHandledTouchSequence++; - - // Do we have any more? Run them if so. - runNextQueuedEvents(); - } else { - // Reuse the pre-queued object if we had it. - QueuedTouch qd = preQueue != null ? preQueue : obtainQueuedTouch().set(ted); - mTouchEventQueue = mTouchEventQueue == null ? qd : mTouchEventQueue.add(qd); - } - return true; - } - - /** - * Enqueue a touch event in the form of a MotionEvent from the framework. - * - * If the touch event's sequence number is the next in line to be processed, it will - * be handled before this method returns. Any subsequent events that have already - * been queued will also be processed in their proper order. - * - * @param ev MotionEvent to be processed in order - */ - public void enqueueTouchEvent(MotionEvent ev) { - final long sequence = nextTouchSequence(); - - if (dropStaleGestures(ev, sequence)) { - return; - } - - // dropStaleGestures above might have fast-forwarded us to - // an event we have already. - runNextQueuedEvents(); - - if (mLastHandledTouchSequence + 1 == sequence) { - handleQueuedMotionEvent(ev); - - mLastHandledTouchSequence++; - - // Do we have any more? Run them if so. - runNextQueuedEvents(); - } else { - QueuedTouch qd = obtainQueuedTouch().set(ev, sequence); - mTouchEventQueue = mTouchEventQueue == null ? qd : mTouchEventQueue.add(qd); - } - } - - private void runNextQueuedEvents() { - QueuedTouch qd = mTouchEventQueue; - while (qd != null && qd.mSequence == mLastHandledTouchSequence + 1) { - handleQueuedTouch(qd); - QueuedTouch recycleMe = qd; - qd = qd.mNext; - recycleQueuedTouch(recycleMe); - mLastHandledTouchSequence++; - } - mTouchEventQueue = qd; - } - - private boolean dropStaleGestures(MotionEvent ev, long sequence) { - if (ev != null && ev.getAction() == MotionEvent.ACTION_MOVE && !mConfirmMove) { - // This is to make sure that we don't attempt to process a tap - // or long press when webkit takes too long to get back to us. - // The movement will be properly confirmed when we process the - // enqueued event later. - final int dx = Math.round(ev.getX()) - mLastTouchX; - final int dy = Math.round(ev.getY()) - mLastTouchY; - if (dx * dx + dy * dy > mTouchSlopSquare) { - mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS); - mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS); - } - } - - if (mTouchEventQueue == null) { - return sequence <= mLastHandledTouchSequence; - } - - // If we have a new down event and it's been a while since the last event - // we saw, catch up as best we can and keep going. - if (ev != null && ev.getAction() == MotionEvent.ACTION_DOWN) { - long eventTime = ev.getEventTime(); - long lastHandledEventTime = mLastEventTime; - if (eventTime > lastHandledEventTime + QUEUED_GESTURE_TIMEOUT) { - Log.w(LOGTAG, "Got ACTION_DOWN but still waiting on stale event. " + - "Catching up."); - runQueuedAndPreQueuedEvents(); - - // Drop leftovers that we truly don't have. - QueuedTouch qd = mTouchEventQueue; - while (qd != null && qd.mSequence < sequence) { - QueuedTouch recycleMe = qd; - qd = qd.mNext; - recycleQueuedTouch(recycleMe); - } - mTouchEventQueue = qd; - mLastHandledTouchSequence = sequence - 1; - } - } - - if (mIgnoreUntilSequence - 1 > mLastHandledTouchSequence) { - QueuedTouch qd = mTouchEventQueue; - while (qd != null && qd.mSequence < mIgnoreUntilSequence) { - QueuedTouch recycleMe = qd; - qd = qd.mNext; - recycleQueuedTouch(recycleMe); - } - mTouchEventQueue = qd; - mLastHandledTouchSequence = mIgnoreUntilSequence - 1; - } - - if (mPreQueue != null) { - // Drop stale prequeued events - QueuedTouch qd = mPreQueue; - while (qd != null && qd.mSequence < mIgnoreUntilSequence) { - QueuedTouch recycleMe = qd; - qd = qd.mNext; - recycleQueuedTouch(recycleMe); - } - mPreQueue = qd; - } - - return sequence <= mLastHandledTouchSequence; - } - - private void handleQueuedTouch(QueuedTouch qt) { - if (qt.mTed != null) { - handleQueuedTouchEventData(qt.mTed); - } else { - handleQueuedMotionEvent(qt.mEvent); - qt.mEvent.recycle(); - } - } - - private void handleQueuedMotionEvent(MotionEvent ev) { - mLastEventTime = ev.getEventTime(); - int action = ev.getActionMasked(); - if (ev.getPointerCount() > 1) { // Multi-touch - handleMultiTouchInWebView(ev); - } else { - final ScaleGestureDetector detector = mZoomManager.getMultiTouchGestureDetector(); - if (detector != null && mPreventDefault != PREVENT_DEFAULT_YES) { - // ScaleGestureDetector needs a consistent event stream to operate properly. - // It won't take any action with fewer than two pointers, but it needs to - // update internal bookkeeping state. - detector.onTouchEvent(ev); - } - - handleTouchEventCommon(ev, action, Math.round(ev.getX()), Math.round(ev.getY())); - } - } - - private void handleQueuedTouchEventData(TouchEventData ted) { - if (ted.mMotionEvent != null) { - mLastEventTime = ted.mMotionEvent.getEventTime(); - } - if (!ted.mReprocess) { - if (ted.mAction == MotionEvent.ACTION_DOWN - && mPreventDefault == PREVENT_DEFAULT_MAYBE_YES) { - // if prevent default is called from WebCore, UI - // will not handle the rest of the touch events any - // more. - mPreventDefault = ted.mNativeResult ? PREVENT_DEFAULT_YES - : PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN; - } else if (ted.mAction == MotionEvent.ACTION_MOVE - && mPreventDefault == PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN) { - // the return for the first ACTION_MOVE will decide - // whether UI will handle touch or not. Currently no - // support for alternating prevent default - mPreventDefault = ted.mNativeResult ? PREVENT_DEFAULT_YES - : PREVENT_DEFAULT_NO; - } - if (mPreventDefault == PREVENT_DEFAULT_YES) { - mTouchHighlightRegion.setEmpty(); - } - } else { - if (ted.mPoints.length > 1) { // multi-touch - if (!ted.mNativeResult && mPreventDefault != PREVENT_DEFAULT_YES) { - mPreventDefault = PREVENT_DEFAULT_NO; - handleMultiTouchInWebView(ted.mMotionEvent); - } else { - mPreventDefault = PREVENT_DEFAULT_YES; - } - return; - } - - // prevent default is not called in WebCore, so the - // message needs to be reprocessed in UI - if (!ted.mNativeResult) { - // Following is for single touch. - switch (ted.mAction) { - case MotionEvent.ACTION_DOWN: - mLastDeferTouchX = ted.mPointsInView[0].x; - mLastDeferTouchY = ted.mPointsInView[0].y; - mDeferTouchMode = TOUCH_INIT_MODE; - break; - case MotionEvent.ACTION_MOVE: { - // no snapping in defer process - int x = ted.mPointsInView[0].x; - int y = ted.mPointsInView[0].y; - - if (mDeferTouchMode != TOUCH_DRAG_MODE) { - mDeferTouchMode = TOUCH_DRAG_MODE; - mLastDeferTouchX = x; - mLastDeferTouchY = y; - startScrollingLayer(x, y); - startDrag(); - } - int deltaX = pinLocX((int) (getScrollX() - + mLastDeferTouchX - x)) - - getScrollX(); - int deltaY = pinLocY((int) (getScrollY() - + mLastDeferTouchY - y)) - - getScrollY(); - doDrag(deltaX, deltaY); - if (deltaX != 0) mLastDeferTouchX = x; - if (deltaY != 0) mLastDeferTouchY = y; - break; - } - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - if (mDeferTouchMode == TOUCH_DRAG_MODE) { - // no fling in defer process - mScroller.springBack(getScrollX(), getScrollY(), 0, - computeMaxScrollX(), 0, - computeMaxScrollY()); - invalidate(); - WebViewCore.resumePriority(); - WebViewCore.resumeUpdatePicture(mWebViewCore); - } - mDeferTouchMode = TOUCH_DONE_MODE; - break; - case WebViewCore.ACTION_DOUBLETAP: - // doDoubleTap() needs mLastTouchX/Y as anchor - mLastDeferTouchX = ted.mPointsInView[0].x; - mLastDeferTouchY = ted.mPointsInView[0].y; - mZoomManager.handleDoubleTap(mLastTouchX, mLastTouchY); - mDeferTouchMode = TOUCH_DONE_MODE; - break; - case WebViewCore.ACTION_LONGPRESS: - HitTestResult hitTest = getHitTestResult(); - if (hitTest != null && hitTest.getType() - != HitTestResult.UNKNOWN_TYPE) { - performLongClick(); - } - mDeferTouchMode = TOUCH_DONE_MODE; - break; - } - } - } - } + return Math.max(0, mEditTextContent.height() - mEditTextContentBounds.height()); } //------------------------------------------------------------------------- @@ -8038,7 +7264,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc /** * General handler to receive message coming from webkit thread */ - class PrivateHandler extends Handler { + class PrivateHandler extends Handler implements WebViewInputDispatcher.UiCallbacks { @Override public void handleMessage(Message msg) { // exclude INVAL_RECT_MSG_ID since it is frequently output @@ -8079,20 +7305,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc ((Message) msg.obj).sendToTarget(); break; } - case PREVENT_DEFAULT_TIMEOUT: { - // if timeout happens, cancel it so that it won't block UI - // to continue handling touch events - if ((msg.arg1 == MotionEvent.ACTION_DOWN - && mPreventDefault == PREVENT_DEFAULT_MAYBE_YES) - || (msg.arg1 == MotionEvent.ACTION_MOVE - && mPreventDefault == PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN)) { - cancelWebCoreTouchEvent( - viewToContentX(mLastTouchX + getScrollX()), - viewToContentY(mLastTouchY + getScrollY()), - true); - } - break; - } case SCROLL_SELECT_TEXT: { if (mAutoScrollX == 0 && mAutoScrollY == 0) { mSentAutoScrollMessage = false; @@ -8108,48 +7320,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc SCROLL_SELECT_TEXT, SELECT_SCROLL_INTERVAL); break; } - case SWITCH_TO_SHORTPRESS: { - if (mTouchMode == TOUCH_INIT_MODE) { - mTouchMode = TOUCH_SHORTPRESS_MODE; - } else if (mTouchMode == TOUCH_DOUBLE_TAP_MODE) { - mTouchMode = TOUCH_DONE_MODE; - } - break; - } - case SWITCH_TO_LONGPRESS: { - removeTouchHighlight(); - if (inFullScreenMode() || mDeferTouchProcess) { - TouchEventData ted = new TouchEventData(); - ted.mAction = WebViewCore.ACTION_LONGPRESS; - ted.mIds = new int[1]; - ted.mIds[0] = 0; - ted.mPoints = new Point[1]; - ted.mPoints[0] = new Point(viewToContentX(mLastTouchX + getScrollX()), - viewToContentY(mLastTouchY + getScrollY())); - ted.mPointsInView = new Point[1]; - ted.mPointsInView[0] = new Point(mLastTouchX, mLastTouchY); - // metaState for long press is tricky. Should it be the - // state when the press started or when the press was - // released? Or some intermediary key state? For - // simplicity for now, we don't set it. - ted.mMetaState = 0; - ted.mReprocess = mDeferTouchProcess; - ted.mNativeLayer = nativeScrollableLayer( - ted.mPoints[0].x, ted.mPoints[0].y, - ted.mNativeLayerRect, null); - ted.mSequence = mTouchEventQueue.nextTouchSequence(); - mTouchEventQueue.preQueueTouchEventData(ted); - mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted); - } else if (mPreventDefault != PREVENT_DEFAULT_YES) { - mTouchMode = TOUCH_DONE_MODE; - performLongClick(); - } - break; - } - case RELEASE_SINGLE_TAP: { - doShortPress(); - break; - } case SCROLL_TO_MSG_ID: { // arg1 = animate, arg2 = onlyIfImeIsShowing // obj = Point(x, y) @@ -8207,6 +7377,8 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc if (mIsPaused) { nativeSetPauseDrawing(mNativeClass, true); } + mInputDispatcher = new WebViewInputDispatcher(this, + mWebViewCore.getInputDispatcherCallbacks()); break; case UPDATE_TEXTFIELD_TEXT_MSG_ID: // Make sure that the textfield is currently focused @@ -8263,20 +7435,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc break; case WEBCORE_NEED_TOUCH_EVENTS: - mForwardTouchEvents = (msg.arg1 != 0); - break; - - case PREVENT_TOUCH_ID: - if (inFullScreenMode()) { - break; - } - TouchEventData ted = (TouchEventData) msg.obj; - - if (mTouchEventQueue.enqueueTouchEvent(ted)) { - // WebCore is responding to us; remove pending timeout. - // It will be re-posted when needed. - removeMessages(PREVENT_DEFAULT_TIMEOUT); - } + mInputDispatcher.setWebKitWantsTouchEvents(msg.arg1 != 0); break; case REQUEST_KEYBOARD: @@ -8456,10 +7615,10 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc mFieldPointer = initData.mFieldPointer; mInputConnection.initEditorInfo(initData); mInputConnection.setTextAndKeepSelection(initData.mText); - mEditTextBounds.set(initData.mNodeBounds); + mEditTextContentBounds.set(initData.mContentBounds); mEditTextLayerId = initData.mNodeLayerId; nativeMapLayerRect(mNativeClass, mEditTextLayerId, - mEditTextBounds); + mEditTextContentBounds); mEditTextContent.set(initData.mContentRect); relocateAutoCompletePopup(); } @@ -8532,11 +7691,30 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } break; + case UPDATE_CONTENT_BOUNDS: + mEditTextContentBounds.set((Rect) msg.obj); + break; + default: super.handleMessage(msg); break; } } + + @Override + public Looper getUiLooper() { + return getLooper(); + } + + @Override + public void dispatchUiEvent(MotionEvent event, int eventType, int flags) { + onHandleUiEvent(event, eventType, flags); + } + + @Override + public Context getContext() { + return WebViewClassic.this.getContext(); + } } private void setHitTestTypeFromUrl(String url) { @@ -9418,13 +8596,11 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc && mWebView.getLayerType() != View.LAYER_TYPE_SOFTWARE) { hwAccelerated = true; } + + // result is of type LayerAndroid::InvalidateFlags, non zero means invalidate/redraw int result = nativeSetHwAccelerated(mNativeClass, hwAccelerated); - if (mWebViewCore == null || mBlockWebkitViewMessages) { - return; - } - if (result == 1) { - // Sync layers - mWebViewCore.layersDraw(); + if (mWebViewCore != null && !mBlockWebkitViewMessages && result != 0) { + mWebViewCore.contentDraw(); } } diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 5549d89..6390ffe 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -40,6 +40,7 @@ import android.view.MotionEvent; import android.view.SurfaceView; import android.view.View; import android.webkit.WebViewClassic.FocusNodeHref; +import android.webkit.WebViewInputDispatcher.WebKitCallbacks; import junit.framework.Assert; @@ -259,6 +260,10 @@ public final class WebViewCore { return mBrowserFrame; } + public WebKitCallbacks getInputDispatcherCallbacks() { + return mEventHub; + } + //------------------------------------------------------------------------- // Common methods //------------------------------------------------------------------------- @@ -595,11 +600,6 @@ public final class WebViewCore { Point wh); /** - * Update the layers' content - */ - private native boolean nativeUpdateLayers(int nativeClass, int baseLayer); - - /** * Notify webkit that animations have begun (on the hardware accelerated content) */ private native void nativeNotifyAnimationStarted(int nativeClass); @@ -663,6 +663,7 @@ public final class WebViewCore { int x, int y); private native void nativeTouchUp(int nativeClass, int touchGeneration, int framePtr, int nodePtr, int x, int y); + private native boolean nativeMouseClick(int nativeClass); private native boolean nativeHandleTouchEvent(int nativeClass, int action, int[] idArray, int[] xArray, int[] yArray, int count, @@ -949,7 +950,7 @@ public final class WebViewCore { public String mName; public String mLabel; public int mMaxLength; - public Rect mNodeBounds; + public Rect mContentBounds; public int mNodeLayerId; public Rect mContentRect; } @@ -1025,8 +1026,8 @@ public final class WebViewCore { "REQUEST_CURSOR_HREF", // = 137; "ADD_JS_INTERFACE", // = 138; "LOAD_DATA", // = 139; - "TOUCH_UP", // = 140; - "TOUCH_EVENT", // = 141; + "", // = 140; + "", // = 141; "SET_ACTIVE", // = 142; "ON_PAUSE", // = 143 "ON_RESUME", // = 144 @@ -1051,7 +1052,7 @@ public final class WebViewCore { /** * @hide */ - public class EventHub { + public class EventHub implements WebViewInputDispatcher.WebKitCallbacks { // Message Ids static final int REVEAL_SELECTION = 96; static final int SCROLL_TEXT_INPUT = 99; @@ -1096,11 +1097,6 @@ public final class WebViewCore { static final int ADD_JS_INTERFACE = 138; static final int LOAD_DATA = 139; - // motion - static final int TOUCH_UP = 140; - // message used to pass UI touch events to WebCore - static final int TOUCH_EVENT = 141; - // Used to tell the focus controller not to draw the blinking cursor, // based on whether the WebView has focus and whether the WebView's // cursor matches the webpage's focus. @@ -1115,9 +1111,6 @@ public final class WebViewCore { // Load and save web archives static final int SAVE_WEBARCHIVE = 147; - // Update layers - static final int WEBKIT_DRAW_LAYERS = 148; - static final int REMOVE_JS_INTERFACE = 149; // Network-based messaging @@ -1266,10 +1259,6 @@ public final class WebViewCore { webkitDraw(); break; - case WEBKIT_DRAW_LAYERS: - webkitDrawLayers(); - break; - case DESTROY: // Time to take down the world. Cancel all pending // loads and destroy the native view and frame. @@ -1299,7 +1288,13 @@ public final class WebViewCore { } else { xPercent = ((Float) msg.obj).floatValue(); } - nativeScrollFocusedTextInput(mNativeClass, xPercent, msg.arg2); + Rect contentBounds = new Rect(); + nativeScrollFocusedTextInput(mNativeClass, xPercent, + msg.arg2, contentBounds); + Message.obtain( + mWebViewClassic.mPrivateHandler, + WebViewClassic.UPDATE_CONTENT_BOUNDS, + contentBounds).sendToTarget(); break; case LOAD_URL: { @@ -1496,45 +1491,6 @@ public final class WebViewCore { nativeCloseIdleConnections(mNativeClass); break; - case TOUCH_UP: - TouchUpData touchUpData = (TouchUpData) msg.obj; - if (touchUpData.mNativeLayer != 0) { - nativeScrollLayer(mNativeClass, - touchUpData.mNativeLayer, - touchUpData.mNativeLayerRect); - } - nativeTouchUp(mNativeClass, - touchUpData.mMoveGeneration, - touchUpData.mFrame, touchUpData.mNode, - touchUpData.mX, touchUpData.mY); - break; - - case TOUCH_EVENT: { - TouchEventData ted = (TouchEventData) msg.obj; - final int count = ted.mPoints.length; - int[] xArray = new int[count]; - int[] yArray = new int[count]; - for (int c = 0; c < count; c++) { - xArray[c] = ted.mPoints[c].x; - yArray[c] = ted.mPoints[c].y; - } - if (ted.mNativeLayer != 0) { - nativeScrollLayer(mNativeClass, - ted.mNativeLayer, ted.mNativeLayerRect); - } - ted.mNativeResult = nativeHandleTouchEvent( - mNativeClass, ted.mAction, ted.mIds, xArray, - yArray, count, ted.mActionIndex, - ted.mMetaState); - Message.obtain( - mWebViewClassic.mPrivateHandler, - WebViewClassic.PREVENT_TOUCH_ID, - ted.mAction, - ted.mNativeResult ? 1 : 0, - ted).sendToTarget(); - break; - } - case SET_ACTIVE: nativeSetFocusControllerActive(mNativeClass, msg.arg1 == 1); break; @@ -1818,6 +1774,38 @@ public final class WebViewCore { } } + @Override + public Looper getWebKitLooper() { + return mHandler.getLooper(); + } + + @Override + public boolean dispatchWebKitEvent(MotionEvent event, int eventType, int flags) { + switch (eventType) { + case WebViewInputDispatcher.EVENT_TYPE_CLICK: + return nativeMouseClick(mNativeClass); + + case WebViewInputDispatcher.EVENT_TYPE_TOUCH: { + int count = event.getPointerCount(); + int[] idArray = new int[count]; + int[] xArray = new int[count]; + int[] yArray = new int[count]; + for (int i = 0; i < count; i++) { + idArray[i] = event.getPointerId(i); + xArray[i] = (int) event.getX(i); + yArray[i] = (int) event.getY(i); + } + return nativeHandleTouchEvent(mNativeClass, + event.getActionMasked(), + idArray, xArray, yArray, count, + event.getActionIndex(), event.getMetaState()); + } + + default: + return false; + } + } + /** * Send a message internally to the queue or to the handler */ @@ -2148,7 +2136,6 @@ public final class WebViewCore { // Used to avoid posting more than one draw message. private boolean mDrawIsScheduled; - private boolean mDrawLayersIsScheduled; // Used to avoid posting more than one split picture message. private boolean mSplitPictureIsScheduled; @@ -2194,25 +2181,6 @@ public final class WebViewCore { DrawData mLastDrawData = null; - // Only update the layers' content, not the base surface - // PictureSet. - private void webkitDrawLayers() { - mDrawLayersIsScheduled = false; - if (mDrawIsScheduled || mLastDrawData == null) { - removeMessages(EventHub.WEBKIT_DRAW); - webkitDraw(); - return; - } - // Directly update the layers we last passed to the UI side - if (nativeUpdateLayers(mNativeClass, mLastDrawData.mBaseLayer)) { - // If anything more complex than position has been touched, let's do a full draw - webkitDraw(); - } - mWebViewClassic.mPrivateHandler.removeMessages(WebViewClassic.INVAL_RECT_MSG_ID); - mWebViewClassic.mPrivateHandler.sendMessageAtFrontOfQueue(mWebViewClassic.mPrivateHandler - .obtainMessage(WebViewClassic.INVAL_RECT_MSG_ID)); - } - private Boolean m_skipDrawFlag = false; private boolean m_drawWasSkipped = false; @@ -2388,15 +2356,6 @@ public final class WebViewCore { } } - // called from JNI - void layersDraw() { - synchronized (this) { - if (mDrawLayersIsScheduled) return; - mDrawLayersIsScheduled = true; - mEventHub.sendMessage(Message.obtain(null, EventHub.WEBKIT_DRAW_LAYERS)); - } - } - // called by JNI private void contentScrollTo(int x, int y, boolean animate, boolean onlyIfImeIsShowing) { @@ -2845,7 +2804,7 @@ public final class WebViewCore { * Scroll the focused textfield to (xPercent, y) in document space */ private native void nativeScrollFocusedTextInput(int nativeClass, - float xPercent, int y); + float xPercent, int y, Rect contentBounds); // these must be in document space (i.e. not scaled/zoomed). private native void nativeSetScrollOffset(int nativeClass, diff --git a/core/java/android/webkit/WebViewInputDispatcher.java b/core/java/android/webkit/WebViewInputDispatcher.java new file mode 100644 index 0000000..e7024d9 --- /dev/null +++ b/core/java/android/webkit/WebViewInputDispatcher.java @@ -0,0 +1,1151 @@ +/* + * 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.webkit; + +import android.content.Context; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.os.SystemClock; +import android.util.Log; +import android.view.InputDevice; +import android.view.MotionEvent; +import android.view.ViewConfiguration; + +/** + * Perform asynchronous dispatch of input events in a {@link WebView}. + * + * This dispatcher is shared by the UI thread ({@link WebViewClassic}) and web kit + * thread ({@link WebViewCore}). The UI thread enqueues events for + * processing, waits for the web kit thread to handle them, and then performs + * additional processing depending on the outcome. + * + * How it works: + * + * 1. The web view thread receives an input event from the input system on the UI + * thread in its {@link WebViewClassic#onTouchEvent} handler. It sends the input event + * to the dispatcher, then immediately returns true to the input system to indicate that + * it will handle the event. + * + * 2. The web kit thread is notified that an event has been enqueued. Meanwhile additional + * events may be enqueued from the UI thread. In some cases, the dispatcher may decide to + * coalesce motion events into larger batches or to cancel events that have been + * sitting in the queue for too long. + * + * 3. The web kit thread wakes up and handles all input events that are waiting for it. + * After processing each input event, it informs the dispatcher whether the web application + * has decided to handle the event itself and to prevent default event handling. + * + * 4. If web kit indicates that it wants to prevent default event handling, then web kit + * consumes the remainder of the gesture and web view receives a cancel event if + * needed. Otherwise, the web view handles the gesture on the UI thread normally. + * + * 5. If the web kit thread takes too long to handle an input event, then it loses the + * right to handle it. The dispatcher synthesizes a cancellation event for web kit and + * then tells the web view on the UI thread to handle the event that timed out along + * with the rest of the gesture. + * + * One thing to keep in mind about the dispatcher is that what goes into the dispatcher + * is not necessarily what the web kit or UI thread will see. As mentioned above, the + * dispatcher may tweak the input event stream to improve responsiveness. Both web view and + * web kit are guaranteed to perceive a consistent stream of input events but + * they might not always see the same events (especially if one decides + * to prevent the other from handling a particular gesture). + * + * This implementation very deliberately does not refer to the {@link WebViewClassic} + * or {@link WebViewCore} classes, preferring to communicate with them only via + * interfaces to avoid unintentional coupling to their implementation details. + * + * Currently, the input dispatcher only handles pointer events (includes touch, + * hover and scroll events). In principle, it could be extended to handle trackball + * and key events if needed. + * + * @hide + */ +final class WebViewInputDispatcher { + private static final String TAG = "WebViewInputDispatcher"; + private static final boolean DEBUG = false; + // This enables batching of MotionEvents. It will combine multiple MotionEvents + // together into a single MotionEvent if more events come in while we are + // still waiting on the processing of a previous event. + // If this is set to false, we will instead opt to drop ACTION_MOVE + // events we cannot keep up with. + // TODO: If batching proves to be working well, remove this + private static final boolean ENABLE_EVENT_BATCHING = true; + + private final Object mLock = new Object(); + + // Pool of queued input events. (guarded by mLock) + private static final int MAX_DISPATCH_EVENT_POOL_SIZE = 10; + private DispatchEvent mDispatchEventPool; + private int mDispatchEventPoolSize; + + // Posted state, tracks events posted to the dispatcher. (guarded by mLock) + private final TouchStream mPostTouchStream = new TouchStream(); + private boolean mPostSendTouchEventsToWebKit; + private boolean mPostDoNotSendTouchEventsToWebKitUntilNextGesture; + private boolean mPostLongPressScheduled; + private boolean mPostClickScheduled; + private int mPostLastWebKitXOffset; + private int mPostLastWebKitYOffset; + private float mPostLastWebKitScale; + + // State for event tracking (click, longpress, double tap, etc..) + private boolean mIsDoubleTapCandidate; + private boolean mIsTapCandidate; + private float mInitialDownX; + private float mInitialDownY; + private float mTouchSlopSquared; + private float mDoubleTapSlopSquared; + + // Web kit state, tracks events observed by web kit. (guarded by mLock) + private final DispatchEventQueue mWebKitDispatchEventQueue = new DispatchEventQueue(); + private final TouchStream mWebKitTouchStream = new TouchStream(); + private final WebKitCallbacks mWebKitCallbacks; + private final WebKitHandler mWebKitHandler; + private boolean mWebKitDispatchScheduled; + private boolean mWebKitTimeoutScheduled; + private long mWebKitTimeoutTime; + + // UI state, tracks events observed by the UI. (guarded by mLock) + private final DispatchEventQueue mUiDispatchEventQueue = new DispatchEventQueue(); + private final TouchStream mUiTouchStream = new TouchStream(); + private final UiCallbacks mUiCallbacks; + private final UiHandler mUiHandler; + private boolean mUiDispatchScheduled; + + // Give up on web kit handling of input events when this timeout expires. + private static final long WEBKIT_TIMEOUT_MILLIS = 200; + private static final int TAP_TIMEOUT = ViewConfiguration.getTapTimeout(); + private static final int LONG_PRESS_TIMEOUT = + ViewConfiguration.getLongPressTimeout() + TAP_TIMEOUT; + private static final int DOUBLE_TAP_TIMEOUT = ViewConfiguration.getDoubleTapTimeout(); + + /** + * Event type: Indicates a touch event type. + * + * This event is delivered together with a {@link MotionEvent} with one of the + * following actions: {@link MotionEvent#ACTION_DOWN}, {@link MotionEvent#ACTION_MOVE}, + * {@link MotionEvent#ACTION_UP}, {@link MotionEvent#ACTION_POINTER_DOWN}, + * {@link MotionEvent#ACTION_POINTER_UP}, {@link MotionEvent#ACTION_CANCEL}. + */ + public static final int EVENT_TYPE_TOUCH = 0; + + /** + * Event type: Indicates a hover event type. + * + * This event is delivered together with a {@link MotionEvent} with one of the + * following actions: {@link MotionEvent#ACTION_HOVER_ENTER}, + * {@link MotionEvent#ACTION_HOVER_MOVE}, {@link MotionEvent#ACTION_HOVER_MOVE}. + */ + public static final int EVENT_TYPE_HOVER = 1; + + /** + * Event type: Indicates a scroll event type. + * + * This event is delivered together with a {@link MotionEvent} with action + * {@link MotionEvent#ACTION_SCROLL}. + */ + public static final int EVENT_TYPE_SCROLL = 2; + + /** + * Event type: Indicates a long-press event type. + * + * This event is delivered in the middle of a sequence of {@link #EVENT_TYPE_TOUCH} events. + * It includes a {@link MotionEvent} with action {@link MotionEvent#ACTION_MOVE} + * that indicates the current touch coordinates of the long-press. + * + * This event is sent when the current touch gesture has been held longer than + * the long-press interval. + */ + public static final int EVENT_TYPE_LONG_PRESS = 3; + + /** + * Event type: Indicates a click event type. + * + * This event is delivered after a sequence of {@link #EVENT_TYPE_TOUCH} events that + * comprise a complete gesture ending with {@link MotionEvent#ACTION_UP}. + * It includes a {@link MotionEvent} with action {@link MotionEvent#ACTION_UP} + * that indicates the location of the click. + * + * This event is sent shortly after the end of a touch after the double-tap + * interval has expired to indicate a click. + */ + public static final int EVENT_TYPE_CLICK = 4; + + /** + * Event type: Indicates a double-tap event type. + * + * This event is delivered after a sequence of {@link #EVENT_TYPE_TOUCH} events that + * comprise a complete gesture ending with {@link MotionEvent#ACTION_UP}. + * It includes a {@link MotionEvent} with action {@link MotionEvent#ACTION_UP} + * that indicates the location of the double-tap. + * + * This event is sent immediately after a sequence of two touches separated + * in time by no more than the double-tap interval and separated in space + * by no more than the double-tap slop. + */ + public static final int EVENT_TYPE_DOUBLE_TAP = 5; + + /** + * Flag: This event is private to this queue. Do not forward it. + */ + public static final int FLAG_PRIVATE = 1 << 0; + + /** + * Flag: This event is currently being processed by web kit. + * If a timeout occurs, make a copy of it before forwarding the event to another queue. + */ + public static final int FLAG_WEBKIT_IN_PROGRESS = 1 << 1; + + /** + * Flag: A timeout occurred while waiting for web kit to process this input event. + */ + public static final int FLAG_WEBKIT_TIMEOUT = 1 << 2; + + /** + * Flag: Indicates that the event was transformed for delivery to web kit. + * The event must be transformed back before being delivered to the UI. + */ + public static final int FLAG_WEBKIT_TRANSFORMED_EVENT = 1 << 3; + + public WebViewInputDispatcher(UiCallbacks uiCallbacks, WebKitCallbacks webKitCallbacks) { + this.mUiCallbacks = uiCallbacks; + mUiHandler = new UiHandler(uiCallbacks.getUiLooper()); + + this.mWebKitCallbacks = webKitCallbacks; + mWebKitHandler = new WebKitHandler(webKitCallbacks.getWebKitLooper()); + + ViewConfiguration config = ViewConfiguration.get(mUiCallbacks.getContext()); + mDoubleTapSlopSquared = config.getScaledDoubleTapSlop(); + mDoubleTapSlopSquared = (mDoubleTapSlopSquared * mDoubleTapSlopSquared); + mTouchSlopSquared = config.getScaledTouchSlop(); + mTouchSlopSquared = (mTouchSlopSquared * mTouchSlopSquared); + } + + /** + * Sets whether web kit wants to receive touch events. + * + * @param enable True to enable dispatching of touch events to web kit, otherwise + * web kit will be skipped. + */ + public void setWebKitWantsTouchEvents(boolean enable) { + if (DEBUG) { + Log.d(TAG, "webkitWantsTouchEvents: " + enable); + } + synchronized (mLock) { + if (mPostSendTouchEventsToWebKit != enable) { + if (!enable) { + enqueueWebKitCancelTouchEventIfNeededLocked(); + } + mPostSendTouchEventsToWebKit = enable; + } + } + } + + /** + * Posts a pointer event to the dispatch queue. + * + * @param event The event to post. + * @param webKitXOffset X offset to apply to events before dispatching them to web kit. + * @param webKitYOffset Y offset to apply to events before dispatching them to web kit. + * @param webKitScale The scale factor to apply to translated events before dispatching + * them to web kit. + * @return True if the dispatcher will handle the event, false if the event is unsupported. + */ + public boolean postPointerEvent(MotionEvent event, + int webKitXOffset, int webKitYOffset, float webKitScale) { + if (event == null + || (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) { + throw new IllegalArgumentException("event must be a pointer event"); + } + + if (DEBUG) { + Log.d(TAG, "postPointerEvent: " + event); + } + + final int action = event.getActionMasked(); + final int eventType; + switch (action) { + case MotionEvent.ACTION_DOWN: + case MotionEvent.ACTION_MOVE: + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_POINTER_DOWN: + case MotionEvent.ACTION_POINTER_UP: + case MotionEvent.ACTION_CANCEL: + eventType = EVENT_TYPE_TOUCH; + break; + case MotionEvent.ACTION_SCROLL: + eventType = EVENT_TYPE_SCROLL; + break; + case MotionEvent.ACTION_HOVER_ENTER: + case MotionEvent.ACTION_HOVER_MOVE: + case MotionEvent.ACTION_HOVER_EXIT: + eventType = EVENT_TYPE_HOVER; + break; + default: + return false; // currently unsupported event type + } + + synchronized (mLock) { + // Ensure that the event is consistent and should be delivered. + MotionEvent eventToEnqueue = event; + if (eventType == EVENT_TYPE_TOUCH) { + eventToEnqueue = mPostTouchStream.update(event); + if (eventToEnqueue == null) { + if (DEBUG) { + Log.d(TAG, "postPointerEvent: dropped event " + event); + } + unscheduleLongPressLocked(); + unscheduleClickLocked(); + return false; + } + + if (mPostSendTouchEventsToWebKit + && mPostDoNotSendTouchEventsToWebKitUntilNextGesture + && action == MotionEvent.ACTION_DOWN) { + // Recover from a previous web kit timeout. + mPostDoNotSendTouchEventsToWebKitUntilNextGesture = false; + } + } + + // Copy the event because we need to retain ownership. + if (eventToEnqueue == event) { + eventToEnqueue = event.copy(); + } + + DispatchEvent d = obtainDispatchEventLocked(eventToEnqueue, eventType, 0, + webKitXOffset, webKitYOffset, webKitScale); + enqueueEventLocked(d); + } + return true; + } + + private void scheduleLongPressLocked() { + unscheduleLongPressLocked(); + mPostLongPressScheduled = true; + mUiHandler.sendEmptyMessageDelayed(UiHandler.MSG_LONG_PRESS, + LONG_PRESS_TIMEOUT); + } + + private void unscheduleLongPressLocked() { + if (mPostLongPressScheduled) { + mPostLongPressScheduled = false; + mUiHandler.removeMessages(UiHandler.MSG_LONG_PRESS); + } + } + + private void postLongPress() { + synchronized (mLock) { + if (!mPostLongPressScheduled) { + return; + } + mPostLongPressScheduled = false; + + MotionEvent event = mPostTouchStream.getLastEvent(); + if (event == null) { + return; + } + + switch (event.getActionMasked()) { + case MotionEvent.ACTION_DOWN: + case MotionEvent.ACTION_MOVE: + case MotionEvent.ACTION_POINTER_DOWN: + case MotionEvent.ACTION_POINTER_UP: + break; + default: + return; + } + + MotionEvent eventToEnqueue = MotionEvent.obtainNoHistory(event); + eventToEnqueue.setAction(MotionEvent.ACTION_MOVE); + DispatchEvent d = obtainDispatchEventLocked(eventToEnqueue, EVENT_TYPE_LONG_PRESS, 0, + mPostLastWebKitXOffset, mPostLastWebKitYOffset, mPostLastWebKitScale); + enqueueEventLocked(d); + } + } + + private void scheduleClickLocked() { + unscheduleClickLocked(); + mPostClickScheduled = true; + mUiHandler.sendEmptyMessageDelayed(UiHandler.MSG_CLICK, DOUBLE_TAP_TIMEOUT); + } + + private void unscheduleClickLocked() { + if (mPostClickScheduled) { + mPostClickScheduled = false; + mUiHandler.removeMessages(UiHandler.MSG_CLICK); + } + } + + private void postClick() { + synchronized (mLock) { + if (!mPostClickScheduled) { + return; + } + mPostClickScheduled = false; + + MotionEvent event = mPostTouchStream.getLastEvent(); + if (event == null || event.getAction() != MotionEvent.ACTION_UP) { + return; + } + + MotionEvent eventToEnqueue = MotionEvent.obtainNoHistory(event); + DispatchEvent d = obtainDispatchEventLocked(eventToEnqueue, EVENT_TYPE_CLICK, 0, + mPostLastWebKitXOffset, mPostLastWebKitYOffset, mPostLastWebKitScale); + enqueueEventLocked(d); + } + } + + private void checkForDoubleTapOnDownLocked(MotionEvent event) { + mIsDoubleTapCandidate = false; + if (!mPostClickScheduled) { + return; + } + int deltaX = (int) mInitialDownX - (int) event.getX(); + int deltaY = (int) mInitialDownY - (int) event.getY(); + if ((deltaX * deltaX + deltaY * deltaY) < mDoubleTapSlopSquared) { + unscheduleClickLocked(); + mIsDoubleTapCandidate = true; + } + } + + private boolean isClickCandidateLocked(MotionEvent event) { + if (event == null + || event.getActionMasked() != MotionEvent.ACTION_UP + || !mIsTapCandidate) { + return false; + } + long downDuration = event.getEventTime() - event.getDownTime(); + return downDuration < TAP_TIMEOUT; + } + + private void enqueueDoubleTapLocked(MotionEvent event) { + unscheduleClickLocked(); + MotionEvent eventToEnqueue = MotionEvent.obtainNoHistory(event); + DispatchEvent d = obtainDispatchEventLocked(eventToEnqueue, EVENT_TYPE_DOUBLE_TAP, 0, + mPostLastWebKitXOffset, mPostLastWebKitYOffset, mPostLastWebKitScale); + enqueueEventLocked(d); + mIsDoubleTapCandidate = false; + } + + private void checkForSlopLocked(MotionEvent event) { + if (!mIsTapCandidate) { + return; + } + int deltaX = (int) mInitialDownX - (int) event.getX(); + int deltaY = (int) mInitialDownY - (int) event.getY(); + if ((deltaX * deltaX + deltaY * deltaY) > mTouchSlopSquared) { + unscheduleLongPressLocked(); + mIsTapCandidate = false; + } + } + + private void updateStateTrackersLocked(DispatchEvent d, MotionEvent event) { + mPostLastWebKitXOffset = d.mWebKitXOffset; + mPostLastWebKitYOffset = d.mWebKitYOffset; + mPostLastWebKitScale = d.mWebKitScale; + int action = event != null ? event.getAction() : MotionEvent.ACTION_CANCEL; + if (d.mEventType != EVENT_TYPE_TOUCH) { + return; + } + + if (action == MotionEvent.ACTION_CANCEL + || event.getPointerCount() > 1) { + unscheduleLongPressLocked(); + unscheduleClickLocked(); + mIsDoubleTapCandidate = false; + mIsTapCandidate = false; + } else if (action == MotionEvent.ACTION_DOWN) { + checkForDoubleTapOnDownLocked(event); + scheduleLongPressLocked(); + mIsTapCandidate = true; + mInitialDownX = event.getX(); + mInitialDownY = event.getY(); + } else if (action == MotionEvent.ACTION_UP) { + unscheduleLongPressLocked(); + if (isClickCandidateLocked(event)) { + if (mIsDoubleTapCandidate) { + enqueueDoubleTapLocked(event); + } else { + scheduleClickLocked(); + } + } + } else if (action == MotionEvent.ACTION_MOVE) { + checkForSlopLocked(event); + } + } + + /** + * Dispatches pending web kit events. + * Must only be called from the web kit thread. + * + * This method may be used to flush the queue of pending input events + * immediately. This method may help to reduce input dispatch latency + * if called before certain expensive operations such as drawing. + */ + public void dispatchWebKitEvents() { + dispatchWebKitEvents(false); + } + + private void dispatchWebKitEvents(boolean calledFromHandler) { + for (;;) { + // Get the next event, but leave it in the queue so we can move it to the UI + // queue if a timeout occurs. + DispatchEvent d; + MotionEvent event; + final int eventType; + int flags; + synchronized (mLock) { + if (!ENABLE_EVENT_BATCHING) { + drainStaleWebKitEventsLocked(); + } + d = mWebKitDispatchEventQueue.mHead; + if (d == null) { + if (mWebKitDispatchScheduled) { + mWebKitDispatchScheduled = false; + if (!calledFromHandler) { + mWebKitHandler.removeMessages( + WebKitHandler.MSG_DISPATCH_WEBKIT_EVENTS); + } + } + return; + } + + event = d.mEvent; + if (event != null) { + event.offsetLocation(d.mWebKitXOffset, d.mWebKitYOffset); + event.scale(d.mWebKitScale); + d.mFlags |= FLAG_WEBKIT_TRANSFORMED_EVENT; + } + + eventType = d.mEventType; + if (eventType == EVENT_TYPE_TOUCH) { + event = mWebKitTouchStream.update(event); + if (DEBUG && event == null && d.mEvent != null) { + Log.d(TAG, "dispatchWebKitEvents: dropped event " + d.mEvent); + } + } + + d.mFlags |= FLAG_WEBKIT_IN_PROGRESS; + flags = d.mFlags; + } + + // Handle the event. + final boolean preventDefault; + if (event == null) { + preventDefault = false; + } else { + preventDefault = dispatchWebKitEvent(event, eventType, flags); + } + + synchronized (mLock) { + flags = d.mFlags; + d.mFlags = flags & ~FLAG_WEBKIT_IN_PROGRESS; + boolean recycleEvent = event != d.mEvent; + + if ((flags & FLAG_WEBKIT_TIMEOUT) != 0) { + // A timeout occurred! + recycleDispatchEventLocked(d); + } else { + // Web kit finished in a timely manner. Dequeue the event. + assert mWebKitDispatchEventQueue.mHead == d; + mWebKitDispatchEventQueue.dequeue(); + + updateWebKitTimeoutLocked(); + + if ((flags & FLAG_PRIVATE) != 0) { + // Event was intended for web kit only. All done. + recycleDispatchEventLocked(d); + } else if (preventDefault) { + // Web kit has decided to consume the event! + if (d.mEventType == EVENT_TYPE_TOUCH) { + enqueueUiCancelTouchEventIfNeededLocked(); + } + } else { + // Web kit is being friendly. Pass the event to the UI. + enqueueUiEventUnbatchedLocked(d); + } + } + + if (event != null && recycleEvent) { + event.recycle(); + } + } + } + } + + // Runs on web kit thread. + private boolean dispatchWebKitEvent(MotionEvent event, int eventType, int flags) { + if (DEBUG) { + Log.d(TAG, "dispatchWebKitEvent: event=" + event + + ", eventType=" + eventType + ", flags=" + flags); + } + boolean preventDefault = mWebKitCallbacks.dispatchWebKitEvent( + event, eventType, flags); + if (DEBUG) { + Log.d(TAG, "dispatchWebKitEvent: preventDefault=" + preventDefault); + } + return preventDefault; + } + + private boolean isMoveEventLocked(DispatchEvent d) { + return d.mEvent != null + && d.mEvent.getActionMasked() == MotionEvent.ACTION_MOVE; + } + + private void drainStaleWebKitEventsLocked() { + DispatchEvent d = mWebKitDispatchEventQueue.mHead; + while (d != null && d.mNext != null + && isMoveEventLocked(d) + && isMoveEventLocked(d.mNext)) { + DispatchEvent next = d.mNext; + skipWebKitEventLocked(d); + d = next; + } + mWebKitDispatchEventQueue.mHead = d; + } + + // Runs on UI thread in response to the web kit thread appearing to be unresponsive. + private void handleWebKitTimeout() { + synchronized (mLock) { + if (!mWebKitTimeoutScheduled) { + return; + } + mWebKitTimeoutScheduled = false; + + if (DEBUG) { + Log.d(TAG, "handleWebKitTimeout: timeout occurred!"); + } + + // Drain the web kit event queue. + DispatchEvent d = mWebKitDispatchEventQueue.dequeueList(); + + // If web kit was processing an event (must be at the head of the list because + // it can only do one at a time), then clone it or ignore it. + if ((d.mFlags & FLAG_WEBKIT_IN_PROGRESS) != 0) { + d.mFlags |= FLAG_WEBKIT_TIMEOUT; + if ((d.mFlags & FLAG_PRIVATE) != 0) { + d = d.mNext; // the event is private to web kit, ignore it + } else { + d = copyDispatchEventLocked(d); + d.mFlags &= ~FLAG_WEBKIT_IN_PROGRESS; + } + } + + // Enqueue all non-private events for handling by the UI thread. + while (d != null) { + DispatchEvent next = d.mNext; + skipWebKitEventLocked(d); + d = next; + } + + // Tell web kit to cancel all pending touches. + // This also prevents us from sending web kit any more touches until the + // next gesture begins. (As required to ensure touch event stream consistency.) + enqueueWebKitCancelTouchEventIfNeededLocked(); + } + } + + private void skipWebKitEventLocked(DispatchEvent d) { + d.mNext = null; + if ((d.mFlags & FLAG_PRIVATE) != 0) { + recycleDispatchEventLocked(d); + } else { + d.mFlags |= FLAG_WEBKIT_TIMEOUT; + enqueueUiEventUnbatchedLocked(d); + } + } + + /** + * Dispatches pending UI events. + * Must only be called from the UI thread. + * + * This method may be used to flush the queue of pending input events + * immediately. This method may help to reduce input dispatch latency + * if called before certain expensive operations such as drawing. + */ + public void dispatchUiEvents() { + dispatchUiEvents(false); + } + + private void dispatchUiEvents(boolean calledFromHandler) { + for (;;) { + MotionEvent event; + final int eventType; + final int flags; + synchronized (mLock) { + DispatchEvent d = mUiDispatchEventQueue.dequeue(); + if (d == null) { + if (mUiDispatchScheduled) { + mUiDispatchScheduled = false; + if (!calledFromHandler) { + mUiHandler.removeMessages(UiHandler.MSG_DISPATCH_UI_EVENTS); + } + } + return; + } + + event = d.mEvent; + if (event != null && (d.mFlags & FLAG_WEBKIT_TRANSFORMED_EVENT) != 0) { + event.scale(1.0f / d.mWebKitScale); + event.offsetLocation(-d.mWebKitXOffset, -d.mWebKitYOffset); + d.mFlags &= ~FLAG_WEBKIT_TRANSFORMED_EVENT; + } + + eventType = d.mEventType; + if (eventType == EVENT_TYPE_TOUCH) { + event = mUiTouchStream.update(event); + if (DEBUG && event == null && d.mEvent != null) { + Log.d(TAG, "dispatchUiEvents: dropped event " + d.mEvent); + } + } + + flags = d.mFlags; + + updateStateTrackersLocked(d, event); + if (event == d.mEvent) { + d.mEvent = null; // retain ownership of event, don't recycle it yet + } + recycleDispatchEventLocked(d); + } + + // Handle the event. + if (event != null) { + dispatchUiEvent(event, eventType, flags); + event.recycle(); + } + } + } + + // Runs on UI thread. + private void dispatchUiEvent(MotionEvent event, int eventType, int flags) { + if (DEBUG) { + Log.d(TAG, "dispatchUiEvent: event=" + event + + ", eventType=" + eventType + ", flags=" + flags); + } + mUiCallbacks.dispatchUiEvent(event, eventType, flags); + } + + private void enqueueEventLocked(DispatchEvent d) { + if (!shouldSkipWebKit(d.mEventType)) { + enqueueWebKitEventLocked(d); + } else { + enqueueUiEventLocked(d); + } + } + + private boolean shouldSkipWebKit(int eventType) { + switch (eventType) { + case EVENT_TYPE_CLICK: + case EVENT_TYPE_HOVER: + case EVENT_TYPE_SCROLL: + return false; + case EVENT_TYPE_TOUCH: + return !mPostSendTouchEventsToWebKit + || mPostDoNotSendTouchEventsToWebKitUntilNextGesture; + } + return true; + } + + private void enqueueWebKitCancelTouchEventIfNeededLocked() { + // We want to cancel touch events that were delivered to web kit. + // Enqueue a null event at the end of the queue if needed. + if (mWebKitTouchStream.isCancelNeeded() || !mWebKitDispatchEventQueue.isEmpty()) { + DispatchEvent d = obtainDispatchEventLocked(null, EVENT_TYPE_TOUCH, FLAG_PRIVATE, + 0, 0, 1.0f); + enqueueWebKitEventUnbatchedLocked(d); + mPostDoNotSendTouchEventsToWebKitUntilNextGesture = true; + } + } + + private void enqueueWebKitEventLocked(DispatchEvent d) { + if (batchEventLocked(d, mWebKitDispatchEventQueue.mTail)) { + if (DEBUG) { + Log.d(TAG, "enqueueWebKitEventLocked: batched event " + d.mEvent); + } + recycleDispatchEventLocked(d); + } else { + enqueueWebKitEventUnbatchedLocked(d); + } + } + + private void enqueueWebKitEventUnbatchedLocked(DispatchEvent d) { + if (DEBUG) { + Log.d(TAG, "enqueueWebKitEventUnbatchedLocked: enqueued event " + d.mEvent); + } + mWebKitDispatchEventQueue.enqueue(d); + scheduleWebKitDispatchLocked(); + updateWebKitTimeoutLocked(); + } + + private void scheduleWebKitDispatchLocked() { + if (!mWebKitDispatchScheduled) { + mWebKitHandler.sendEmptyMessage(WebKitHandler.MSG_DISPATCH_WEBKIT_EVENTS); + mWebKitDispatchScheduled = true; + } + } + + private void updateWebKitTimeoutLocked() { + DispatchEvent d = mWebKitDispatchEventQueue.mHead; + if (d != null && mWebKitTimeoutScheduled && mWebKitTimeoutTime == d.mTimeoutTime) { + return; + } + if (mWebKitTimeoutScheduled) { + mUiHandler.removeMessages(UiHandler.MSG_WEBKIT_TIMEOUT); + mWebKitTimeoutScheduled = false; + } + if (d != null) { + mUiHandler.sendEmptyMessageAtTime(UiHandler.MSG_WEBKIT_TIMEOUT, d.mTimeoutTime); + mWebKitTimeoutScheduled = true; + mWebKitTimeoutTime = d.mTimeoutTime; + } + } + + private void enqueueUiCancelTouchEventIfNeededLocked() { + // We want to cancel touch events that were delivered to the UI. + // Enqueue a null event at the end of the queue if needed. + if (mUiTouchStream.isCancelNeeded() || !mUiDispatchEventQueue.isEmpty()) { + DispatchEvent d = obtainDispatchEventLocked(null, EVENT_TYPE_TOUCH, FLAG_PRIVATE, + 0, 0, 1.0f); + enqueueUiEventUnbatchedLocked(d); + } + } + + private void enqueueUiEventLocked(DispatchEvent d) { + if (batchEventLocked(d, mUiDispatchEventQueue.mTail)) { + if (DEBUG) { + Log.d(TAG, "enqueueUiEventLocked: batched event " + d.mEvent); + } + recycleDispatchEventLocked(d); + } else { + enqueueUiEventUnbatchedLocked(d); + } + } + + private void enqueueUiEventUnbatchedLocked(DispatchEvent d) { + if (DEBUG) { + Log.d(TAG, "enqueueUiEventUnbatchedLocked: enqueued event " + d.mEvent); + } + mUiDispatchEventQueue.enqueue(d); + scheduleUiDispatchLocked(); + } + + private void scheduleUiDispatchLocked() { + if (!mUiDispatchScheduled) { + mUiHandler.sendEmptyMessage(UiHandler.MSG_DISPATCH_UI_EVENTS); + mUiDispatchScheduled = true; + } + } + + private boolean batchEventLocked(DispatchEvent in, DispatchEvent tail) { + if (!ENABLE_EVENT_BATCHING) { + return false; + } + if (tail != null && tail.mEvent != null && in.mEvent != null + && in.mEventType == tail.mEventType + && in.mFlags == tail.mFlags + && in.mWebKitXOffset == tail.mWebKitXOffset + && in.mWebKitYOffset == tail.mWebKitYOffset + && in.mWebKitScale == tail.mWebKitScale) { + return tail.mEvent.addBatch(in.mEvent); + } + return false; + } + + private DispatchEvent obtainDispatchEventLocked(MotionEvent event, + int eventType, int flags, int webKitXOffset, int webKitYOffset, float webKitScale) { + DispatchEvent d = obtainUninitializedDispatchEventLocked(); + d.mEvent = event; + d.mEventType = eventType; + d.mFlags = flags; + d.mTimeoutTime = SystemClock.uptimeMillis() + WEBKIT_TIMEOUT_MILLIS; + d.mWebKitXOffset = webKitXOffset; + d.mWebKitYOffset = webKitYOffset; + d.mWebKitScale = webKitScale; + if (DEBUG) { + Log.d(TAG, "Timeout time: " + (d.mTimeoutTime - SystemClock.uptimeMillis())); + } + return d; + } + + private DispatchEvent copyDispatchEventLocked(DispatchEvent d) { + DispatchEvent copy = obtainUninitializedDispatchEventLocked(); + if (d.mEvent != null) { + copy.mEvent = d.mEvent.copy(); + } + copy.mEventType = d.mEventType; + copy.mFlags = d.mFlags; + copy.mTimeoutTime = d.mTimeoutTime; + copy.mWebKitXOffset = d.mWebKitXOffset; + copy.mWebKitYOffset = d.mWebKitYOffset; + copy.mWebKitScale = d.mWebKitScale; + copy.mNext = d.mNext; + return copy; + } + + private DispatchEvent obtainUninitializedDispatchEventLocked() { + DispatchEvent d = mDispatchEventPool; + if (d != null) { + mDispatchEventPoolSize -= 1; + mDispatchEventPool = d.mNext; + d.mNext = null; + } else { + d = new DispatchEvent(); + } + return d; + } + + private void recycleDispatchEventLocked(DispatchEvent d) { + if (d.mEvent != null) { + d.mEvent.recycle(); + d.mEvent = null; + } + + if (mDispatchEventPoolSize < MAX_DISPATCH_EVENT_POOL_SIZE) { + mDispatchEventPoolSize += 1; + d.mNext = mDispatchEventPool; + mDispatchEventPool = d; + } + } + + /* Implemented by {@link WebViewClassic} to perform operations on the UI thread. */ + public static interface UiCallbacks { + /** + * Gets the UI thread's looper. + * @return The looper. + */ + public Looper getUiLooper(); + + /** + * Gets the UI's context + * @return The context + */ + public Context getContext(); + + /** + * Dispatches an event to the UI. + * @param event The event. + * @param eventType The event type. + * @param flags The event's dispatch flags. + */ + public void dispatchUiEvent(MotionEvent event, int eventType, int flags); + } + + /* Implemented by {@link WebViewCore} to perform operations on the web kit thread. */ + public static interface WebKitCallbacks { + /** + * Gets the web kit thread's looper. + * @return The looper. + */ + public Looper getWebKitLooper(); + + /** + * Dispatches an event to web kit. + * @param event The event. + * @param eventType The event type. + * @param flags The event's dispatch flags. + * @return True if web kit wants to prevent default event handling. + */ + public boolean dispatchWebKitEvent(MotionEvent event, int eventType, int flags); + } + + // Runs on UI thread. + private final class UiHandler extends Handler { + public static final int MSG_DISPATCH_UI_EVENTS = 1; + public static final int MSG_WEBKIT_TIMEOUT = 2; + public static final int MSG_LONG_PRESS = 3; + public static final int MSG_CLICK = 4; + + public UiHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_DISPATCH_UI_EVENTS: + dispatchUiEvents(true); + break; + case MSG_WEBKIT_TIMEOUT: + handleWebKitTimeout(); + break; + case MSG_LONG_PRESS: + postLongPress(); + break; + case MSG_CLICK: + postClick(); + break; + default: + throw new IllegalStateException("Unknown message type: " + msg.what); + } + } + } + + // Runs on web kit thread. + private final class WebKitHandler extends Handler { + public static final int MSG_DISPATCH_WEBKIT_EVENTS = 1; + + public WebKitHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_DISPATCH_WEBKIT_EVENTS: + dispatchWebKitEvents(true); + break; + default: + throw new IllegalStateException("Unknown message type: " + msg.what); + } + } + } + + private static final class DispatchEvent { + public DispatchEvent mNext; + + public MotionEvent mEvent; + public int mEventType; + public int mFlags; + public long mTimeoutTime; + public int mWebKitXOffset; + public int mWebKitYOffset; + public float mWebKitScale; + } + + private static final class DispatchEventQueue { + public DispatchEvent mHead; + public DispatchEvent mTail; + + public boolean isEmpty() { + return mHead != null; + } + + public void enqueue(DispatchEvent d) { + if (mHead == null) { + mHead = d; + mTail = d; + } else { + mTail.mNext = d; + mTail = d; + } + } + + public DispatchEvent dequeue() { + DispatchEvent d = mHead; + if (d != null) { + DispatchEvent next = d.mNext; + if (next == null) { + mHead = null; + mTail = null; + } else { + mHead = next; + d.mNext = null; + } + } + return d; + } + + public DispatchEvent dequeueList() { + DispatchEvent d = mHead; + if (d != null) { + mHead = null; + mTail = null; + } + return d; + } + } + + /** + * Keeps track of a stream of touch events so that we can discard touch + * events that would make the stream inconsistent. + */ + private static final class TouchStream { + private MotionEvent mLastEvent; + + /** + * Gets the last touch event that was delivered. + * @return The last touch event, or null if none. + */ + public MotionEvent getLastEvent() { + return mLastEvent; + } + + /** + * Updates the touch event stream. + * @param event The event that we intend to send, or null to cancel the + * touch event stream. + * @return The event that we should actually send, or null if no event should + * be sent because the proposed event would make the stream inconsistent. + */ + public MotionEvent update(MotionEvent event) { + if (event == null) { + if (isCancelNeeded()) { + event = mLastEvent; + if (event != null) { + event.setAction(MotionEvent.ACTION_CANCEL); + mLastEvent = null; + } + } + return event; + } + + switch (event.getActionMasked()) { + case MotionEvent.ACTION_MOVE: + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_POINTER_DOWN: + case MotionEvent.ACTION_POINTER_UP: + if (mLastEvent == null + || mLastEvent.getAction() == MotionEvent.ACTION_UP) { + return null; + } + updateLastEvent(event); + return event; + + case MotionEvent.ACTION_DOWN: + updateLastEvent(event); + return event; + + case MotionEvent.ACTION_CANCEL: + if (mLastEvent == null) { + return null; + } + updateLastEvent(null); + return event; + + default: + return null; + } + } + + /** + * Returns true if there is a gesture in progress that may need to be canceled. + * @return True if cancel is needed. + */ + public boolean isCancelNeeded() { + return mLastEvent != null && mLastEvent.getAction() != MotionEvent.ACTION_UP; + } + + private void updateLastEvent(MotionEvent event) { + if (mLastEvent != null) { + mLastEvent.recycle(); + } + mLastEvent = event != null ? MotionEvent.obtainNoHistory(event) : null; + } + } +}
\ No newline at end of file diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java index 4e13ea1..c2559a5 100644 --- a/core/java/android/widget/HorizontalScrollView.java +++ b/core/java/android/widget/HorizontalScrollView.java @@ -77,7 +77,7 @@ public class HorizontalScrollView extends FrameLayout { /** * Position of the last motion event. */ - private float mLastMotionX; + private int mLastMotionX; /** * True when the layout has changed but the traversal has not come through yet. @@ -460,7 +460,7 @@ public class HorizontalScrollView extends FrameLayout { } final int pointerIndex = ev.findPointerIndex(activePointerId); - final float x = ev.getX(pointerIndex); + final int x = (int) ev.getX(pointerIndex); final int xDiff = (int) Math.abs(x - mLastMotionX); if (xDiff > mTouchSlop) { mIsBeingDragged = true; @@ -473,7 +473,7 @@ public class HorizontalScrollView extends FrameLayout { } case MotionEvent.ACTION_DOWN: { - final float x = ev.getX(); + final int x = (int) ev.getX(); if (!inChild((int) x, (int) ev.getY())) { mIsBeingDragged = false; recycleVelocityTracker(); @@ -505,18 +505,18 @@ public class HorizontalScrollView extends FrameLayout { mIsBeingDragged = false; mActivePointerId = INVALID_POINTER; if (mScroller.springBack(mScrollX, mScrollY, 0, getScrollRange(), 0, 0)) { - invalidate(); + postInvalidateOnAnimation(); } break; case MotionEvent.ACTION_POINTER_DOWN: { final int index = ev.getActionIndex(); - mLastMotionX = ev.getX(index); + mLastMotionX = (int) ev.getX(index); mActivePointerId = ev.getPointerId(index); break; } case MotionEvent.ACTION_POINTER_UP: onSecondaryPointerUp(ev); - mLastMotionX = ev.getX(ev.findPointerIndex(mActivePointerId)); + mLastMotionX = (int) ev.getX(ev.findPointerIndex(mActivePointerId)); break; } @@ -550,7 +550,7 @@ public class HorizontalScrollView extends FrameLayout { } // Remember where the motion event started - mLastMotionX = ev.getX(); + mLastMotionX = (int) ev.getX(); mActivePointerId = ev.getPointerId(0); break; } @@ -558,7 +558,7 @@ public class HorizontalScrollView extends FrameLayout { if (mIsBeingDragged) { // Scroll to follow the motion event final int activePointerIndex = ev.findPointerIndex(mActivePointerId); - final float x = ev.getX(activePointerIndex); + final int x = (int) ev.getX(activePointerIndex); final int deltaX = (int) (mLastMotionX - x); mLastMotionX = x; @@ -591,7 +591,7 @@ public class HorizontalScrollView extends FrameLayout { } if (mEdgeGlowLeft != null && (!mEdgeGlowLeft.isFinished() || !mEdgeGlowRight.isFinished())) { - invalidate(); + postInvalidateOnAnimation(); } } } @@ -608,7 +608,7 @@ public class HorizontalScrollView extends FrameLayout { } else { if (mScroller.springBack(mScrollX, mScrollY, 0, getScrollRange(), 0, 0)) { - invalidate(); + postInvalidateOnAnimation(); } } } @@ -626,7 +626,7 @@ public class HorizontalScrollView extends FrameLayout { case MotionEvent.ACTION_CANCEL: if (mIsBeingDragged && getChildCount() > 0) { if (mScroller.springBack(mScrollX, mScrollY, 0, getScrollRange(), 0, 0)) { - invalidate(); + postInvalidateOnAnimation(); } mActivePointerId = INVALID_POINTER; mIsBeingDragged = false; @@ -654,7 +654,7 @@ public class HorizontalScrollView extends FrameLayout { // active pointer and adjust accordingly. // TODO: Make this decision more intelligent. final int newPointerIndex = pointerIndex == 0 ? 1 : 0; - mLastMotionX = ev.getX(newPointerIndex); + mLastMotionX = (int) ev.getX(newPointerIndex); mActivePointerId = ev.getPointerId(newPointerIndex); if (mVelocityTracker != null) { mVelocityTracker.clear(); @@ -1084,7 +1084,7 @@ public class HorizontalScrollView extends FrameLayout { dx = Math.max(0, Math.min(scrollX + dx, maxX)) - scrollX; mScroller.startScroll(scrollX, mScrollY, dx, 0); - invalidate(); + postInvalidateOnAnimation(); } else { if (!mScroller.isFinished()) { mScroller.abortAnimation(); @@ -1206,7 +1206,7 @@ public class HorizontalScrollView extends FrameLayout { } if (!awakenScrollBars()) { - invalidate(); + postInvalidateOnAnimation(); } } } @@ -1452,7 +1452,7 @@ public class HorizontalScrollView extends FrameLayout { newFocused.requestFocus(movingRight ? View.FOCUS_RIGHT : View.FOCUS_LEFT); } - invalidate(); + postInvalidateOnAnimation(); } } @@ -1503,7 +1503,7 @@ public class HorizontalScrollView extends FrameLayout { canvas.translate(-height + mPaddingTop, Math.min(0, scrollX)); mEdgeGlowLeft.setSize(height, getWidth()); if (mEdgeGlowLeft.draw(canvas)) { - invalidate(); + postInvalidateOnAnimation(); } canvas.restoreToCount(restoreCount); } @@ -1517,7 +1517,7 @@ public class HorizontalScrollView extends FrameLayout { -(Math.max(getScrollRange(), scrollX) + width)); mEdgeGlowRight.setSize(height, width); if (mEdgeGlowRight.draw(canvas)) { - invalidate(); + postInvalidateOnAnimation(); } canvas.restoreToCount(restoreCount); } diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java index 3bc4f7f..0b49404 100644 --- a/core/java/android/widget/ProgressBar.java +++ b/core/java/android/widget/ProgressBar.java @@ -37,9 +37,11 @@ import android.graphics.drawable.shapes.RoundRectShape; import android.graphics.drawable.shapes.Shape; import android.os.Parcel; import android.os.Parcelable; -import android.os.SystemClock; import android.util.AttributeSet; -import android.view.Choreographer; +import android.util.Pool; +import android.util.Poolable; +import android.util.PoolableManager; +import android.util.Pools; import android.view.Gravity; import android.view.RemotableViewMethod; import android.view.View; @@ -55,6 +57,8 @@ import android.view.animation.LinearInterpolator; import android.view.animation.Transformation; import android.widget.RemoteViews.RemoteView; +import java.util.ArrayList; + /** * <p> @@ -218,6 +222,10 @@ public class ProgressBar extends View { private boolean mShouldStartAnimationDrawable; private boolean mInDrawing; + private boolean mAttached; + private boolean mRefreshIsPosted; + + private final ArrayList<RefreshData> mRefreshData = new ArrayList<RefreshData>(); private AccessibilityEventSender mAccessibilityEventSender; @@ -558,29 +566,76 @@ public class ProgressBar extends View { } private class RefreshProgressRunnable implements Runnable { + public void run() { + synchronized (ProgressBar.this) { + final int count = mRefreshData.size(); + for (int i = 0; i < count; i++) { + final RefreshData rd = mRefreshData.get(i); + doRefreshProgress(rd.id, rd.progress, rd.fromUser, true); + rd.recycle(); + } + mRefreshData.clear(); + mRefreshIsPosted = false; + } + } + } - private int mId; - private int mProgress; - private boolean mFromUser; + private static class RefreshData implements Poolable<RefreshData> { + public int id; + public int progress; + public boolean fromUser; - RefreshProgressRunnable(int id, int progress, boolean fromUser) { - mId = id; - mProgress = progress; - mFromUser = fromUser; - } + private RefreshData mNext; + private boolean mIsPooled; - public void run() { - doRefreshProgress(mId, mProgress, mFromUser, true); - // Put ourselves back in the cache when we are done - mRefreshProgressRunnable = this; + private static final int POOL_MAX = 24; + private static final Pool<RefreshData> sPool = Pools.synchronizedPool( + Pools.finitePool(new PoolableManager<RefreshData>() { + @Override + public RefreshData newInstance() { + return new RefreshData(); + } + + @Override + public void onAcquired(RefreshData element) { + } + + @Override + public void onReleased(RefreshData element) { + } + }, POOL_MAX)); + + public static RefreshData obtain(int id, int progress, boolean fromUser) { + RefreshData rd = sPool.acquire(); + rd.id = id; + rd.progress = progress; + rd.fromUser = fromUser; + return rd; } - public void setup(int id, int progress, boolean fromUser) { - mId = id; - mProgress = progress; - mFromUser = fromUser; + public void recycle() { + sPool.release(this); + } + + @Override + public void setNextPoolable(RefreshData element) { + mNext = element; + } + + @Override + public RefreshData getNextPoolable() { + return mNext; + } + + @Override + public boolean isPooled() { + return mIsPooled; + } + + @Override + public void setPooled(boolean isPooled) { + mIsPooled = isPooled; } - } private synchronized void doRefreshProgress(int id, int progress, boolean fromUser, @@ -619,14 +674,16 @@ public class ProgressBar extends View { if (mRefreshProgressRunnable != null) { // Use cached RefreshProgressRunnable if available r = mRefreshProgressRunnable; - // Uncache it - mRefreshProgressRunnable = null; - r.setup(id, progress, fromUser); } else { // Make a new one - r = new RefreshProgressRunnable(id, progress, fromUser); + r = new RefreshProgressRunnable(); + } + final RefreshData rd = RefreshData.obtain(id, progress, fromUser); + mRefreshData.add(rd); + if (mAttached && !mRefreshIsPosted) { + post(r); + mRefreshIsPosted = true; } - post(r); } } @@ -1092,6 +1149,18 @@ public class ProgressBar extends View { if (mIndeterminate) { startAnimation(); } + if (mRefreshData != null) { + synchronized (this) { + final int count = mRefreshData.size(); + for (int i = 0; i < count; i++) { + final RefreshData rd = mRefreshData.get(i); + doRefreshProgress(rd.id, rd.progress, rd.fromUser, true); + rd.recycle(); + } + mRefreshData.clear(); + } + } + mAttached = true; } @Override @@ -1099,7 +1168,10 @@ public class ProgressBar extends View { if (mIndeterminate) { stopAnimation(); } - if(mRefreshProgressRunnable != null) { + if (mRefreshProgressRunnable != null) { + removeCallbacks(mRefreshProgressRunnable); + } + if (mRefreshProgressRunnable != null && mRefreshIsPosted) { removeCallbacks(mRefreshProgressRunnable); } if (mAccessibilityEventSender != null) { @@ -1108,6 +1180,7 @@ public class ProgressBar extends View { // This should come after stopAnimation(), otherwise an invalidate message remains in the // queue, which can prevent the entire view hierarchy from being GC'ed during a rotation super.onDetachedFromWindow(); + mAttached = false; } @Override diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java index e0e3e93..0f0dbae 100644 --- a/core/java/android/widget/ScrollView.java +++ b/core/java/android/widget/ScrollView.java @@ -73,7 +73,7 @@ public class ScrollView extends FrameLayout { /** * Position of the last motion event. */ - private float mLastMotionY; + private int mLastMotionY; /** * True when the layout has changed but the traversal has not come through yet. @@ -472,8 +472,8 @@ public class ScrollView extends FrameLayout { } final int pointerIndex = ev.findPointerIndex(activePointerId); - final float y = ev.getY(pointerIndex); - final int yDiff = (int) Math.abs(y - mLastMotionY); + final int y = (int) ev.getY(pointerIndex); + final int yDiff = Math.abs(y - mLastMotionY); if (yDiff > mTouchSlop) { mIsBeingDragged = true; mLastMotionY = y; @@ -487,7 +487,7 @@ public class ScrollView extends FrameLayout { } case MotionEvent.ACTION_DOWN: { - final float y = ev.getY(); + final int y = (int) ev.getY(); if (!inChild((int) ev.getX(), (int) y)) { mIsBeingDragged = false; recycleVelocityTracker(); @@ -522,7 +522,7 @@ public class ScrollView extends FrameLayout { mActivePointerId = INVALID_POINTER; recycleVelocityTracker(); if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange())) { - invalidate(); + postInvalidateOnAnimation(); } break; case MotionEvent.ACTION_POINTER_UP: @@ -564,7 +564,7 @@ public class ScrollView extends FrameLayout { } // Remember where the motion event started - mLastMotionY = ev.getY(); + mLastMotionY = (int) ev.getY(); mActivePointerId = ev.getPointerId(0); break; } @@ -572,8 +572,8 @@ public class ScrollView extends FrameLayout { if (mIsBeingDragged) { // Scroll to follow the motion event final int activePointerIndex = ev.findPointerIndex(mActivePointerId); - final float y = ev.getY(activePointerIndex); - final int deltaY = (int) (mLastMotionY - y); + final int y = (int) ev.getY(activePointerIndex); + final int deltaY = mLastMotionY - y; mLastMotionY = y; final int oldX = mScrollX; @@ -605,7 +605,7 @@ public class ScrollView extends FrameLayout { } if (mEdgeGlowTop != null && (!mEdgeGlowTop.isFinished() || !mEdgeGlowBottom.isFinished())) { - invalidate(); + postInvalidateOnAnimation(); } } } @@ -622,7 +622,7 @@ public class ScrollView extends FrameLayout { } else { if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange())) { - invalidate(); + postInvalidateOnAnimation(); } } } @@ -634,7 +634,7 @@ public class ScrollView extends FrameLayout { case MotionEvent.ACTION_CANCEL: if (mIsBeingDragged && getChildCount() > 0) { if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange())) { - invalidate(); + postInvalidateOnAnimation(); } mActivePointerId = INVALID_POINTER; endDrag(); @@ -642,13 +642,13 @@ public class ScrollView extends FrameLayout { break; case MotionEvent.ACTION_POINTER_DOWN: { final int index = ev.getActionIndex(); - mLastMotionY = ev.getY(index); + mLastMotionY = (int) ev.getY(index); mActivePointerId = ev.getPointerId(index); break; } case MotionEvent.ACTION_POINTER_UP: onSecondaryPointerUp(ev); - mLastMotionY = ev.getY(ev.findPointerIndex(mActivePointerId)); + mLastMotionY = (int) ev.getY(ev.findPointerIndex(mActivePointerId)); break; } return true; @@ -663,7 +663,7 @@ public class ScrollView extends FrameLayout { // active pointer and adjust accordingly. // TODO: Make this decision more intelligent. final int newPointerIndex = pointerIndex == 0 ? 1 : 0; - mLastMotionY = ev.getY(newPointerIndex); + mLastMotionY = (int) ev.getY(newPointerIndex); mActivePointerId = ev.getPointerId(newPointerIndex); if (mVelocityTracker != null) { mVelocityTracker.clear(); @@ -1047,7 +1047,7 @@ public class ScrollView extends FrameLayout { dy = Math.max(0, Math.min(scrollY + dy, maxY)) - scrollY; mScroller.startScroll(mScrollX, scrollY, 0, dy); - invalidate(); + postInvalidateOnAnimation(); } else { if (!mScroller.isFinished()) { mScroller.abortAnimation(); @@ -1174,7 +1174,7 @@ public class ScrollView extends FrameLayout { if (!awakenScrollBars()) { // Keep on drawing until the animation has finished. - invalidate(); + postInvalidateOnAnimation(); } } else { if (mFlingStrictSpan != null) { @@ -1430,7 +1430,7 @@ public class ScrollView extends FrameLayout { mFlingStrictSpan = StrictMode.enterCriticalSpan("ScrollView-fling"); } - invalidate(); + postInvalidateOnAnimation(); } } @@ -1495,7 +1495,7 @@ public class ScrollView extends FrameLayout { canvas.translate(mPaddingLeft, Math.min(0, scrollY)); mEdgeGlowTop.setSize(width, getHeight()); if (mEdgeGlowTop.draw(canvas)) { - invalidate(); + postInvalidateOnAnimation(); } canvas.restoreToCount(restoreCount); } @@ -1509,7 +1509,7 @@ public class ScrollView extends FrameLayout { canvas.rotate(180, width, 0); mEdgeGlowBottom.setSize(width, height); if (mEdgeGlowBottom.draw(canvas)) { - invalidate(); + postInvalidateOnAnimation(); } canvas.restoreToCount(restoreCount); } diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index 4d308dd..f77e8f3 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -223,6 +223,14 @@ public class LockPatternUtils { } } + public int getCurrentUser() { + if (Process.myUid() == Process.SYSTEM_UID) { + return mCurrentUserId; + } else { + throw new SecurityException("Only the system process can get the current user"); + } + } + public void removeUser(int userId) { if (Process.myUid() == Process.SYSTEM_UID) { try { diff --git a/core/jni/Android.mk b/core/jni/Android.mk index ec0fe00..523b2d5 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -48,6 +48,7 @@ LOCAL_SRC_FILES:= \ android_view_Surface.cpp \ android_view_TextureView.cpp \ android_view_InputChannel.cpp \ + android_view_InputDevice.cpp \ android_view_InputEventReceiver.cpp \ android_view_KeyEvent.cpp \ android_view_KeyCharacterMap.cpp \ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index e705c47..879b9d2 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -148,7 +148,6 @@ extern int register_android_net_TrafficStats(JNIEnv* env); extern int register_android_net_wifi_WifiManager(JNIEnv* env); extern int register_android_text_AndroidCharacter(JNIEnv *env); extern int register_android_text_AndroidBidi(JNIEnv *env); -extern int register_android_text_KeyCharacterMap(JNIEnv *env); extern int register_android_opengl_classes(JNIEnv *env); extern int register_android_bluetooth_HeadsetBase(JNIEnv* env); extern int register_android_bluetooth_BluetoothAudioGateway(JNIEnv* env); @@ -168,7 +167,9 @@ extern int register_android_app_backup_FullBackup(JNIEnv *env); extern int register_android_app_ActivityThread(JNIEnv *env); extern int register_android_app_NativeActivity(JNIEnv *env); extern int register_android_view_InputChannel(JNIEnv* env); +extern int register_android_view_InputDevice(JNIEnv* env); extern int register_android_view_InputEventReceiver(JNIEnv* env); +extern int register_android_view_KeyCharacterMap(JNIEnv *env); extern int register_android_view_KeyEvent(JNIEnv* env); extern int register_android_view_MotionEvent(JNIEnv* env); extern int register_android_view_PointerIcon(JNIEnv* env); @@ -1082,7 +1083,8 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_emoji_EmojiFactory), REG_JNI(register_android_text_AndroidCharacter), REG_JNI(register_android_text_AndroidBidi), - REG_JNI(register_android_text_KeyCharacterMap), + REG_JNI(register_android_view_InputDevice), + REG_JNI(register_android_view_KeyCharacterMap), REG_JNI(register_android_os_Process), REG_JNI(register_android_os_SystemProperties), REG_JNI(register_android_os_Binder), diff --git a/core/jni/android_view_InputDevice.cpp b/core/jni/android_view_InputDevice.cpp new file mode 100644 index 0000000..d7d476a --- /dev/null +++ b/core/jni/android_view_InputDevice.cpp @@ -0,0 +1,97 @@ +/* + * 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. + */ + +#include <androidfw/Input.h> + +#include <android_runtime/AndroidRuntime.h> +#include <nativehelper/jni.h> +#include <nativehelper/JNIHelp.h> + +#include <ScopedLocalRef.h> + +#include "android_view_InputDevice.h" +#include "android_view_KeyCharacterMap.h" + +namespace android { + +static struct { + jclass clazz; + + jmethodID ctor; + jmethodID addMotionRange; +} gInputDeviceClassInfo; + +jobject android_view_InputDevice_create(JNIEnv* env, const InputDeviceInfo& deviceInfo) { + ScopedLocalRef<jstring> nameObj(env, env->NewStringUTF(deviceInfo.getName().string())); + if (!nameObj.get()) { + return NULL; + } + + ScopedLocalRef<jstring> descriptorObj(env, + env->NewStringUTF(deviceInfo.getDescriptor().string())); + if (!descriptorObj.get()) { + return NULL; + } + + ScopedLocalRef<jobject> kcmObj(env, + android_view_KeyCharacterMap_create(env, deviceInfo.getId(), + deviceInfo.getKeyCharacterMap())); + if (!kcmObj.get()) { + return NULL; + } + + ScopedLocalRef<jobject> inputDeviceObj(env, env->NewObject(gInputDeviceClassInfo.clazz, + gInputDeviceClassInfo.ctor, deviceInfo.getId(), nameObj.get(), + descriptorObj.get(), deviceInfo.getSources(), deviceInfo.getKeyboardType(), + kcmObj.get())); + + const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges(); + for (size_t i = 0; i < ranges.size(); i++) { + const InputDeviceInfo::MotionRange& range = ranges.itemAt(i); + env->CallVoidMethod(inputDeviceObj.get(), gInputDeviceClassInfo.addMotionRange, + range.axis, range.source, range.min, range.max, range.flat, range.fuzz); + if (env->ExceptionCheck()) { + return NULL; + } + } + + return env->NewLocalRef(inputDeviceObj.get()); +} + + +#define FIND_CLASS(var, className) \ + var = env->FindClass(className); \ + LOG_FATAL_IF(! var, "Unable to find class " className); + +#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ + var = env->GetMethodID(clazz, methodName, methodDescriptor); \ + LOG_FATAL_IF(! var, "Unable to find method " methodName); + +int register_android_view_InputDevice(JNIEnv* env) +{ + FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice"); + gInputDeviceClassInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceClassInfo.clazz)); + + GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz, + "<init>", "(ILjava/lang/String;Ljava/lang/String;IILandroid/view/KeyCharacterMap;)V"); + + GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz, + "addMotionRange", "(IIFFFF)V"); + + return 0; +} + +}; // namespace android diff --git a/core/jni/android_view_InputDevice.h b/core/jni/android_view_InputDevice.h new file mode 100644 index 0000000..78651ba --- /dev/null +++ b/core/jni/android_view_InputDevice.h @@ -0,0 +1,31 @@ +/* + * 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. + */ + +#ifndef _ANDROID_VIEW_INPUTDEVICE_H +#define _ANDROID_VIEW_INPUTDEVICE_H + +#include "jni.h" + +#include <androidfw/InputDevice.h> + +namespace android { + +/* Creates an InputDevice object from the given information. */ +extern jobject android_view_InputDevice_create(JNIEnv* env, const InputDeviceInfo& deviceInfo); + +} // namespace android + +#endif // _ANDROID_VIEW_INPUTDEVICE_H diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp index 348437d..8f6f5f4 100644 --- a/core/jni/android_view_InputEventReceiver.cpp +++ b/core/jni/android_view_InputEventReceiver.cpp @@ -52,8 +52,7 @@ public: status_t initialize(); status_t finishInputEvent(uint32_t seq, bool handled); - status_t consumeEvents(bool consumeBatches); - static int handleReceiveCallback(int receiveFd, int events, void* data); + status_t consumeEvents(JNIEnv* env, bool consumeBatches); protected: virtual ~NativeInputEventReceiver(); @@ -68,6 +67,8 @@ private: const char* getInputChannelName() { return mInputConsumer.getChannel()->getName().string(); } + + static int handleReceiveCallback(int receiveFd, int events, void* data); }; @@ -128,11 +129,13 @@ int NativeInputEventReceiver::handleReceiveCallback(int receiveFd, int events, v return 1; } - status_t status = r->consumeEvents(false /*consumeBatches*/); + JNIEnv* env = AndroidRuntime::getJNIEnv(); + status_t status = r->consumeEvents(env, false /*consumeBatches*/); + r->mMessageQueue->raiseAndClearException(env, "handleReceiveCallback"); return status == OK || status == NO_MEMORY ? 1 : 0; } -status_t NativeInputEventReceiver::consumeEvents(bool consumeBatches) { +status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, bool consumeBatches) { #if DEBUG_DISPATCH_CYCLE ALOGD("channel '%s' ~ Consuming input events, consumeBatches=%s.", getInputChannelName(), consumeBatches ? "true" : "false"); @@ -142,7 +145,7 @@ status_t NativeInputEventReceiver::consumeEvents(bool consumeBatches) { mBatchedInputEventPending = false; } - JNIEnv* env = AndroidRuntime::getJNIEnv(); + bool skipCallbacks = false; for (;;) { uint32_t seq; InputEvent* inputEvent; @@ -150,7 +153,8 @@ status_t NativeInputEventReceiver::consumeEvents(bool consumeBatches) { consumeBatches, &seq, &inputEvent); if (status) { if (status == WOULD_BLOCK) { - if (mInputConsumer.hasPendingBatch() && !mBatchedInputEventPending) { + if (!skipCallbacks && !mBatchedInputEventPending + && mInputConsumer.hasPendingBatch()) { // There is a pending batch. Come back later. mBatchedInputEventPending = true; #if DEBUG_DISPATCH_CYCLE @@ -159,8 +163,8 @@ status_t NativeInputEventReceiver::consumeEvents(bool consumeBatches) { #endif env->CallVoidMethod(mReceiverObjGlobal, gInputEventReceiverClassInfo.dispatchBatchedInputEventPending); - if (mMessageQueue->raiseAndClearException( - env, "dispatchBatchedInputEventPending")) { + if (env->ExceptionCheck()) { + ALOGE("Exception dispatching batched input events."); mBatchedInputEventPending = false; // try again later } } @@ -172,46 +176,47 @@ status_t NativeInputEventReceiver::consumeEvents(bool consumeBatches) { } assert(inputEvent); - jobject inputEventObj; - switch (inputEvent->getType()) { - case AINPUT_EVENT_TYPE_KEY: + if (!skipCallbacks) { + jobject inputEventObj; + switch (inputEvent->getType()) { + case AINPUT_EVENT_TYPE_KEY: #if DEBUG_DISPATCH_CYCLE - ALOGD("channel '%s' ~ Received key event.", getInputChannelName()); + ALOGD("channel '%s' ~ Received key event.", getInputChannelName()); #endif - inputEventObj = android_view_KeyEvent_fromNative(env, - static_cast<KeyEvent*>(inputEvent)); - mMessageQueue->raiseAndClearException(env, "new KeyEvent"); - break; + inputEventObj = android_view_KeyEvent_fromNative(env, + static_cast<KeyEvent*>(inputEvent)); + break; - case AINPUT_EVENT_TYPE_MOTION: + case AINPUT_EVENT_TYPE_MOTION: #if DEBUG_DISPATCH_CYCLE - ALOGD("channel '%s' ~ Received motion event.", getInputChannelName()); + ALOGD("channel '%s' ~ Received motion event.", getInputChannelName()); #endif - inputEventObj = android_view_MotionEvent_obtainAsCopy(env, - static_cast<MotionEvent*>(inputEvent)); - mMessageQueue->raiseAndClearException(env, "new MotionEvent"); - break; - - default: - assert(false); // InputConsumer should prevent this from ever happening - inputEventObj = NULL; - } + inputEventObj = android_view_MotionEvent_obtainAsCopy(env, + static_cast<MotionEvent*>(inputEvent)); + break; - if (!inputEventObj) { - ALOGW("channel '%s' ~ Failed to obtain event object.", getInputChannelName()); - mInputConsumer.sendFinishedSignal(seq, false); - continue; - } + default: + assert(false); // InputConsumer should prevent this from ever happening + inputEventObj = NULL; + } + if (inputEventObj) { #if DEBUG_DISPATCH_CYCLE - ALOGD("channel '%s' ~ Dispatching input event.", getInputChannelName()); + ALOGD("channel '%s' ~ Dispatching input event.", getInputChannelName()); #endif - env->CallVoidMethod(mReceiverObjGlobal, - gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj); - - env->DeleteLocalRef(inputEventObj); + env->CallVoidMethod(mReceiverObjGlobal, + gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj); + if (env->ExceptionCheck()) { + ALOGE("Exception dispatching input event."); + skipCallbacks = true; + } + } else { + ALOGW("channel '%s' ~ Failed to obtain event object.", getInputChannelName()); + skipCallbacks = true; + } + } - if (mMessageQueue->raiseAndClearException(env, "dispatchInputEvent")) { + if (skipCallbacks) { mInputConsumer.sendFinishedSignal(seq, false); } } @@ -268,8 +273,8 @@ static void nativeFinishInputEvent(JNIEnv* env, jclass clazz, jint receiverPtr, static void nativeConsumeBatchedInputEvents(JNIEnv* env, jclass clazz, jint receiverPtr) { sp<NativeInputEventReceiver> receiver = reinterpret_cast<NativeInputEventReceiver*>(receiverPtr); - status_t status = receiver->consumeEvents(true /*consumeBatches*/); - if (status && status != DEAD_OBJECT) { + status_t status = receiver->consumeEvents(env, true /*consumeBatches*/); + if (status && status != DEAD_OBJECT && !env->ExceptionCheck()) { String8 message; message.appendFormat("Failed to consume batched input event. status=%d", status); jniThrowRuntimeException(env, message.string()); diff --git a/core/jni/android_view_KeyCharacterMap.cpp b/core/jni/android_view_KeyCharacterMap.cpp index 7245d9d..3e56a89 100644 --- a/core/jni/android_view_KeyCharacterMap.cpp +++ b/core/jni/android_view_KeyCharacterMap.cpp @@ -14,19 +14,27 @@ * limitations under the License. */ +#include <android_runtime/AndroidRuntime.h> + #include <androidfw/KeyCharacterMap.h> #include <androidfw/Input.h> +#include <binder/Parcel.h> -#include <android_runtime/AndroidRuntime.h> #include <nativehelper/jni.h> #include <nativehelper/JNIHelp.h> +#include "android_os_Parcel.h" #include "android_view_KeyEvent.h" namespace android { static struct { jclass clazz; + jmethodID ctor; +} gKeyCharacterMapClassInfo; + +static struct { + jclass clazz; } gKeyEventClassInfo; static struct { @@ -35,44 +43,87 @@ static struct { } gFallbackActionClassInfo; -static jint nativeLoad(JNIEnv *env, jobject clazz, jstring fileStr) { - const char* file = env->GetStringUTFChars(fileStr, NULL); - - KeyCharacterMap* map; - status_t status = KeyCharacterMap::load(String8(file), &map); - jint result; - if (status) { - String8 msg; - msg.appendFormat("Could not load key character map '%s' due to error %d. " - "Refer to the log for details.", file, status); - jniThrowException(env, "android/view/KeyCharacterMap$KeyCharacterMapUnavailableException", - msg.string()); - result = 0; - } else { - result = reinterpret_cast<jint>(map); +class NativeKeyCharacterMap { +public: + NativeKeyCharacterMap(int32_t deviceId, const sp<KeyCharacterMap>& map) : + mDeviceId(deviceId), mMap(map) { } - env->ReleaseStringUTFChars(fileStr, file); - return result; + ~NativeKeyCharacterMap() { + } + + inline int32_t getDeviceId() const { + return mDeviceId; + } + + inline const sp<KeyCharacterMap>& getMap() const { + return mMap; + } + +private: + int32_t mDeviceId; + sp<KeyCharacterMap> mMap; +}; + + +jobject android_view_KeyCharacterMap_create(JNIEnv* env, int32_t deviceId, + const sp<KeyCharacterMap>& kcm) { + NativeKeyCharacterMap* map = new NativeKeyCharacterMap(deviceId, + kcm.get() ? kcm : KeyCharacterMap::empty()); + if (!map) { + return NULL; + } + + return env->NewObject(gKeyCharacterMapClassInfo.clazz, gKeyCharacterMapClassInfo.ctor, + reinterpret_cast<jint>(map)); +} + +static jint nativeReadFromParcel(JNIEnv *env, jobject clazz, jobject parcelObj) { + Parcel* parcel = parcelForJavaObject(env, parcelObj); + if (!parcel) { + return 0; + } + + int32_t deviceId = parcel->readInt32(); + if (parcel->errorCheck()) { + return 0; + } + + sp<KeyCharacterMap> kcm = KeyCharacterMap::readFromParcel(parcel); + if (!kcm.get()) { + return 0; + } + + NativeKeyCharacterMap* map = new NativeKeyCharacterMap(deviceId, kcm); + return reinterpret_cast<jint>(map); +} + +static void nativeWriteToParcel(JNIEnv* env, jobject clazz, jint ptr, jobject parcelObj) { + NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr); + Parcel* parcel = parcelForJavaObject(env, parcelObj); + if (parcel) { + parcel->writeInt32(map->getDeviceId()); + map->getMap()->writeToParcel(parcel); + } } static void nativeDispose(JNIEnv *env, jobject clazz, jint ptr) { - KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr); + NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr); delete map; } static jchar nativeGetCharacter(JNIEnv *env, jobject clazz, jint ptr, jint keyCode, jint metaState) { - KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr); - return map->getCharacter(keyCode, metaState); + NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr); + return map->getMap()->getCharacter(keyCode, metaState); } static jboolean nativeGetFallbackAction(JNIEnv *env, jobject clazz, jint ptr, jint keyCode, jint metaState, jobject fallbackActionObj) { - KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr); + NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr); KeyCharacterMap::FallbackAction fallbackAction; - bool result = map->getFallbackAction(keyCode, metaState, &fallbackAction); + bool result = map->getMap()->getFallbackAction(keyCode, metaState, &fallbackAction); if (result) { env->SetIntField(fallbackActionObj, gFallbackActionClassInfo.keyCode, fallbackAction.keyCode); @@ -83,13 +134,13 @@ static jboolean nativeGetFallbackAction(JNIEnv *env, jobject clazz, jint ptr, ji } static jchar nativeGetNumber(JNIEnv *env, jobject clazz, jint ptr, jint keyCode) { - KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr); - return map->getNumber(keyCode); + NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr); + return map->getMap()->getNumber(keyCode); } static jchar nativeGetMatch(JNIEnv *env, jobject clazz, jint ptr, jint keyCode, jcharArray charsArray, jint metaState) { - KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr); + NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr); jsize numChars = env->GetArrayLength(charsArray); jchar* chars = static_cast<jchar*>(env->GetPrimitiveArrayCritical(charsArray, NULL)); @@ -97,25 +148,25 @@ static jchar nativeGetMatch(JNIEnv *env, jobject clazz, jint ptr, jint keyCode, return 0; } - char16_t result = map->getMatch(keyCode, chars, size_t(numChars), metaState); + char16_t result = map->getMap()->getMatch(keyCode, chars, size_t(numChars), metaState); env->ReleasePrimitiveArrayCritical(charsArray, chars, JNI_ABORT); return result; } static jchar nativeGetDisplayLabel(JNIEnv *env, jobject clazz, jint ptr, jint keyCode) { - KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr); - return map->getDisplayLabel(keyCode); + NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr); + return map->getMap()->getDisplayLabel(keyCode); } static jint nativeGetKeyboardType(JNIEnv *env, jobject clazz, jint ptr) { - KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr); - return map->getKeyboardType(); + NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr); + return map->getMap()->getKeyboardType(); } -static jobjectArray nativeGetEvents(JNIEnv *env, jobject clazz, jint ptr, jint deviceId, +static jobjectArray nativeGetEvents(JNIEnv *env, jobject clazz, jint ptr, jcharArray charsArray) { - KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr); + NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr); jchar* chars = env->GetCharArrayElements(charsArray, NULL); if (!chars) { @@ -125,7 +176,7 @@ static jobjectArray nativeGetEvents(JNIEnv *env, jobject clazz, jint ptr, jint d Vector<KeyEvent> events; jobjectArray result = NULL; - if (map->getEvents(deviceId, chars, size_t(numChars), events)) { + if (map->getMap()->getEvents(map->getDeviceId(), chars, size_t(numChars), events)) { result = env->NewObjectArray(jsize(events.size()), gKeyEventClassInfo.clazz, NULL); if (result) { for (size_t i = 0; i < events.size(); i++) { @@ -148,8 +199,10 @@ static jobjectArray nativeGetEvents(JNIEnv *env, jobject clazz, jint ptr, jint d static JNINativeMethod g_methods[] = { /* name, signature, funcPtr */ - { "nativeLoad", "(Ljava/lang/String;)I", - (void*)nativeLoad }, + { "nativeReadFromParcel", "(Landroid/os/Parcel;)I", + (void*)nativeReadFromParcel }, + { "nativeWriteToParcel", "(ILandroid/os/Parcel;)V", + (void*)nativeWriteToParcel }, { "nativeDispose", "(I)V", (void*)nativeDispose }, { "nativeGetCharacter", "(III)C", @@ -164,7 +217,7 @@ static JNINativeMethod g_methods[] = { (void*)nativeGetDisplayLabel }, { "nativeGetKeyboardType", "(I)I", (void*)nativeGetKeyboardType }, - { "nativeGetEvents", "(II[C)[Landroid/view/KeyEvent;", + { "nativeGetEvents", "(I[C)[Landroid/view/KeyEvent;", (void*)nativeGetEvents }, }; @@ -172,12 +225,22 @@ static JNINativeMethod g_methods[] = { var = env->FindClass(className); \ LOG_FATAL_IF(! var, "Unable to find class " className); +#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ + var = env->GetMethodID(clazz, methodName, methodDescriptor); \ + LOG_FATAL_IF(! var, "Unable to find method " methodName); + #define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ LOG_FATAL_IF(! var, "Unable to find field " fieldName); -int register_android_text_KeyCharacterMap(JNIEnv* env) +int register_android_view_KeyCharacterMap(JNIEnv* env) { + FIND_CLASS(gKeyCharacterMapClassInfo.clazz, "android/view/KeyCharacterMap"); + gKeyCharacterMapClassInfo.clazz = jclass(env->NewGlobalRef(gKeyCharacterMapClassInfo.clazz)); + + GET_METHOD_ID(gKeyCharacterMapClassInfo.ctor, gKeyCharacterMapClassInfo.clazz, + "<init>", "(I)V"); + FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent"); gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz)); diff --git a/core/jni/android_view_KeyCharacterMap.h b/core/jni/android_view_KeyCharacterMap.h new file mode 100644 index 0000000..04024f6 --- /dev/null +++ b/core/jni/android_view_KeyCharacterMap.h @@ -0,0 +1,32 @@ +/* + * 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. + */ + +#ifndef _ANDROID_VIEW_KEY_CHARACTER_MAP_H +#define _ANDROID_VIEW_KEY_CHARACTER_MAP_H + +#include "jni.h" + +#include <androidfw/KeyCharacterMap.h> + +namespace android { + +/* Creates a KeyCharacterMap object from the given information. */ +extern jobject android_view_KeyCharacterMap_create(JNIEnv* env, int32_t deviceId, + const sp<KeyCharacterMap>& map); + +} // namespace android + +#endif // _ANDROID_VIEW_KEY_CHARACTER_MAP_H diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 3ee2377..f5c0f8f 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1256,6 +1256,13 @@ android:description="@string/permdesc_setPointerSpeed" android:protectionLevel="signature" /> + <!-- Allows low-level access to setting the keyboard layout. + Not for use by normal applications. --> + <permission android:name="android.permission.SET_KEYBOARD_LAYOUT" + android:label="@string/permlab_setKeyboardLayout" + android:description="@string/permdesc_setKeyboardLayout" + android:protectionLevel="signature" /> + <!-- Allows an application to install packages. --> <permission android:name="android.permission.INSTALL_PACKAGES" android:label="@string/permlab_installPackages" diff --git a/core/res/res/layout/input_method_switch_dialog_title.xml b/core/res/res/layout/input_method_switch_dialog_title.xml new file mode 100644 index 0000000..7032bd3 --- /dev/null +++ b/core/res/res/layout/input_method_switch_dialog_title.xml @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2012, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" > + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="9dip" + android:layout_marginLeft="20dip" + android:layout_marginRight="10dip" + android:layout_marginTop="6dip" + android:gravity="center_vertical" + android:orientation="vertical" > + + <com.android.internal.widget.DialogTitle + android:id="@+id/alertTitle" + style="@android:style/DialogWindowTitle.Holo" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:ellipsize="end" + android:singleLine="true" + android:text="@string/select_input_method" /> + </LinearLayout> + + <!-- Hard keyboard switch --> + + <LinearLayout + android:id="@+id/hard_keyboard_section" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" > + + <View + android:layout_width="match_parent" + android:layout_height="2dip" + android:background="@android:color/holo_blue_light" /> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" > + + <LinearLayout + android:layout_width="0dip" + android:layout_height="wrap_content" + android:layout_weight="1" + android:background="?android:attr/selectableItemBackground" + android:ellipsize="marquee" + android:gravity="center_vertical" + android:minHeight="?android:attr/listPreferredItemHeightSmall" + android:orientation="vertical" + android:paddingBottom="5dip" + android:paddingLeft="16dip" + android:paddingRight="0dip" + android:paddingTop="5dip" > + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:singleLine="true" + android:text="@string/hardware" + android:textAppearance="?android:attr/textAppearanceMedium" + android:textColor="?android:attr/textColorAlertDialogListItem" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:singleLine="true" + android:text="@string/use_physical_keyboard" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="?android:attr/textColorAlertDialogListItem" /> + </LinearLayout> + + <Switch + android:id="@+id/hard_keyboard_switch" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_marginRight="12dip" /> + </LinearLayout> + </LinearLayout> + + <View + android:id="@+id/titleDivider" + android:layout_width="match_parent" + android:layout_height="2dip" + android:background="@android:drawable/divider_horizontal_dark" /> + +</LinearLayout>
\ No newline at end of file diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index f23c7e2..9528a7a 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Laat die program toe om die skerm se rotasie te eniger tyd te verander. Dit moet nooit vir normale programme nodig wees nie."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"verander wyserspoed"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Laat die program toe om die muis of stuurpaneel se wyserspoed te eniger tyd te verander. Dit moet nooit vir normale programme nodig wees nie."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"stuur Linux-seine na programme"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Laat die program toe om te versoek dat die voorsiende sein na alle aanhoudende prosesse gestuur word."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"laat program altyd loop"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Raak om USB-ontfouting te deaktiveer."</string> <string name="select_input_method" msgid="4653387336791222978">"Kies invoermetode"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Stel invoermetodes op"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidate"</u></string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index b0218dd..747b12d 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"በማንኛውም ጊዜ የማሳያውን መሽከርከር ለመለወጥ ለመተግበሪያው ይፈቅዳሉ፡፡ ለተለመዱ መተግበሪያዎች አያስፈልግም፡፡"</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"የጠቋሚ ፍጥነት ለውጥ"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"መዳፊት ወይም ዱካ መከተያ ጠቋሚ ፍጥነትን በማንኛውም ጊዜ ለመለወጥ ለመተግበሪያው ይፈቅዳሉ፡፡ ለመደበኛ መተግበሪያዎች መቼም ቢሆን አያስፈልግም፡፡"</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"ወደ መተግበሪያዎችን የLinux ምልክቶች ላክ"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"ለሁሉም ተከታታይ ሂደቶች ልከው የሚያቀርቧቸው ሲግናሎችን ለመጠየቅ ለመተግበሪያው ይፈቅዳሉ።"</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"ትግበራ ሁልጊዜ አሂድ ላይ አድርግ"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ማረሚያ ላለማንቃት ዳስስ።"</string> <string name="select_input_method" msgid="4653387336791222978">"የግቤት ስልት ምረጥ"</string> <string name="configure_input_methods" msgid="9091652157722495116">"የግቤት ስልቶችን አዘጋጅ"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"ዕጩዎች"</u></string> @@ -1172,7 +1180,7 @@ <string name="number_picker_increment_button" msgid="2412072272832284313">"ጨምር"</string> <string name="number_picker_decrement_button" msgid="476050778386779067">"ቀንስ"</string> <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> ንካ እና ያዝ።"</string> - <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"ለመጨመር ወደ ላይ አንሸራትት እና ለመቀነስ ወደ ታች አንሸራትት።"</string> + <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"ለመጨመር ወደ ላይ እና ለመቀነስ ወደ ታች አንሸራትት።"</string> <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"ደቂቃ ጨምር"</string> <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"ደቂቃ ቀንስ"</string> <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"ሰዓት ጨምር"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 9c3d658..e95ea69 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"للسماح للتطبيق بتغيير تدوير الشاشة في أي وقت. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"تغيير سرعة المؤشر"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"للسماح للتطبيق بتغيير سرعة مؤشر الماوس أو لوحة التتبع في أي وقت. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"إرسال إشارات Linux للتطبيقات"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"للسماح للتطبيق بطلب إرسال الإشارة المزوّدة لجميع العمليات المستمرة."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"تشغيل التطبيق دائمًا"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"المس لتعطيل تصحيح أخطاء USB."</string> <string name="select_input_method" msgid="4653387336791222978">"اختيار أسلوب الإدخال"</string> <string name="configure_input_methods" msgid="9091652157722495116">"إعداد أسلوب الإدخال"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789 أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"العناصر المرشحة"</u></string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 9aab752..c78ecd9 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Дазваляе прыкладанням змяняць паварот экрана ў любы час. Не патрабуецца для звычайных прыкладанняў."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"змена хутк. перамяшч. ўказ."</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Дазваляе прыкладанням змяняць хуткасць курсору мышы або трэкпада ў любы час. Не патрабуецца для звычайных прыкладанняў."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"адправіць сігналы Linux да прыкладанняў"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Дазваляе прыкладанням запытваць адпраўку падаваемага сігнала для ўсiх пастаянных працэсаў."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"прымусіць прыкладанне працаваць заўсёды"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Націсніце, каб адключыць адладку USB."</string> <string name="select_input_method" msgid="4653387336791222978">"Выберыце метад уводу"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Наладзіць метады ўводу"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" АБВГДЕЁЖЗІЙКЛМНОПРСТУЎФХЦЧШ\'ЫЬЭЮЯ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"кандыдат."</u></string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 81a75bd..8bcbec3 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Разрешава на приложението да променя ориентацията на екрана по всяко време. Нормалните приложения би трябвало никога да не се нуждаят от това."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"промяна на скоростта на курсор"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Разрешава на приложението да променя скоростта на курсора на мишката или на тракпада по всяко време. Нормалните приложения би трябвало никога да не се нуждаят от това."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"изпращане на сигнали от Linux до приложенията"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Разрешава на приложението да подаде заявка предоставеният сигнал да се изпрати до всички постоянни процеси."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"задаване на постоянно изпълнение на приложението"</string> @@ -1019,8 +1023,7 @@ <string name="time_picker_dialog_title" msgid="8349362623068819295">"Задаване на часа"</string> <string name="date_picker_dialog_title" msgid="5879450659453782278">"Задаване на дата"</string> <string name="date_time_set" msgid="5777075614321087758">"Задаване"</string> - <!-- no translation found for date_time_done (2507683751759308828) --> - <skip /> + <string name="date_time_done" msgid="2507683751759308828">"Готово"</string> <string name="default_permission_group" msgid="2690160991405646128">"По подразбиране"</string> <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"НОВО: "</font></string> <string name="no_permissions" msgid="7283357728219338112">"Не се изискват разрешения"</string> @@ -1060,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Докоснете, за да деактивирате отстраняването на грешки през USB."</string> <string name="select_input_method" msgid="4653387336791222978">"Избор на метод на въвеждане"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Методи на въвеждане: Настройка"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string> @@ -1170,35 +1177,22 @@ <string name="add_account_label" msgid="2935267344849993553">"Добавяне на профил"</string> <string name="choose_account_text" msgid="6303348737197849675">"Кой профил искате да използвате?"</string> <string name="add_account_button_label" msgid="3611982894853435874">"Добавяне на профил"</string> - <!-- no translation found for number_picker_increment_button (2412072272832284313) --> - <skip /> - <!-- no translation found for number_picker_decrement_button (476050778386779067) --> - <skip /> + <string name="number_picker_increment_button" msgid="2412072272832284313">"Увеличаване"</string> + <string name="number_picker_decrement_button" msgid="476050778386779067">"Намаляване"</string> <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Докоснете <xliff:g id="VALUE">%s</xliff:g> път/и и задръжте."</string> - <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) --> - <skip /> - <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) --> - <skip /> - <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) --> - <skip /> - <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) --> - <skip /> - <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) --> - <skip /> + <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Плъзнете нагоре за увеличаване и надолу за намаляване."</string> + <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Увеличаване на минутите"</string> + <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Намаляване на минутите"</string> + <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Увеличаване на часовете"</string> + <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Намаляване на часовете"</string> <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Задаване на PM"</string> <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Задаване на AM"</string> - <!-- no translation found for date_picker_increment_month_button (5369998479067934110) --> - <skip /> - <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) --> - <skip /> - <!-- no translation found for date_picker_increment_day_button (7130465412308173903) --> - <skip /> - <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) --> - <skip /> - <!-- no translation found for date_picker_increment_year_button (6318697384310808899) --> - <skip /> - <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) --> - <skip /> + <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Увеличаване на месеците"</string> + <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Намаляване на месеците"</string> + <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Увеличаване на дните"</string> + <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Намаляване на дните"</string> + <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Увеличаване на годините"</string> + <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Намаляване на годините"</string> <string name="checkbox_checked" msgid="7222044992652711167">"отметнато"</string> <string name="checkbox_not_checked" msgid="5174639551134444056">"не е отметнато"</string> <string name="radiobutton_selected" msgid="8603599808486581511">"избрано"</string> @@ -1218,20 +1212,15 @@ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Споделяне със"</string> <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Споделяне със: <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> <string name="content_description_sliding_handle" msgid="415975056159262248">"Плъзгаща се дръжка. Докоснете и задръжте."</string> - <!-- no translation found for description_direction_up (7169032478259485180) --> - <skip /> - <!-- no translation found for description_direction_down (5087739728639014595) --> - <skip /> - <!-- no translation found for description_direction_left (7207478719805562165) --> - <skip /> - <!-- no translation found for description_direction_right (8034433242579600980) --> - <skip /> + <string name="description_direction_up" msgid="7169032478259485180">"Плъзнете нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_down" msgid="5087739728639014595">"Плъзнете надолу за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_left" msgid="7207478719805562165">"Плъзнете наляво за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_right" msgid="8034433242579600980">"Плъзнете надясно за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="description_target_unlock" msgid="2228524900439801453">"Отключване"</string> <string name="description_target_camera" msgid="969071997552486814">"Камера"</string> <string name="description_target_silent" msgid="893551287746522182">"Тих режим"</string> <string name="description_target_soundon" msgid="30052466675500172">"Включване на звука"</string> - <!-- no translation found for description_target_search (3091587249776033139) --> - <skip /> + <string name="description_target_search" msgid="3091587249776033139">"Търсене"</string> <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Прокарайте пръст, за да отключите."</string> <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Включете слушалки, за да чуете изговарянето на клавишите за паролата."</string> <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Точка."</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 6c6030c..fdae718 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Permet que l\'aplicació canviï el gir de la pantalla en qualsevol moment. No s\'hauria de necessitar mai per a les aplicacions normals."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"canvi de velocitat del punter"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Permet que l\'aplicació canviï la velocitat del punter del ratolí o del ratolí tàctil en qualsevol moment. No s\'hauria de necessitar mai per a les aplicacions normals."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"envia senyals Linux a les aplicacions"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Permet que l\'aplicació sol·liciti que el senyal subministrat s\'enviï a tots els processos persistents."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"fes que l\'aplicació s\'executi sempre"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca-ho per desactivar la depuració USB."</string> <string name="select_input_method" msgid="4653387336791222978">"Selecció de mètodes d\'introducció"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Configura els mètodes d\'entrada"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index d95feaa..98b5771 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Umožňuje aplikaci kdykoli změnit otočení obrazovky. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"změna rychlosti kurzoru"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Umožňuje aplikaci kdykoli změnit rychlost ukazatele myši nebo touchpadu. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"odeslání signálů systému Linux aplikacím"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Umožňuje aplikaci vyžádat zaslání poskytnutého signálu všem trvalým procesům."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"trvalé spuštění aplikace"</string> @@ -1019,8 +1023,7 @@ <string name="time_picker_dialog_title" msgid="8349362623068819295">"Nastavení času"</string> <string name="date_picker_dialog_title" msgid="5879450659453782278">"Nastavení data"</string> <string name="date_time_set" msgid="5777075614321087758">"Nastavit"</string> - <!-- no translation found for date_time_done (2507683751759308828) --> - <skip /> + <string name="date_time_done" msgid="2507683751759308828">"Hotovo"</string> <string name="default_permission_group" msgid="2690160991405646128">"Výchozí"</string> <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVÉ: "</font></string> <string name="no_permissions" msgid="7283357728219338112">"Nejsou vyžadována žádná oprávnění"</string> @@ -1060,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Dotykem zakážete ladění USB."</string> <string name="select_input_method" msgid="4653387336791222978">"Vybrat metodu vstupu"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Nastavit metody vstupu"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidáti"</u></string> @@ -1170,35 +1177,22 @@ <string name="add_account_label" msgid="2935267344849993553">"Přidat účet"</string> <string name="choose_account_text" msgid="6303348737197849675">"Který účet chcete použít?"</string> <string name="add_account_button_label" msgid="3611982894853435874">"Přidat účet"</string> - <!-- no translation found for number_picker_increment_button (2412072272832284313) --> - <skip /> - <!-- no translation found for number_picker_decrement_button (476050778386779067) --> - <skip /> + <string name="number_picker_increment_button" msgid="2412072272832284313">"Zvýšit"</string> + <string name="number_picker_decrement_button" msgid="476050778386779067">"Snížit"</string> <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> dotkněte se a podržte."</string> - <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) --> - <skip /> - <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) --> - <skip /> - <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) --> - <skip /> - <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) --> - <skip /> - <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) --> - <skip /> + <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Chcete-li hodnotu zvýšit, přijeďte prstem nahoru, chcete-li hodnotu snížit, přejeďte prstem dolů."</string> + <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Přidat minutu"</string> + <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Ubrat minutu"</string> + <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Přidat hodinu"</string> + <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Ubrat hodinu"</string> <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Nastavit odp."</string> <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Nastavit dop."</string> - <!-- no translation found for date_picker_increment_month_button (5369998479067934110) --> - <skip /> - <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) --> - <skip /> - <!-- no translation found for date_picker_increment_day_button (7130465412308173903) --> - <skip /> - <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) --> - <skip /> - <!-- no translation found for date_picker_increment_year_button (6318697384310808899) --> - <skip /> - <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) --> - <skip /> + <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Přidat měsíc"</string> + <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Ubrat měsíc"</string> + <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Přidat den"</string> + <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Ubrat den"</string> + <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Přidat rok"</string> + <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Ubrat rok"</string> <string name="checkbox_checked" msgid="7222044992652711167">"zaškrtnuto"</string> <string name="checkbox_not_checked" msgid="5174639551134444056">"nezaškrtnuto"</string> <string name="radiobutton_selected" msgid="8603599808486581511">"Vybráno"</string> @@ -1218,20 +1212,15 @@ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Sdílet s"</string> <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Sdílet s aplikací <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> <string name="content_description_sliding_handle" msgid="415975056159262248">"Posuvník. Dotkněte se a podržte."</string> - <!-- no translation found for description_direction_up (7169032478259485180) --> - <skip /> - <!-- no translation found for description_direction_down (5087739728639014595) --> - <skip /> - <!-- no translation found for description_direction_left (7207478719805562165) --> - <skip /> - <!-- no translation found for description_direction_right (8034433242579600980) --> - <skip /> + <string name="description_direction_up" msgid="7169032478259485180">"Přejeďte prstem nahoru: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string> + <string name="description_direction_down" msgid="5087739728639014595">"Přejeďte prstem dolů: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string> + <string name="description_direction_left" msgid="7207478719805562165">"Přejeďte prstem doleva: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string> + <string name="description_direction_right" msgid="8034433242579600980">"Přejeďte prstem doprava: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string> <string name="description_target_unlock" msgid="2228524900439801453">"Odemknout"</string> <string name="description_target_camera" msgid="969071997552486814">"Fotoaparát"</string> <string name="description_target_silent" msgid="893551287746522182">"Tichý"</string> <string name="description_target_soundon" msgid="30052466675500172">"Zapnout zvuk"</string> - <!-- no translation found for description_target_search (3091587249776033139) --> - <skip /> + <string name="description_target_search" msgid="3091587249776033139">"Vyhledávání"</string> <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Odemknete posunutím prstu."</string> <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Chcete-li slyšet, které klávesy jste při zadávání hesla stiskli, připojte sluchátka."</string> <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Tečka."</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 2c7f130..a3c7474 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Tillader, at appen kan ændre skærmretningen på et hvilket som helst tidspunkt. Bør aldrig være nødvendigt for almindelige apps."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"ændre markørens hastighed"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Tillader, at appen til enhver tid kan ændre musemarkørens hastighed. Bør aldrig være nødvendigt for normale apps."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"sende Linux-signaler til apps"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Tillader, at appen kan anmode om, at det leverede signal sendes til alle vedholdende processer."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"sørge for, at appen altid kører"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Tryk for at deaktivere USB-fejlretning."</string> <string name="select_input_method" msgid="4653387336791222978">"Vælg inputmetode"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Konfigurer inputmetoder"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidater"</u></string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index aa44b87..ae88920 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Ermöglicht der App, die Bildschirmdrehung jederzeit zu ändern. Sollte nie für normale Apps benötigt werden."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"Zeigergeschwindigkeit ändern"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Ermöglicht der App, jederzeit die Geschwindigkeit des Maus- bzw. Touchpad-Zeigers zu ändern. Sollte nie für normale Apps benötigt werden."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"Linux-Signale an Apps senden"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Ermöglicht der App, das Senden des gelieferten Signals an alle andauernden Prozesse zu fordern"</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"App permanent ausführen"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Zum Deaktivieren von USB-Debugging tippen"</string> <string name="select_input_method" msgid="4653387336791222978">"Eingabemethode wählen"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Eingabemethoden einrichten"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"Kandidaten"</u></string> @@ -1169,10 +1177,10 @@ <string name="add_account_label" msgid="2935267344849993553">"Konto hinzufügen"</string> <string name="choose_account_text" msgid="6303348737197849675">"Welches Konto möchten Sie verwenden?"</string> <string name="add_account_button_label" msgid="3611982894853435874">"Konto hinzufügen"</string> - <string name="number_picker_increment_button" msgid="2412072272832284313">"Erhöhen"</string> + <string name="number_picker_increment_button" msgid="2412072272832284313">"Verlängern"</string> <string name="number_picker_decrement_button" msgid="476050778386779067">"Verringern"</string> <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> berühren und gedrückt halten"</string> - <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Zum Erhöhen nach oben und zum Verringern nach unten schieben"</string> + <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Zum Verlängern nach oben und zum Verringern nach unten schieben"</string> <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Minuten verlängern"</string> <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Minuten verringern"</string> <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Stunden verlängern"</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index d85d639..ce49a84 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Επιτρέπει στην εφαρμογή την αλλαγή της περιστροφής της οθόνης ανά πάσα στιγμή. Δεν απαιτείται για συνήθεις εφαρμογές."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"αλλαγή ταχύτητας δείκτη"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Επιτρέπει στην εφαρμογή την αλλαγή της ταχύτητας του δείκτη του ποντικιού ή της επιφάνειας αφής ανά πάσα στιγμή. Δεν πρέπει να χρησιμοποιείται από συνήθεις εφαρμογές."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"αποστολή σημάτων Linux σε εφαρμογές"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Επιτρέπει στην εφαρμογή την αποστολή αιτήματος για την αποστολή του παρεχόμενου σήματος σε όλες τις υπάρχουσες διαδικασίες."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"να εκτελείται συνεχώς η εφαρμογή"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Αγγίξτε για απενεργοποίηση του εντοπισμού σφαλμάτων USB."</string> <string name="select_input_method" msgid="4653387336791222978">"Επιλογή μεθόδου εισόδου"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Ρύθμιση μεθόδων εισαγωγής"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"υποψήφιοι"</u></string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index fa767ff..38b69fe 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Allows the app to change the rotation of the screen at any time. Should never be needed for normal apps."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"change pointer speed"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Allows the app to change the mouse or touch pad pointer speed at any time. Should never be needed for normal apps."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"send Linux signals to apps"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Allows the app to request that the supplied signal be sent to all persistent processes."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"make app always run"</string> @@ -1019,8 +1023,7 @@ <string name="time_picker_dialog_title" msgid="8349362623068819295">"Set time"</string> <string name="date_picker_dialog_title" msgid="5879450659453782278">"Set date"</string> <string name="date_time_set" msgid="5777075614321087758">"Set"</string> - <!-- no translation found for date_time_done (2507683751759308828) --> - <skip /> + <string name="date_time_done" msgid="2507683751759308828">"Done"</string> <string name="default_permission_group" msgid="2690160991405646128">"Default"</string> <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NEW: "</font></string> <string name="no_permissions" msgid="7283357728219338112">"No permission required"</string> @@ -1060,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Touch to disable USB debugging."</string> <string name="select_input_method" msgid="4653387336791222978">"Choose input method"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Set up input methods"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidates"</u></string> @@ -1170,35 +1177,22 @@ <string name="add_account_label" msgid="2935267344849993553">"Add an account"</string> <string name="choose_account_text" msgid="6303348737197849675">"Which account do you want to use?"</string> <string name="add_account_button_label" msgid="3611982894853435874">"Add account"</string> - <!-- no translation found for number_picker_increment_button (2412072272832284313) --> - <skip /> - <!-- no translation found for number_picker_decrement_button (476050778386779067) --> - <skip /> + <string name="number_picker_increment_button" msgid="2412072272832284313">"Increase"</string> + <string name="number_picker_decrement_button" msgid="476050778386779067">"Decrease"</string> <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> touch and hold."</string> - <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) --> - <skip /> - <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) --> - <skip /> - <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) --> - <skip /> - <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) --> - <skip /> - <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) --> - <skip /> + <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Slide up to increase and down to decrease."</string> + <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Increase minute"</string> + <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Decrease minute"</string> + <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Increase hour"</string> + <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Decrease hour"</string> <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Set p.m."</string> <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Set a.m."</string> - <!-- no translation found for date_picker_increment_month_button (5369998479067934110) --> - <skip /> - <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) --> - <skip /> - <!-- no translation found for date_picker_increment_day_button (7130465412308173903) --> - <skip /> - <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) --> - <skip /> - <!-- no translation found for date_picker_increment_year_button (6318697384310808899) --> - <skip /> - <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) --> - <skip /> + <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Increase month"</string> + <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Decrease month"</string> + <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Increase day"</string> + <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Decrease day"</string> + <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Increase year"</string> + <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Decrease year"</string> <string name="checkbox_checked" msgid="7222044992652711167">"ticked"</string> <string name="checkbox_not_checked" msgid="5174639551134444056">"not ticked"</string> <string name="radiobutton_selected" msgid="8603599808486581511">"selected"</string> @@ -1218,20 +1212,15 @@ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Share with"</string> <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Share with <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> <string name="content_description_sliding_handle" msgid="415975056159262248">"Sliding handle. Touch & hold."</string> - <!-- no translation found for description_direction_up (7169032478259485180) --> - <skip /> - <!-- no translation found for description_direction_down (5087739728639014595) --> - <skip /> - <!-- no translation found for description_direction_left (7207478719805562165) --> - <skip /> - <!-- no translation found for description_direction_right (8034433242579600980) --> - <skip /> + <string name="description_direction_up" msgid="7169032478259485180">"Slide up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_down" msgid="5087739728639014595">"Slide down for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_left" msgid="7207478719805562165">"Slide left for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_right" msgid="8034433242579600980">"Slide right for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="description_target_unlock" msgid="2228524900439801453">"Unlock"</string> <string name="description_target_camera" msgid="969071997552486814">"Camera"</string> <string name="description_target_silent" msgid="893551287746522182">"Silent"</string> <string name="description_target_soundon" msgid="30052466675500172">"Sound on"</string> - <!-- no translation found for description_target_search (3091587249776033139) --> - <skip /> + <string name="description_target_search" msgid="3091587249776033139">"Search"</string> <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Swipe to unlock."</string> <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Plug in a headset to hear password keys spoken."</string> <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Dot"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 5c7b782..d400734 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Permite que la aplicación cambie la rotación de la pantalla en cualquier momento. Las aplicaciones normales no deberían necesitar este permiso."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"cambiar velocidad del puntero"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Permite que la aplicación cambie la velocidad del puntero del mouse o el trackpad en cualquier momento. Las aplicaciones normales no deben utilizar este permiso."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"enviar señales de Linux a las aplicaciones"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Permite que la aplicación solicite que la señal suministrada se envíe a todos los procesos persistentes."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"hacer que la aplicación se ejecute siempre"</string> @@ -1019,8 +1023,7 @@ <string name="time_picker_dialog_title" msgid="8349362623068819295">"Configurar hora"</string> <string name="date_picker_dialog_title" msgid="5879450659453782278">"Configurar fecha"</string> <string name="date_time_set" msgid="5777075614321087758">"Establecer"</string> - <!-- no translation found for date_time_done (2507683751759308828) --> - <skip /> + <string name="date_time_done" msgid="2507683751759308828">"Listo"</string> <string name="default_permission_group" msgid="2690160991405646128">"Predeterminado"</string> <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NUEVO: "</font></string> <string name="no_permissions" msgid="7283357728219338112">"No se requieren permisos"</string> @@ -1060,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca para desactivar la depuración de USB."</string> <string name="select_input_method" msgid="4653387336791222978">"Selecciona el método de introducción"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Configurar métodos de introducción"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string> @@ -1170,35 +1177,22 @@ <string name="add_account_label" msgid="2935267344849993553">"Agregar una cuenta"</string> <string name="choose_account_text" msgid="6303348737197849675">"¿Qué cuenta quieres usar?"</string> <string name="add_account_button_label" msgid="3611982894853435874">"Agregar una cuenta"</string> - <!-- no translation found for number_picker_increment_button (2412072272832284313) --> - <skip /> - <!-- no translation found for number_picker_decrement_button (476050778386779067) --> - <skip /> + <string name="number_picker_increment_button" msgid="2412072272832284313">"Aumentar"</string> + <string name="number_picker_decrement_button" msgid="476050778386779067">"Reducir"</string> <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Mantén presionado <xliff:g id="VALUE">%s</xliff:g>."</string> - <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) --> - <skip /> - <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) --> - <skip /> - <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) --> - <skip /> - <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) --> - <skip /> - <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) --> - <skip /> + <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Desliza el dedo hacia arriba para aumentar los valores y hacia abajo para reducirlos."</string> + <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Aumentar minutos"</string> + <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Reducir minutos"</string> + <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Aumentar hora"</string> + <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Reducir hora"</string> <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Establecer p.m."</string> <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Establecer a.m."</string> - <!-- no translation found for date_picker_increment_month_button (5369998479067934110) --> - <skip /> - <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) --> - <skip /> - <!-- no translation found for date_picker_increment_day_button (7130465412308173903) --> - <skip /> - <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) --> - <skip /> - <!-- no translation found for date_picker_increment_year_button (6318697384310808899) --> - <skip /> - <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) --> - <skip /> + <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Aumentar mes"</string> + <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Reducir mes"</string> + <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Aumentar día"</string> + <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Reducir día"</string> + <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Aumentar año"</string> + <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Reducir año"</string> <string name="checkbox_checked" msgid="7222044992652711167">"marcado"</string> <string name="checkbox_not_checked" msgid="5174639551134444056">"no marcado"</string> <string name="radiobutton_selected" msgid="8603599808486581511">"seleccionado"</string> @@ -1218,20 +1212,15 @@ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Compartir con"</string> <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Compartir con <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> <string name="content_description_sliding_handle" msgid="415975056159262248">"Mantén presionado el controlador deslizante."</string> - <!-- no translation found for description_direction_up (7169032478259485180) --> - <skip /> - <!-- no translation found for description_direction_down (5087739728639014595) --> - <skip /> - <!-- no translation found for description_direction_left (7207478719805562165) --> - <skip /> - <!-- no translation found for description_direction_right (8034433242579600980) --> - <skip /> + <string name="description_direction_up" msgid="7169032478259485180">"Desliza el dedo hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_down" msgid="5087739728639014595">"Desliza el dedo hacia abajo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_left" msgid="7207478719805562165">"Desliza el dedo hacia la izquierda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_right" msgid="8034433242579600980">"Desliza el dedo hacia la derecha para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="description_target_unlock" msgid="2228524900439801453">"Desbloquear"</string> <string name="description_target_camera" msgid="969071997552486814">"Cámara"</string> <string name="description_target_silent" msgid="893551287746522182">"Silencioso"</string> <string name="description_target_soundon" msgid="30052466675500172">"Sonido activado"</string> - <!-- no translation found for description_target_search (3091587249776033139) --> - <skip /> + <string name="description_target_search" msgid="3091587249776033139">"Buscar"</string> <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Desliza el dedo para desbloquear."</string> <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Conecta un auricular para escuchar las contraseñas."</string> <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punto"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 8ade0e0..6852184 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Permite que la aplicación cambie la rotación de la pantalla en cualquier momento. Las aplicaciones normales no deberían necesitar este permiso."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"cambiar velocidad del puntero"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Permite que la aplicación modifique la velocidad del puntero del ratón o del trackpad en cualquier momento. Las aplicaciones normales no deberían necesitar este permiso."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"enviar señales Linux a aplicaciones"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Permite que la aplicación solicite que la señal suministrada se envíe a todos los procesos persistentes."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"hacer que la aplicación se ejecute siempre"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Tocar para inhabilitar la depuración USB"</string> <string name="select_input_method" msgid="4653387336791222978">"Seleccionar método de introducción"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Ajustar métodos de introducción"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 0a8faed..737ab21 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Võimaldab rakendusel muuta ekraani pööramist mis tahes ajal. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"kursorikiiruse muutmine"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Võimaldab rakendusel muuta igal ajal hiire- või puutepadjakursori kiirust. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"Linuxi signaalide saatmine rakendustele"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Võimaldab rakendusel taotleda edastatud signaali saatmist kõigile püsiprotsessidele."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"Rakenduste pidev töös hoidmine"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Puudutage USB-silumise keelamiseks."</string> <string name="select_input_method" msgid="4653387336791222978">"Valige sisestusmeetod"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Seadista sisestusmeetodid"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidaadid"</u></string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index c9329bb..80b273b 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"به برنامه اجازه میدهد تا چرخش صفحه را هر وقت بخواهد تغییر دهد. برای برنامههای عادی نیاز نیست."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"تغییر سرعت اشاره گر"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"به برنامه اجازه میدهد تا سرعت ماوس و پد کنترل را هر وقت خواست تغییر دهد. برای برنامههای عادی نیاز نیست."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"ارسال سیگنالهای Linux به برنامهها"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"به برنامه اجازه میدهد تا درخواست کند سیگنال ارائه شده به همه مراحل دائم ارسال شود."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"همیشه برنامه اجرا شود"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"غیرفعال کردن اشکال زدایی USB را لمس کنید."</string> <string name="select_input_method" msgid="4653387336791222978">"انتخاب روش ورودی"</string> <string name="configure_input_methods" msgid="9091652157722495116">"تنظیم روشهای ورودی"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"داوطلبین"</u></string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 8a1079b..f011ec3 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Antaa sovelluksen muuttaa näytön kiertoa milloin tahansa. Ei tavallisten sovellusten käyttöön."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"muuta osoittimen nopeutta"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Antaa sovelluksen muuttaa hiiren tai kosketuslevyn osoittimen nopeutta milloin tahansa. Ei tavallisten sovellusten käyttöön."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"Linux-signaalien lähettäminen sovelluksille"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Antaa sovelluksen pyytää, että tarjottu signaali lähetetään kaikille käynnissä oleville prosesseille."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"sovelluksen asettaminen aina käynnissä olevaksi"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Poista USB-vianetsintä käytöstä koskettamalla tätä."</string> <string name="select_input_method" msgid="4653387336791222978">"Valitse syöttötapa"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Määritä syöttötavat"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidaatit"</u></string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index f05e564..7c78654 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Permet à l\'application de changer l\'orientation de l\'écran à tout moment. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"changer la vitesse du pointeur"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Permet à l\'application de modifier à tout moment la vitesse du pointeur de la souris ou du pavé tactile. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"envoyer des signaux Linux aux applications"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Permet à l\'application de demander que le signal fourni soit envoyé à tous les processus persistants."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"exécuter l\'application en continu"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Appuyez pour désactiver le débogage USB."</string> <string name="select_input_method" msgid="4653387336791222978">"Sélectionnez le mode de saisie"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Configurer les modes de saisie"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 9a742c4..1ee3d03 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"एप्लिकेशन को किसी भी समय स्क्रीन का रोटेशन बदलने देता है. सामान्य एप्लिकेशन के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"सूचक गति बदलें"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"एप्लिकेशन को माउस या ट्रैकपैड सूचक गति को किसी भी समय बदलने देता है. सामान्य एप्लिकेशन के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"एप्लिकेशन को Linux सिग्नल भेजें"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"एप्लिकेशन को यह अनुरोध करने देता है कि दिया गया सिग्नल सभी जारी प्रक्रियाओं को भेजा जाए."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"एप्लिकेशन को हमेशा चलने वाला बनाएं"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"USB डीबग करना अक्षम करने के लिए स्पर्श करें."</string> <string name="select_input_method" msgid="4653387336791222978">"इनपुट पद्धति चुनें"</string> <string name="configure_input_methods" msgid="9091652157722495116">"इनपुट पद्धतियां सेट करें"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"उम्मीदवार"</u></string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index ba0fb7a..0023310 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Omogućuje aplikaciji promjenu rotacije zaslona u bilo kojem trenutku. Ne bi smjelo biti potrebno za normalne aplikacije."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"promjena brzine pokazivača"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Omogućuje aplikaciji promjenu brzine miša ili dodirne pločice. Ne bi smjelo biti potrebno za normalne aplikacije."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"slanje Linux signala aplikacijama"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Aplikaciji omogućuje zahtijevanje da isporučeni signal bude poslan na sve trajne procese."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"trajni rad aplikacije"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Dodirnite da biste onemogućili rješavanje programske pogreške na USB-u."</string> <string name="select_input_method" msgid="4653387336791222978">"Odabir načina unosa"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Postavljanje načina unosa"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidati"</u></string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 25a8d2a..4ae52d5 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Lehetővé teszi az alkalmazás számára a képernyő elforgatásának bármikori módosítását. A normál alkalmazásoknak erre soha nincs szüksége."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"mutató sebességének módosítása"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Lehetővé teszi az alkalmazás számára, hogy bármikor módosítsa az egér vagy az érintőpad mutatójának sebességét. Normál alkalmazásoknak soha nem lehet rá szükségük."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"Linux-jelek küldése az alkalmazásoknak"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Lehetővé teszi az alkalmazás számára, hogy a megadott jelet elküldje az összes állandó folyamatnak."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"az alkalmazás állandó futtatása"</string> @@ -1019,8 +1023,7 @@ <string name="time_picker_dialog_title" msgid="8349362623068819295">"Idő beállítása"</string> <string name="date_picker_dialog_title" msgid="5879450659453782278">"Dátum beállítása"</string> <string name="date_time_set" msgid="5777075614321087758">"Beállítás"</string> - <!-- no translation found for date_time_done (2507683751759308828) --> - <skip /> + <string name="date_time_done" msgid="2507683751759308828">"Kész"</string> <string name="default_permission_group" msgid="2690160991405646128">"Alapértelmezett"</string> <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"ÚJ: "</font></string> <string name="no_permissions" msgid="7283357728219338112">"Nincs szükség engedélyre"</string> @@ -1060,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Érintse meg az USB hibakeresés kikapcsolásához."</string> <string name="select_input_method" msgid="4653387336791222978">"Beviteli mód kiválasztása"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Beviteli módok beállítása"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"jelöltek"</u></string> @@ -1170,35 +1177,22 @@ <string name="add_account_label" msgid="2935267344849993553">"Fiók hozzáadása"</string> <string name="choose_account_text" msgid="6303348737197849675">"Melyik fiókot szeretné használni?"</string> <string name="add_account_button_label" msgid="3611982894853435874">"Fiók hozzáadása"</string> - <!-- no translation found for number_picker_increment_button (2412072272832284313) --> - <skip /> - <!-- no translation found for number_picker_decrement_button (476050778386779067) --> - <skip /> + <string name="number_picker_increment_button" msgid="2412072272832284313">"Növelés"</string> + <string name="number_picker_decrement_button" msgid="476050778386779067">"Csökkentés"</string> <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> érintse meg és tartsa lenyomva."</string> - <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) --> - <skip /> - <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) --> - <skip /> - <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) --> - <skip /> - <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) --> - <skip /> - <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) --> - <skip /> + <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"A növeléshez csúsztassa felfelé, a csökkentéshez pedig lefelé."</string> + <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Perc értékének növelése"</string> + <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Perc értékének csökkentése"</string> + <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Óra értékének növelése"</string> + <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Óra értékének csökkentése"</string> <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Állítsa du. értékre"</string> <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Állítsa de. értékre"</string> - <!-- no translation found for date_picker_increment_month_button (5369998479067934110) --> - <skip /> - <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) --> - <skip /> - <!-- no translation found for date_picker_increment_day_button (7130465412308173903) --> - <skip /> - <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) --> - <skip /> - <!-- no translation found for date_picker_increment_year_button (6318697384310808899) --> - <skip /> - <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) --> - <skip /> + <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Hónap értékének növelése"</string> + <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Hónap értékének csökkentése"</string> + <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Dátum értékének növelése"</string> + <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Dátum értékének csökkentése"</string> + <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Év értékének növelése"</string> + <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Év értékének csökkentése"</string> <string name="checkbox_checked" msgid="7222044992652711167">"bejelölve"</string> <string name="checkbox_not_checked" msgid="5174639551134444056">"nincs bejelölve"</string> <string name="radiobutton_selected" msgid="8603599808486581511">"bejelölve"</string> @@ -1218,20 +1212,15 @@ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Megosztás a következővel:"</string> <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Ossza meg a következő alkalmazással: <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> <string name="content_description_sliding_handle" msgid="415975056159262248">"Csúsztatható fogantyú. Érintse meg és tartsa."</string> - <!-- no translation found for description_direction_up (7169032478259485180) --> - <skip /> - <!-- no translation found for description_direction_down (5087739728639014595) --> - <skip /> - <!-- no translation found for description_direction_left (7207478719805562165) --> - <skip /> - <!-- no translation found for description_direction_right (8034433242579600980) --> - <skip /> + <string name="description_direction_up" msgid="7169032478259485180">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa felfelé."</string> + <string name="description_direction_down" msgid="5087739728639014595">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa lefelé."</string> + <string name="description_direction_left" msgid="7207478719805562165">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa balra."</string> + <string name="description_direction_right" msgid="8034433242579600980">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa jobbra."</string> <string name="description_target_unlock" msgid="2228524900439801453">"Feloldás"</string> <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string> <string name="description_target_silent" msgid="893551287746522182">"Némítás"</string> <string name="description_target_soundon" msgid="30052466675500172">"Hang bekapcsolása"</string> - <!-- no translation found for description_target_search (3091587249776033139) --> - <skip /> + <string name="description_target_search" msgid="3091587249776033139">"Keresés"</string> <string name="description_target_unlock_tablet" msgid="3833195335629795055">"A feloldásához húzza végig az ujját."</string> <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Csatlakoztasson egy fülhallgatót, ha hallani szeretné a jelszó betűit felolvasva."</string> <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Pont."</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 944f429..bd6294b 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Mengizinkan apl mengubah rotasi layar kapan saja. Tidak pernah dibutuhkan oleh apl normal."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"ubah kecepatan penunjuk"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Mengizinkan apl mengubah kecepatan mouse atau pointer trackpad kapan saja. Tidak pernah diperlukan oleh apl normal."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"mengirim sinyal Linux ke apl"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Mengizinkan apl meminta agar sinyal yang disediakan dikirim ke semua proses yang ada."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"membuat apl selalu berjalan"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Sentuh untuk menonaktifkan debugging USB."</string> <string name="select_input_method" msgid="4653387336791222978">"Pilih metode masukan"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Menyiapkan metode masukan"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"calon"</u></string> @@ -1169,22 +1177,22 @@ <string name="add_account_label" msgid="2935267344849993553">"Tambahkan akun"</string> <string name="choose_account_text" msgid="6303348737197849675">"Akun mana yang ingin Anda gunakan?"</string> <string name="add_account_button_label" msgid="3611982894853435874">"Tambahkan akun"</string> - <string name="number_picker_increment_button" msgid="2412072272832284313">"Menambah"</string> - <string name="number_picker_decrement_button" msgid="476050778386779067">"Mengurangi"</string> + <string name="number_picker_increment_button" msgid="2412072272832284313">"Tambah"</string> + <string name="number_picker_decrement_button" msgid="476050778386779067">"Kurangi"</string> <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> sentuh dan tahan."</string> <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Geser ke atas untuk menambah dan ke bawah untuk mengurangi."</string> - <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Menambah menit"</string> - <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Mengurangi menit"</string> - <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Menambah jam"</string> - <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Mengurangi jam"</string> + <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Tambah menit"</string> + <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Kurangi menit"</string> + <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Tambah jam"</string> + <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Kurangi jam"</string> <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Menyetel PM"</string> <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Setel AM"</string> - <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Menambah bulan"</string> - <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Mengurangi bulan"</string> - <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Menambah hari"</string> - <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Mengurangi hari"</string> - <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Menambah tahun"</string> - <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Mengurangi tahun"</string> + <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Tambah bulan"</string> + <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Kurangi bulan"</string> + <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Tambah hari"</string> + <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Kurangi hari"</string> + <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Tambah tahun"</string> + <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Kurangi tahun"</string> <string name="checkbox_checked" msgid="7222044992652711167">"dicentang"</string> <string name="checkbox_not_checked" msgid="5174639551134444056">"tidak diperiksa"</string> <string name="radiobutton_selected" msgid="8603599808486581511">"dipilih"</string> @@ -1212,7 +1220,7 @@ <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string> <string name="description_target_silent" msgid="893551287746522182">"Senyap"</string> <string name="description_target_soundon" msgid="30052466675500172">"Suara hidup"</string> - <string name="description_target_search" msgid="3091587249776033139">"Penelusuran"</string> + <string name="description_target_search" msgid="3091587249776033139">"Telusuri"</string> <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Gesek untuk membuka kunci."</string> <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Pasang headset untuk mendengar tombol sandi yang diucapkan."</string> <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Titik."</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 03cf404..ae52c62 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Consente all\'applicazione di cambiare la rotazione dello schermo in qualsiasi momento. Non dovrebbe mai essere necessario per le normali applicazioni."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"cambio velocità del puntatore"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Consente all\'applicazione di modificare la velocità del puntatore del mouse o del trackpad in qualsiasi momento. Non dovrebbe mai essere necessaria per le applicazioni normali."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"invio segnali Linux alle applicazioni"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Consente all\'applicazione di richiedere l\'invio del segnale fornito a tutti i processi persistenti."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"esecuzione permanente delle applicazioni"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Tocca per disattivare il debug USB."</string> <string name="select_input_method" msgid="4653387336791222978">"Scegli il metodo di immissione"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Configura metodi di immissione"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidati"</u></string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 3c6e0c2..613410f 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"מאפשר ליישום לשנות את הסיבוב של המסך בכל עת. הרשאה זו לעולם אינה נחוצה ליישומים רגילים."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"שינוי מהירות המצביע"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"מאפשר ליישום לשנות את המהירות של מצביע העכבר או לוח המגע בכל עת. יישומים רגילים לא אמורים לעולם להזדקק להרשאה זו."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"שליחת אותות Linux ליישומים"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"מאפשר ליישום לבקש שהאות שנקלט יישלח לכל התהליכים המתמשכים."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"הגדרת היישום לפעול תמיד"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"גע כדי להשבית את ניקוי הבאגים בהתקן ה-USB."</string> <string name="select_input_method" msgid="4653387336791222978">"בחר שיטת הזנה"</string> <string name="configure_input_methods" msgid="9091652157722495116">"הגדר שיטות קלט"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"מועמדים"</u></string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 9e21085..5e5010d 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"いつでも画面の向きを変更することをアプリに許可します。通常のアプリでは不要です。"</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"ポインタの速度の変更"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"マウスまたはトラックパッドのポインタの速度をいつでも変更することをアプリに許可します。通常のアプリでは不要です。"</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"アプリへのLinuxシグナルの送信"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"受信したシグナルをすべての継続プロセスに送信するようリクエストすることをアプリに許可します。"</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"アプリの常時実行"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"タップしてUSBデバッグを無効にします。"</string> <string name="select_input_method" msgid="4653387336791222978">"入力方法の選択"</string> <string name="configure_input_methods" msgid="9091652157722495116">"入力方法をセットアップ"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"候補"</u></string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 8dc3fa6..5556aae 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"앱이 언제든지 화면 회전을 변경할 수 있도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"포인터 속도 변경"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"앱이 언제든지 마우스 또는 트랙패드 포인터의 속도를 변경할 수 있도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"앱에 Linux 시그널 보내기"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"제공된 시그널을 모든 영구 프로세스로 전송하는 것을 앱이 요청할 수 있도록 허용합니다."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"앱이 항상 실행되도록 설정"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"USB 디버깅을 사용하지 않으려면 터치하세요."</string> <string name="select_input_method" msgid="4653387336791222978">"입력 방법 선택"</string> <string name="configure_input_methods" msgid="9091652157722495116">"입력 방법 설정"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"가능한 원인"</u></string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index fa13981..9e82e8c 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Leidžiama programai bet kada kaitalioti ekraną. Įprastoms programoms to neturėtų prireikti."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"keisti žymiklio greitį"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Leidžiama programai keisti pelės ar sensorinio pulto žymiklio greitį. Įprastoms programoms to neturėtų prireikti."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"siųsti „Linux“ signalus programoms"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Leidžiama programai pateikti užklausą, kad teikiamas signalas būtų siunčiamas visiems nuolatiniams procesams."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"nustatyti, kad programa būtų visada vykdoma"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Palieskite, kad neleistumėte USB derinimo."</string> <string name="select_input_method" msgid="4653387336791222978">"Pasirinkite įvesties metodą"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Nustatyti įvesties metodus"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidatai"</u></string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 1fe5316..ae451e0 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Ļauj lietotnei jebkurā laikā mainīt ekrāna pozīciju. Parastajām lietotnēm tas nekad nav nepieciešams."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"Rādītāja ātruma mainīšana"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Ļauj lietotnei jebkurā laikā mainīt peles vai skārienpaliktņa rādītāja ātrumu. Parastajām lietotnēm tas nekad nav nepieciešams."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"sūtīt Linux signālus lietotnēm"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Ļauj lietotnei pieprasīt, lai piegādātais signāls tiktu sūtīts visiem pastāvīgajiem procesiem."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"likt lietotnei vienmēr darboties"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Pieskarieties, lai atspējotu USB atkļūdošanu."</string> <string name="select_input_method" msgid="4653387336791222978">"Ievades metodes izvēle"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Iestatīt ievades metodes"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidāti"</u></string> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index da9ca41..ead175b 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Membenarkan apl untuk menukar putaran skrin pada bila-bila masa. Tidak sekali-kali diperlukan untuk apl biasa."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"tukar kelajuan penuding"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Membenarkan apl untuk menukar kelajuan penunjuk tetikus atau pad jejak pada bila-bila masa. Tidak sekali-kali diperlukan untuk apl biasa."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"hantar isyarat Linux kepada apl"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Membenarkan apl meminta isyarat yang dibekalkan dihantar kepada semua proses yang berterusan."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"buatkan apl sentiasa berjalan"</string> @@ -1019,8 +1023,7 @@ <string name="time_picker_dialog_title" msgid="8349362623068819295">"Tetapkan masa"</string> <string name="date_picker_dialog_title" msgid="5879450659453782278">"Tetapkan tarikh"</string> <string name="date_time_set" msgid="5777075614321087758">"Tetapkan"</string> - <!-- no translation found for date_time_done (2507683751759308828) --> - <skip /> + <string name="date_time_done" msgid="2507683751759308828">"Selesai"</string> <string name="default_permission_group" msgid="2690160991405646128">"Lalai"</string> <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"BAHARU: "</font></string> <string name="no_permissions" msgid="7283357728219338112">"Tiada kebenaran diperlukan"</string> @@ -1060,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Sentuh untuk melumpuhkan penyahpepijatan USB."</string> <string name="select_input_method" msgid="4653387336791222978">"Pilih kaedah input"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Sediakan kaedah input"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"calon"</u></string> @@ -1170,35 +1177,22 @@ <string name="add_account_label" msgid="2935267344849993553">"Tambah akaun"</string> <string name="choose_account_text" msgid="6303348737197849675">"Akaun mana yang mahu anda gunakan?"</string> <string name="add_account_button_label" msgid="3611982894853435874">"Tambah akaun"</string> - <!-- no translation found for number_picker_increment_button (2412072272832284313) --> - <skip /> - <!-- no translation found for number_picker_decrement_button (476050778386779067) --> - <skip /> + <string name="number_picker_increment_button" msgid="2412072272832284313">"Tingkatkan"</string> + <string name="number_picker_decrement_button" msgid="476050778386779067">"Kurangkan"</string> <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> sentuh terus."</string> - <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) --> - <skip /> - <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) --> - <skip /> - <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) --> - <skip /> - <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) --> - <skip /> - <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) --> - <skip /> + <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Luncurkan ke atas untuk meningkatkan dan ke bawah untuk mengurangkan."</string> + <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Tingkatkan minit"</string> + <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Kurangkan minit"</string> + <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Tingkatkan jam"</string> + <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Kurangkan jam"</string> <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Tetapkan PM"</string> <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Tetapkan AM"</string> - <!-- no translation found for date_picker_increment_month_button (5369998479067934110) --> - <skip /> - <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) --> - <skip /> - <!-- no translation found for date_picker_increment_day_button (7130465412308173903) --> - <skip /> - <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) --> - <skip /> - <!-- no translation found for date_picker_increment_year_button (6318697384310808899) --> - <skip /> - <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) --> - <skip /> + <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Tingkatkan bulan"</string> + <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Kurangkan bulan"</string> + <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Tingkatkan hari"</string> + <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Kurangkan hari"</string> + <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Tingkatkan tahun"</string> + <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Kurangkan tahun"</string> <string name="checkbox_checked" msgid="7222044992652711167">"ditandakan"</string> <string name="checkbox_not_checked" msgid="5174639551134444056">"tidak ditandakan"</string> <string name="radiobutton_selected" msgid="8603599808486581511">"dipilih"</string> @@ -1218,20 +1212,15 @@ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Kongsi dengan"</string> <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Kongsi dengan <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> <string name="content_description_sliding_handle" msgid="415975056159262248">"Pemegang gelongsor. Sentuh & tahan."</string> - <!-- no translation found for description_direction_up (7169032478259485180) --> - <skip /> - <!-- no translation found for description_direction_down (5087739728639014595) --> - <skip /> - <!-- no translation found for description_direction_left (7207478719805562165) --> - <skip /> - <!-- no translation found for description_direction_right (8034433242579600980) --> - <skip /> + <string name="description_direction_up" msgid="7169032478259485180">"Luncurkan ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_down" msgid="5087739728639014595">"Luncurkan ke bawah untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_left" msgid="7207478719805562165">"Luncurkan ke kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_right" msgid="8034433242579600980">"Luncurkan ke kanan untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="description_target_unlock" msgid="2228524900439801453">"Buka kunci"</string> <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string> <string name="description_target_silent" msgid="893551287746522182">"Senyap"</string> <string name="description_target_soundon" msgid="30052466675500172">"Bunyi dihidupkan"</string> - <!-- no translation found for description_target_search (3091587249776033139) --> - <skip /> + <string name="description_target_search" msgid="3091587249776033139">"Carian"</string> <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Leret untuk membuka kunci."</string> <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Pasangkan set kepala untuk mendengar kekunci kata laluan disebutkan."</string> <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Titik."</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index ec580ad..bbd846f 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Gir appen tillatelse til når som helst å endre rotasjonen av skjermen. Skal aldri være nødvendig for vanlige apper."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"endre pekerhastighet"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Lar appen når som helst endre markørhastigheten til musen eller styreflaten. Skal aldri være nødvendig for vanlige apper."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"sende Linux-signaler til apper"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Lar appen be om at det leverte signalet sendes til alle vedvarende prosesser."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"angi at appen alltid skal kjøre"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Trykk for å deaktivere USB-feilsøking."</string> <string name="select_input_method" msgid="4653387336791222978">"Velg inndatametode"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Konfigurer inndatametoder"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string> <string name="candidates_style" msgid="4333913089637062257">"TAG_FONT"<u>"kandidater"</u>"CLOSE_FONT"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 94d9712..8440d62 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Hiermee kan de app de rotatie van het scherm op elk moment wijzigen. Nooit vereist voor normale apps."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"aanwijzersnelheid wijzigen"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Hiermee kan de app de snelheid van de muis- of trackpadaanwijzer op elk moment wijzigen. Nooit vereist voor normale apps."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"Linux-signalen verzenden naar apps"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Hiermee kan de app ervoor zorgen dat het geleverde signaal wordt verzonden naar alle persistente processen."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"app altijd laten uitvoeren"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Raak deze optie aan om USB-foutopsporing uit te schakelen."</string> <string name="select_input_method" msgid="4653387336791222978">"Invoermethode selecteren"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Invoermethoden instellen"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidaten"</u></string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index ee10502..ee1e6a3 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Pozwala aplikacji na zmianę obrotu ekranu w dowolnym momencie. To uprawnienie nie powinno być potrzebne zwykłym aplikacjom."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"zmiana szybkości wskaźnika"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Pozwala aplikacji zmienić szybkość wskaźnika myszy lub touchpada w dowolnym momencie. Nieprzeznaczone dla zwykłych aplikacji."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"wysyłanie sygnałów systemu Linux do aplikacji"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Pozwala aplikacji na żądanie, aby dostarczony sygnał został wysłany do wszystkich trwałych procesów."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"sprawianie, że aplikacja jest cały czas uruchomiona"</string> @@ -1019,8 +1023,7 @@ <string name="time_picker_dialog_title" msgid="8349362623068819295">"Ustaw godzinę"</string> <string name="date_picker_dialog_title" msgid="5879450659453782278">"Ustaw datę"</string> <string name="date_time_set" msgid="5777075614321087758">"Ustaw"</string> - <!-- no translation found for date_time_done (2507683751759308828) --> - <skip /> + <string name="date_time_done" msgid="2507683751759308828">"Gotowe"</string> <string name="default_permission_group" msgid="2690160991405646128">"Domyślne"</string> <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOWE: "</font></string> <string name="no_permissions" msgid="7283357728219338112">"Nie są wymagane żadne uprawnienia"</string> @@ -1060,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Dotknij, aby wyłączyć debugowanie USB."</string> <string name="select_input_method" msgid="4653387336791222978">"Wybierz metodę wprowadzania"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Konfiguruj metody wprowadzania"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĄBCĆDEĘFGHIJKLŁMNŃOÓPQRSŚTUVWXYZŹŻ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandydaci"</u></string> @@ -1170,35 +1177,22 @@ <string name="add_account_label" msgid="2935267344849993553">"Dodaj konto"</string> <string name="choose_account_text" msgid="6303348737197849675">"Którego konta chcesz użyć?"</string> <string name="add_account_button_label" msgid="3611982894853435874">"Dodaj konto"</string> - <!-- no translation found for number_picker_increment_button (2412072272832284313) --> - <skip /> - <!-- no translation found for number_picker_decrement_button (476050778386779067) --> - <skip /> + <string name="number_picker_increment_button" msgid="2412072272832284313">"Zwiększ"</string> + <string name="number_picker_decrement_button" msgid="476050778386779067">"Zmniejsz"</string> <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> dotknij i przytrzymaj."</string> - <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) --> - <skip /> - <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) --> - <skip /> - <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) --> - <skip /> - <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) --> - <skip /> - <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) --> - <skip /> + <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Przesuń w górę, by zwiększyć, i w dół, by zmniejszyć."</string> + <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Zmień minutę na późniejszą"</string> + <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Zmień minutę na wcześniejszą"</string> + <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Zmień godzinę na późniejszą"</string> + <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Zmień godzinę na wcześniejszą"</string> <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Ustaw PM"</string> <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Ustaw AM"</string> - <!-- no translation found for date_picker_increment_month_button (5369998479067934110) --> - <skip /> - <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) --> - <skip /> - <!-- no translation found for date_picker_increment_day_button (7130465412308173903) --> - <skip /> - <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) --> - <skip /> - <!-- no translation found for date_picker_increment_year_button (6318697384310808899) --> - <skip /> - <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) --> - <skip /> + <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Zmień miesiąc na późniejszy"</string> + <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Zmień miesiąc na wcześniejszy"</string> + <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Zmień dzień na późniejszy"</string> + <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Zmień dzień na wcześniejszy"</string> + <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Zmień rok na późniejszy"</string> + <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Zmień rok na wcześniejszy"</string> <string name="checkbox_checked" msgid="7222044992652711167">"zaznaczono"</string> <string name="checkbox_not_checked" msgid="5174639551134444056">"nie zaznaczono"</string> <string name="radiobutton_selected" msgid="8603599808486581511">"wybrano"</string> @@ -1218,20 +1212,15 @@ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Udostępnij przez"</string> <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Udostępnij przez <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> <string name="content_description_sliding_handle" msgid="415975056159262248">"Uchwyt przesuwny. Dotknij i przytrzymaj."</string> - <!-- no translation found for description_direction_up (7169032478259485180) --> - <skip /> - <!-- no translation found for description_direction_down (5087739728639014595) --> - <skip /> - <!-- no translation found for description_direction_left (7207478719805562165) --> - <skip /> - <!-- no translation found for description_direction_right (8034433242579600980) --> - <skip /> + <string name="description_direction_up" msgid="7169032478259485180">"Przesuń w górę: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_down" msgid="5087739728639014595">"Przesuń w dół: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_left" msgid="7207478719805562165">"Przesuń w lewo: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_right" msgid="8034433242579600980">"Przesuń w prawo: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="description_target_unlock" msgid="2228524900439801453">"Odblokuj"</string> <string name="description_target_camera" msgid="969071997552486814">"Aparat"</string> <string name="description_target_silent" msgid="893551287746522182">"Wyciszenie"</string> <string name="description_target_soundon" msgid="30052466675500172">"Włącz dźwięk"</string> - <!-- no translation found for description_target_search (3091587249776033139) --> - <skip /> + <string name="description_target_search" msgid="3091587249776033139">"Szukaj"</string> <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Przesuń, aby odblokować."</string> <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Podłącz zestaw słuchawkowy, aby wysłuchać znaków hasła wypowiadanych na głos."</string> <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Kropka"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 290ae19..393ba17 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Permite que a aplicação altere a rotação do ecrã em qualquer momento. Nunca deve ser necessário para aplicações normais."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"alterar a veloc. do ponteiro"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Permite à aplicação mudar em qualquer altura a velocidade do ponteiro do rato ou do trackpad. Nunca deverá ser necessário para aplicações normais."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"enviar sinais Linux para aplicações"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Permite à aplicação pedir que o sinal fornecido seja enviado a todos os processos persistentes."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"fazer com que a aplicação seja sempre executada"</string> @@ -1019,8 +1023,7 @@ <string name="time_picker_dialog_title" msgid="8349362623068819295">"Definir hora"</string> <string name="date_picker_dialog_title" msgid="5879450659453782278">"Definir data"</string> <string name="date_time_set" msgid="5777075614321087758">"Definir"</string> - <!-- no translation found for date_time_done (2507683751759308828) --> - <skip /> + <string name="date_time_done" msgid="2507683751759308828">"Concluído"</string> <string name="default_permission_group" msgid="2690160991405646128">"Predefinido"</string> <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVA: "</font></string> <string name="no_permissions" msgid="7283357728219338112">"Não são necessárias permissões"</string> @@ -1060,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Toque para desativar a depuração USB."</string> <string name="select_input_method" msgid="4653387336791222978">"Escolher o método de entrada"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Configurar métodos de introdução"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string> @@ -1170,35 +1177,22 @@ <string name="add_account_label" msgid="2935267344849993553">"Adicionar uma conta"</string> <string name="choose_account_text" msgid="6303348737197849675">"Que conta pretende utilizar?"</string> <string name="add_account_button_label" msgid="3611982894853435874">"Adicionar conta"</string> - <!-- no translation found for number_picker_increment_button (2412072272832284313) --> - <skip /> - <!-- no translation found for number_picker_decrement_button (476050778386779067) --> - <skip /> + <string name="number_picker_increment_button" msgid="2412072272832284313">"Aumentar"</string> + <string name="number_picker_decrement_button" msgid="476050778386779067">"Diminuir"</string> <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Toque sem soltar em <xliff:g id="VALUE">%s</xliff:g>."</string> - <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) --> - <skip /> - <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) --> - <skip /> - <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) --> - <skip /> - <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) --> - <skip /> - <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) --> - <skip /> + <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Deslizar para cima para aumentar e para baixo para diminuir."</string> + <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Aumentar minutos"</string> + <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Diminuir minutos"</string> + <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Aumentar horas"</string> + <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Diminuir hora"</string> <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Definir PM"</string> <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Definir AM"</string> - <!-- no translation found for date_picker_increment_month_button (5369998479067934110) --> - <skip /> - <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) --> - <skip /> - <!-- no translation found for date_picker_increment_day_button (7130465412308173903) --> - <skip /> - <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) --> - <skip /> - <!-- no translation found for date_picker_increment_year_button (6318697384310808899) --> - <skip /> - <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) --> - <skip /> + <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Aumentar mês"</string> + <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Diminuir mês"</string> + <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Aumentar o dia"</string> + <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Diminuir dia"</string> + <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Aumentar ano"</string> + <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Diminuir ano"</string> <string name="checkbox_checked" msgid="7222044992652711167">"marcado"</string> <string name="checkbox_not_checked" msgid="5174639551134444056">"desmarcado"</string> <string name="radiobutton_selected" msgid="8603599808486581511">"selecionado"</string> @@ -1218,20 +1212,15 @@ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Partilhar com:"</string> <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Compartilhar com <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> <string name="content_description_sliding_handle" msgid="415975056159262248">"Barra deslizante. Toque & não solte."</string> - <!-- no translation found for description_direction_up (7169032478259485180) --> - <skip /> - <!-- no translation found for description_direction_down (5087739728639014595) --> - <skip /> - <!-- no translation found for description_direction_left (7207478719805562165) --> - <skip /> - <!-- no translation found for description_direction_right (8034433242579600980) --> - <skip /> + <string name="description_direction_up" msgid="7169032478259485180">"Deslize para cima para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string> + <string name="description_direction_down" msgid="5087739728639014595">"Deslize para baixo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string> + <string name="description_direction_left" msgid="7207478719805562165">"Deslize para a esquerda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string> + <string name="description_direction_right" msgid="8034433242579600980">"Deslize para a direita para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string> <string name="description_target_unlock" msgid="2228524900439801453">"Desbloquear"</string> <string name="description_target_camera" msgid="969071997552486814">"Câmara"</string> <string name="description_target_silent" msgid="893551287746522182">"Silencioso"</string> <string name="description_target_soundon" msgid="30052466675500172">"Som ativado"</string> - <!-- no translation found for description_target_search (3091587249776033139) --> - <skip /> + <string name="description_target_search" msgid="3091587249776033139">"Pesquisar"</string> <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Deslizar rapidamente para desbloquear."</string> <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Ligue os auscultadores com microfone integrado para ouvir as teclas da palavra-passe."</string> <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Ponto."</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 09fe685..bb145f7 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Permite que o aplicativo gire a tela a qualquer momento. Nunca deve ser necessário para aplicativos normais."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"alterar velocidade do ponteiro"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Permite que o aplicativo altere a velocidade do cursos do mouse ou trackpad a qualquer momento. Nunca deve ser necessário para aplicativos normais."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"enviar sinais para aplicativos Linux"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Permite que o aplicativo solicite o envio do sinal fornecido a todos os processos persistentes."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"sempre executar o aplicativo"</string> @@ -1019,8 +1023,7 @@ <string name="time_picker_dialog_title" msgid="8349362623068819295">"Definir hora"</string> <string name="date_picker_dialog_title" msgid="5879450659453782278">"Definir data"</string> <string name="date_time_set" msgid="5777075614321087758">"Definir"</string> - <!-- no translation found for date_time_done (2507683751759308828) --> - <skip /> + <string name="date_time_done" msgid="2507683751759308828">"Concluído"</string> <string name="default_permission_group" msgid="2690160991405646128">"Padrão"</string> <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVO: "</font></string> <string name="no_permissions" msgid="7283357728219338112">"Nenhuma permissão necessária"</string> @@ -1060,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Toque para desativar a depuração do USB."</string> <string name="select_input_method" msgid="4653387336791222978">"Selecione o método de entrada"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Configurar métodos de entrada"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string> @@ -1170,35 +1177,22 @@ <string name="add_account_label" msgid="2935267344849993553">"Adicionar uma conta"</string> <string name="choose_account_text" msgid="6303348737197849675">"Qual conta você deseja usar?"</string> <string name="add_account_button_label" msgid="3611982894853435874">"Adicionar conta"</string> - <!-- no translation found for number_picker_increment_button (2412072272832284313) --> - <skip /> - <!-- no translation found for number_picker_decrement_button (476050778386779067) --> - <skip /> + <string name="number_picker_increment_button" msgid="2412072272832284313">"Aumentar"</string> + <string name="number_picker_decrement_button" msgid="476050778386779067">"Diminuir"</string> <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> toque e mantenha pressionado."</string> - <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) --> - <skip /> - <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) --> - <skip /> - <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) --> - <skip /> - <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) --> - <skip /> - <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) --> - <skip /> + <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Deslize para cima para aumentar e para baixo para diminuir."</string> + <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Aumentar minuto"</string> + <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Diminuir minuto"</string> + <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Aumentar hora"</string> + <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Diminuir hora"</string> <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Configurar valor PM"</string> <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Configurar valor AM"</string> - <!-- no translation found for date_picker_increment_month_button (5369998479067934110) --> - <skip /> - <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) --> - <skip /> - <!-- no translation found for date_picker_increment_day_button (7130465412308173903) --> - <skip /> - <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) --> - <skip /> - <!-- no translation found for date_picker_increment_year_button (6318697384310808899) --> - <skip /> - <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) --> - <skip /> + <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Aumentar mês"</string> + <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Diminuir mês"</string> + <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Aumentar dia"</string> + <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Diminuir dia"</string> + <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Aumentar ano"</string> + <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Diminuir ano"</string> <string name="checkbox_checked" msgid="7222044992652711167">"verificado"</string> <string name="checkbox_not_checked" msgid="5174639551134444056">"não selecionado"</string> <string name="radiobutton_selected" msgid="8603599808486581511">"selecionado"</string> @@ -1218,20 +1212,15 @@ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Compartilhar com"</string> <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Compartilhar com <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> <string name="content_description_sliding_handle" msgid="415975056159262248">"Recurso deslizante. Toque e segure."</string> - <!-- no translation found for description_direction_up (7169032478259485180) --> - <skip /> - <!-- no translation found for description_direction_down (5087739728639014595) --> - <skip /> - <!-- no translation found for description_direction_left (7207478719805562165) --> - <skip /> - <!-- no translation found for description_direction_right (8034433242579600980) --> - <skip /> + <string name="description_direction_up" msgid="7169032478259485180">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para cima."</string> + <string name="description_direction_down" msgid="5087739728639014595">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para baixo."</string> + <string name="description_direction_left" msgid="7207478719805562165">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para a esquerda."</string> + <string name="description_direction_right" msgid="8034433242579600980">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para a direita."</string> <string name="description_target_unlock" msgid="2228524900439801453">"Desbloquear"</string> <string name="description_target_camera" msgid="969071997552486814">"Câmera"</string> <string name="description_target_silent" msgid="893551287746522182">"Silencioso"</string> <string name="description_target_soundon" msgid="30052466675500172">"Som ativado"</string> - <!-- no translation found for description_target_search (3091587249776033139) --> - <skip /> + <string name="description_target_search" msgid="3091587249776033139">"Pesquisar"</string> <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Deslize para desbloquear."</string> <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Conecte um fone de ouvido para ouvir as teclas da senha."</string> <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Ponto final."</string> diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml index f4bc105..8b0718f 100644 --- a/core/res/res/values-rm/strings.xml +++ b/core/res/res/values-rm/strings.xml @@ -399,6 +399,10 @@ <skip /> <!-- no translation found for permdesc_setPointerSpeed (6866563234274104233) --> <skip /> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <!-- no translation found for permlab_signalPersistentProcesses (4539002991947376659) --> <skip /> <!-- no translation found for permdesc_signalPersistentProcesses (4896992079182649141) --> @@ -1575,6 +1579,10 @@ <skip /> <!-- no translation found for configure_input_methods (9091652157722495116) --> <skip /> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 9dee72d..d93d8d1 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Permite aplicaţiei să modifice rotaţia ecranului în orice moment. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"modifică viteza indicatorului"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Permite aplicaţiei să modifice oricând viteza indicatorului mouse-ului sau al trackpadului. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"trimitere semnale Linux către aplicaţii"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Permite aplicaţiei să solicite trimiterea semnalului furnizat către toate procesele persistente."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"rulare continuă a aplicaţiei"</string> @@ -1019,8 +1023,7 @@ <string name="time_picker_dialog_title" msgid="8349362623068819295">"Setaţi ora"</string> <string name="date_picker_dialog_title" msgid="5879450659453782278">"Setaţi data"</string> <string name="date_time_set" msgid="5777075614321087758">"Setaţi"</string> - <!-- no translation found for date_time_done (2507683751759308828) --> - <skip /> + <string name="date_time_done" msgid="2507683751759308828">"Terminat"</string> <string name="default_permission_group" msgid="2690160991405646128">"Prestabilit"</string> <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOU: "</font></string> <string name="no_permissions" msgid="7283357728219338112">"Nu se solicită nicio permisiune"</string> @@ -1060,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Atingeţi pentru a dezactiva depanarea USB."</string> <string name="select_input_method" msgid="4653387336791222978">"Alegeţi metoda de introducere"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Configurare metode introducere"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidaţi"</u></string> @@ -1170,35 +1177,22 @@ <string name="add_account_label" msgid="2935267344849993553">"Adăugaţi un cont"</string> <string name="choose_account_text" msgid="6303348737197849675">"Ce cont doriţi să utilizaţi?"</string> <string name="add_account_button_label" msgid="3611982894853435874">"Adăugaţi un cont"</string> - <!-- no translation found for number_picker_increment_button (2412072272832284313) --> - <skip /> - <!-- no translation found for number_picker_decrement_button (476050778386779067) --> - <skip /> + <string name="number_picker_increment_button" msgid="2412072272832284313">"Creşteţi"</string> + <string name="number_picker_decrement_button" msgid="476050778386779067">"Reduceţi"</string> <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Atingeţi şi ţineţi apăsat <xliff:g id="VALUE">%s</xliff:g>."</string> - <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) --> - <skip /> - <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) --> - <skip /> - <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) --> - <skip /> - <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) --> - <skip /> - <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) --> - <skip /> + <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Glisaţi în sus pentru a creşte şi în jos pentru a reduce."</string> + <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Creşteţi valoarea pentru minute"</string> + <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Reduceţi valoarea pentru minute"</string> + <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Creşteţi valoarea pentru oră"</string> + <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Reduceţi valoarea pentru oră"</string> <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Setaţi valoarea PM"</string> <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Setaţi valoarea AM"</string> - <!-- no translation found for date_picker_increment_month_button (5369998479067934110) --> - <skip /> - <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) --> - <skip /> - <!-- no translation found for date_picker_increment_day_button (7130465412308173903) --> - <skip /> - <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) --> - <skip /> - <!-- no translation found for date_picker_increment_year_button (6318697384310808899) --> - <skip /> - <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) --> - <skip /> + <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Creşteţi valoarea pentru lună"</string> + <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Reduceţi valoarea pentru lună"</string> + <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Creşteţi valoarea pentru zi"</string> + <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Reduceţi valoarea pentru zi"</string> + <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Creşteţi valoarea pentru an"</string> + <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Reduceţi valoarea pentru an"</string> <string name="checkbox_checked" msgid="7222044992652711167">"bifată"</string> <string name="checkbox_not_checked" msgid="5174639551134444056">"nebifată"</string> <string name="radiobutton_selected" msgid="8603599808486581511">"selectat"</string> @@ -1218,20 +1212,15 @@ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Permiteţi accesul pentru"</string> <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Permiteţi accesul pentru <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> <string name="content_description_sliding_handle" msgid="415975056159262248">"Mâner glisant. Atingeţi şi ţineţi apăsat."</string> - <!-- no translation found for description_direction_up (7169032478259485180) --> - <skip /> - <!-- no translation found for description_direction_down (5087739728639014595) --> - <skip /> - <!-- no translation found for description_direction_left (7207478719805562165) --> - <skip /> - <!-- no translation found for description_direction_right (8034433242579600980) --> - <skip /> + <string name="description_direction_up" msgid="7169032478259485180">"Glisaţi în sus pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_down" msgid="5087739728639014595">"Glisaţi în jos pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_left" msgid="7207478719805562165">"Glisaţi spre stânga pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_right" msgid="8034433242579600980">"Glisaţi spre dreapta pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="description_target_unlock" msgid="2228524900439801453">"Deblocaţi"</string> <string name="description_target_camera" msgid="969071997552486814">"Cameră foto"</string> <string name="description_target_silent" msgid="893551287746522182">"Silenţios"</string> <string name="description_target_soundon" msgid="30052466675500172">"Sunet activat"</string> - <!-- no translation found for description_target_search (3091587249776033139) --> - <skip /> + <string name="description_target_search" msgid="3091587249776033139">"Căutaţi"</string> <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Glisaţi pentru a debloca."</string> <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Conectaţi un set căşti-microfon pentru a auzi tastele apăsate când introduceţi parola."</string> <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punct."</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 041133cd..2743763 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Приложение сможет менять ориентацию экрана. Это разрешение не используется обычными приложениями."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"изменять скорость указателя"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Приложение сможет в любой момент изменить скорость движения указателя мыши или сенсорной панели. Это разрешение не используется обычными приложениями."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"отправка сигналов Linux приложениям"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Приложение сможет запрашивать передачу полученного сигнала всем постоянным процессам."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"постоянная работа приложения"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Нажмите, чтобы отключить отладку по USB."</string> <string name="select_input_method" msgid="4653387336791222978">"Выберите способ ввода"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Настройка способов ввода"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"варианты"</u></string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index c7c7b4f..49d04c3 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Umožňuje aplikácii kedykoľvek zmeniť otáčanie obrazovky. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"zmena rýchlosti ukazovateľa"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Umožňuje aplikácii kedykoľvek zmeniť rýchlosť kurzora myši alebo touchpadu. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"odoslať aplikáciám signály systému Linux"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Umožňuje aplikácii vyžiadať odoslanie poskytnutého signálu všetkým trvalým procesom."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"nastaviť, aby bola aplikácia neustále spustená"</string> @@ -1019,8 +1023,7 @@ <string name="time_picker_dialog_title" msgid="8349362623068819295">"Nastaviť čas"</string> <string name="date_picker_dialog_title" msgid="5879450659453782278">"Nastaviť dátum"</string> <string name="date_time_set" msgid="5777075614321087758">"Nastaviť"</string> - <!-- no translation found for date_time_done (2507683751759308828) --> - <skip /> + <string name="date_time_done" msgid="2507683751759308828">"Hotovo"</string> <string name="default_permission_group" msgid="2690160991405646128">"Predvolené"</string> <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVINKA: "</font></string> <string name="no_permissions" msgid="7283357728219338112">"Nevyžadujú sa žiadne oprávnenia."</string> @@ -1060,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Dotknutím zakážete ladenie USB."</string> <string name="select_input_method" msgid="4653387336791222978">"Zvoliť metódu vstupu"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Nastavenie metód vstupu"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁÄBCČDĎDZDŽEÉFGHCHIÍJKLĽMNŇOÓÔPRŔSŠTŤUÚVWXYÝZŽ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidáti"</u></string> @@ -1170,35 +1177,22 @@ <string name="add_account_label" msgid="2935267344849993553">"Pridať účet"</string> <string name="choose_account_text" msgid="6303348737197849675">"Ktorý účet chcete použiť?"</string> <string name="add_account_button_label" msgid="3611982894853435874">"Pridať účet"</string> - <!-- no translation found for number_picker_increment_button (2412072272832284313) --> - <skip /> - <!-- no translation found for number_picker_decrement_button (476050778386779067) --> - <skip /> + <string name="number_picker_increment_button" msgid="2412072272832284313">"Zvýšiť"</string> + <string name="number_picker_decrement_button" msgid="476050778386779067">"Znížiť"</string> <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Dotknite sa a podržte <xliff:g id="VALUE">%s</xliff:g>."</string> - <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) --> - <skip /> - <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) --> - <skip /> - <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) --> - <skip /> - <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) --> - <skip /> - <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) --> - <skip /> + <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Ak chcete hodnotu zvýšiť, prejdite prstom nahor. Ak chcete hodnotu znížiť, prejdite prstom nadol."</string> + <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Pridať minútu"</string> + <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Ubrať minútu"</string> + <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Pridať hodinu"</string> + <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Ubrať hodinu"</string> <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Nastaviť čas popoludní"</string> <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Nastaviť čas dopoludnia"</string> - <!-- no translation found for date_picker_increment_month_button (5369998479067934110) --> - <skip /> - <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) --> - <skip /> - <!-- no translation found for date_picker_increment_day_button (7130465412308173903) --> - <skip /> - <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) --> - <skip /> - <!-- no translation found for date_picker_increment_year_button (6318697384310808899) --> - <skip /> - <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) --> - <skip /> + <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Pridať mesiac"</string> + <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Ubrať mesiac"</string> + <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Pridať deň"</string> + <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Ubrať deň"</string> + <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Pridať rok"</string> + <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Ubrať rok"</string> <string name="checkbox_checked" msgid="7222044992652711167">"začiarknuté"</string> <string name="checkbox_not_checked" msgid="5174639551134444056">"nezačiarknuté"</string> <string name="radiobutton_selected" msgid="8603599808486581511">"vybratý"</string> @@ -1218,20 +1212,15 @@ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Zdieľať s"</string> <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Zdieľať s aplikáciou <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> <string name="content_description_sliding_handle" msgid="415975056159262248">"Posuvné tlačidlo. Dotknite sa a podržte."</string> - <!-- no translation found for description_direction_up (7169032478259485180) --> - <skip /> - <!-- no translation found for description_direction_down (5087739728639014595) --> - <skip /> - <!-- no translation found for description_direction_left (7207478719805562165) --> - <skip /> - <!-- no translation found for description_direction_right (8034433242579600980) --> - <skip /> + <string name="description_direction_up" msgid="7169032478259485180">"Prejdite prstom nahor: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_down" msgid="5087739728639014595">"Prejdite prstom nadol: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_left" msgid="7207478719805562165">"Prejdite prstom doľava: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_right" msgid="8034433242579600980">"Prejdite prstom doprava: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="description_target_unlock" msgid="2228524900439801453">"Odomknúť"</string> <string name="description_target_camera" msgid="969071997552486814">"Fotoaparát"</string> <string name="description_target_silent" msgid="893551287746522182">"Tichý"</string> <string name="description_target_soundon" msgid="30052466675500172">"Zapnúť zvuk"</string> - <!-- no translation found for description_target_search (3091587249776033139) --> - <skip /> + <string name="description_target_search" msgid="3091587249776033139">"Vyhľadávanie"</string> <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Posunom odomknúť."</string> <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Ak si chcete vypočuť vyslovené klávesy hesla, pripojte náhlavnú súpravu."</string> <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Bodka."</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 4dc425b..55f3593 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Programu omogoča, da kadar koli zasuka zaslon. Ne uporabljajte za navadne programe."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"spreminjanje hitrosti kazalca"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Programu omogoča spreminjanje hitrosti kazalca miške ali sledilne ploščice. Tega ni treba nikoli uporabiti za navadne programe."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"pošiljanje signalov Linuxa programom"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Programu omogoča, da zahteva, da je posredovani signal poslan vsem trajnim procesom."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"neprekinjeno izvajanje programov"</string> @@ -1019,8 +1023,7 @@ <string name="time_picker_dialog_title" msgid="8349362623068819295">"Nastavi uro"</string> <string name="date_picker_dialog_title" msgid="5879450659453782278">"Nastavi datum"</string> <string name="date_time_set" msgid="5777075614321087758">"Nastavi"</string> - <!-- no translation found for date_time_done (2507683751759308828) --> - <skip /> + <string name="date_time_done" msgid="2507683751759308828">"Končano"</string> <string name="default_permission_group" msgid="2690160991405646128">"Privzeto"</string> <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVO: "</font></string> <string name="no_permissions" msgid="7283357728219338112">"Ni zahtevanih dovoljenj"</string> @@ -1060,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Dotaknite se, če želite onemogočiti iskanje in odpravljanje napak prek vrat USB."</string> <string name="select_input_method" msgid="4653387336791222978">"Izberite način vnosa"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Nastavi načine vnosa"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidati"</u></string> @@ -1170,35 +1177,22 @@ <string name="add_account_label" msgid="2935267344849993553">"Dodajanje računa"</string> <string name="choose_account_text" msgid="6303348737197849675">"Kateri račun želite uporabiti?"</string> <string name="add_account_button_label" msgid="3611982894853435874">"Dodaj račun"</string> - <!-- no translation found for number_picker_increment_button (2412072272832284313) --> - <skip /> - <!-- no translation found for number_picker_decrement_button (476050778386779067) --> - <skip /> + <string name="number_picker_increment_button" msgid="2412072272832284313">"Več"</string> + <string name="number_picker_decrement_button" msgid="476050778386779067">"Manj"</string> <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Dotaknite se vrednosti <xliff:g id="VALUE">%s</xliff:g> in jo pridržite."</string> - <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) --> - <skip /> - <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) --> - <skip /> - <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) --> - <skip /> - <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) --> - <skip /> - <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) --> - <skip /> + <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Povlecite navzgor za povečanje in navzdol za zmanjšanje."</string> + <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Povečanje vrednosti za minuto"</string> + <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Zmanjšanje vrednosti za minuto"</string> + <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Povečanje vrednosti za uro"</string> + <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Zmanjšanje vrednosti za uro"</string> <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Nastavi PM"</string> <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Nastavi AM"</string> - <!-- no translation found for date_picker_increment_month_button (5369998479067934110) --> - <skip /> - <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) --> - <skip /> - <!-- no translation found for date_picker_increment_day_button (7130465412308173903) --> - <skip /> - <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) --> - <skip /> - <!-- no translation found for date_picker_increment_year_button (6318697384310808899) --> - <skip /> - <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) --> - <skip /> + <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Povečanje vrednosti za mesec"</string> + <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Zmanjšanje vrednosti za mesec"</string> + <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Povečanje vrednosti za dan"</string> + <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Zmanjšanje vrednosti za dan"</string> + <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Povečanje vrednosti za leto"</string> + <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Zmanjšanje vrednosti za leto"</string> <string name="checkbox_checked" msgid="7222044992652711167">"potrjeno"</string> <string name="checkbox_not_checked" msgid="5174639551134444056">"ni odkljukano"</string> <string name="radiobutton_selected" msgid="8603599808486581511">"izbrano"</string> @@ -1218,20 +1212,15 @@ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Delite z"</string> <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Delite s programom <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> <string name="content_description_sliding_handle" msgid="415975056159262248">"Drsna ročica. Dotaknite se in pridržite."</string> - <!-- no translation found for description_direction_up (7169032478259485180) --> - <skip /> - <!-- no translation found for description_direction_down (5087739728639014595) --> - <skip /> - <!-- no translation found for description_direction_left (7207478719805562165) --> - <skip /> - <!-- no translation found for description_direction_right (8034433242579600980) --> - <skip /> + <string name="description_direction_up" msgid="7169032478259485180">"Povlecite navzgor za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_down" msgid="5087739728639014595">"Povlecite navzdol za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_left" msgid="7207478719805562165">"Povlecite v levo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string> + <string name="description_direction_right" msgid="8034433242579600980">"Povlecite v desno za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="description_target_unlock" msgid="2228524900439801453">"Odkleni"</string> <string name="description_target_camera" msgid="969071997552486814">"Fotoaparat"</string> <string name="description_target_silent" msgid="893551287746522182">"Tiho"</string> <string name="description_target_soundon" msgid="30052466675500172">"Vklopljen zvok"</string> - <!-- no translation found for description_target_search (3091587249776033139) --> - <skip /> + <string name="description_target_search" msgid="3091587249776033139">"Iskanje"</string> <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Povlecite, če želite odkleniti."</string> <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Priključite slušalke, če želite slišati izgovorjene tipke gesla."</string> <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Pika."</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 94024b8..de03bec 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Дозвољава апликацији да у сваком тренутку промени ротацију екрана. Уобичајене апликације никада не би требало да је користе."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"промена брзине показивача"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Дозвољава апликацији да у било ком тренутку промени брзину показивача миша или показивачког уређаја са плочицом. Уобичајене апликације никада не би требало да је користе."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"слање Linux сигнала апликацијама"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Дозвољава апликацији да захтева да испоручени сигнал буде послат свим трајним процесима."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"омогућавање непрекидне активности апликације"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Додирните да бисте онемогућили отклањање грешака са USB-а."</string> <string name="select_input_method" msgid="4653387336791222978">"Избор метода уноса"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Подеси методе уноса"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index ec77eb1..7448ff8 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Gör att appen när som helst kan ändra skärmläget. Behövs inte för vanliga appar."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"ändra markörens hastighet"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Tillåter att appen när som helst ändrar hastigheten för musens eller styrplattans markör. Ska inte behövas för vanliga appar."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"skicka Linux-signaler till appar"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Tillåter att appen begär att den angivna signalen skickas till alla beständiga processer."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"se till att appen alltid körs"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Tryck om du vill inaktivera USB-felsökning."</string> <string name="select_input_method" msgid="4653387336791222978">"Välj inmatningsmetod"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Konfigurera inmatningsmetoder"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidater"</u></string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 6b64163..ab6c82f 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Inaruhusu programu kubadilisha mzunguko wa skrini wakati wowote. Kamwe hazihitajiki kwa programu za kawaida."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"Badilisha kasi ya pointa"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Inaruhusu programu kubadilisha kasi ya kielekezi cha kipanya au pedi ya kufuatilia wakati wowote. Kamwe haitahitajika kwa programu za kawaida."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"Tuma ishara za Linux kwa programu"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Inaruhusu programu kuomba ishara iliyotolewa kutumwa kwa michakato inyoendelea."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"Fanya programu kuendeshwa kila mara"</string> @@ -1019,8 +1023,7 @@ <string name="time_picker_dialog_title" msgid="8349362623068819295">"Weka muda"</string> <string name="date_picker_dialog_title" msgid="5879450659453782278">"Weka tarehe"</string> <string name="date_time_set" msgid="5777075614321087758">"Weka"</string> - <!-- no translation found for date_time_done (2507683751759308828) --> - <skip /> + <string name="date_time_done" msgid="2507683751759308828">"Imekamilika"</string> <string name="default_permission_group" msgid="2690160991405646128">"Chaguo-msingi"</string> <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">" MPYA: "</font></string> <string name="no_permissions" msgid="7283357728219338112">"Hakuna vibali vinavyohitajika"</string> @@ -1060,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Gusa ili kulemaza utatuaji wa USB."</string> <string name="select_input_method" msgid="4653387336791222978">"Chagua njia ya ingizo"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Weka mbinu za ingizo"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"wagombeaji"</u></string> @@ -1170,35 +1177,22 @@ <string name="add_account_label" msgid="2935267344849993553">"Ongeza akaunti"</string> <string name="choose_account_text" msgid="6303348737197849675">"Je, ni akaunti gani unataka kutumia?"</string> <string name="add_account_button_label" msgid="3611982894853435874">"Ongeza akaunti"</string> - <!-- no translation found for number_picker_increment_button (2412072272832284313) --> - <skip /> - <!-- no translation found for number_picker_decrement_button (476050778386779067) --> - <skip /> + <string name="number_picker_increment_button" msgid="2412072272832284313">"Ongeza"</string> + <string name="number_picker_decrement_button" msgid="476050778386779067">"Punguza"</string> <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> gusa na ushikilie."</string> - <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) --> - <skip /> - <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) --> - <skip /> - <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) --> - <skip /> - <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) --> - <skip /> - <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) --> - <skip /> + <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Sogeza juu ili uongeze na chini ili upunguze."</string> + <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Ongeza dakika"</string> + <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Punguza dakika"</string> + <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Ongeza saa"</string> + <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Punguza saa"</string> <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Seti PM"</string> <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Seti AM"</string> - <!-- no translation found for date_picker_increment_month_button (5369998479067934110) --> - <skip /> - <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) --> - <skip /> - <!-- no translation found for date_picker_increment_day_button (7130465412308173903) --> - <skip /> - <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) --> - <skip /> - <!-- no translation found for date_picker_increment_year_button (6318697384310808899) --> - <skip /> - <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) --> - <skip /> + <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Ongeza mwezi"</string> + <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Punguza mwezi"</string> + <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Ongeza siku"</string> + <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Punguza siku"</string> + <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Ongeza mwaka"</string> + <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Punguza mwaka"</string> <string name="checkbox_checked" msgid="7222044992652711167">"imeangaliwa"</string> <string name="checkbox_not_checked" msgid="5174639551134444056">"haijakaguliwa"</string> <string name="radiobutton_selected" msgid="8603599808486581511">"Iliyochaguliwa"</string> @@ -1218,20 +1212,15 @@ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Gawa na"</string> <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Gawa na <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> <string name="content_description_sliding_handle" msgid="415975056159262248">"Utambo unaosonga. Gusa & shika"</string> - <!-- no translation found for description_direction_up (7169032478259485180) --> - <skip /> - <!-- no translation found for description_direction_down (5087739728639014595) --> - <skip /> - <!-- no translation found for description_direction_left (7207478719805562165) --> - <skip /> - <!-- no translation found for description_direction_right (8034433242579600980) --> - <skip /> + <string name="description_direction_up" msgid="7169032478259485180">"Sogeza juu kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string> + <string name="description_direction_down" msgid="5087739728639014595">"Sogeza chini kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_left" msgid="7207478719805562165">"Sogeza kushoto kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string> + <string name="description_direction_right" msgid="8034433242579600980">"Sogeza kulika kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string> <string name="description_target_unlock" msgid="2228524900439801453">"Fungua"</string> <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string> <string name="description_target_silent" msgid="893551287746522182">"Kimya"</string> <string name="description_target_soundon" msgid="30052466675500172">"Sauti imewashwa"</string> - <!-- no translation found for description_target_search (3091587249776033139) --> - <skip /> + <string name="description_target_search" msgid="3091587249776033139">"Tafuta"</string> <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Pitisha ili kufungua."</string> <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Chomeka kifaa cha sauti ili kusikiliza vibonye vya nenosiri vikizungumzwa."</string> <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Nukta."</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index a9313b7..7007522 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"อนุญาตให้แอปพลิเคชันเปลี่ยนการหมุนของหน้าจอได้ตลอดเวลา ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"เปลี่ยนความเร็วของตัวชี้"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"อนุญาตให้แอปพลิเคชันเปลี่ยนความเร็วตัวชี้ของเมาส์หรือแทร็กแพดได้ทุกเมื่อ ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"ส่งสัญญาณ Linux ไปยังแอปพลิเคชัน"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"อนุญาตให้แอปพลิเคชันร้องขอให้ส่งสัญญาณแจ้งไปยังกระบวนการที่ยังทำงานอยู่ทั้งหมด"</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"ทำให้แอปพลิเคชันทำงานเสมอ"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"แตะเพื่อปิดใช้งานการแก้ไขข้อบกพร่องของ USB"</string> <string name="select_input_method" msgid="4653387336791222978">"เลือกวิธีการป้อนข้อมูล"</string> <string name="configure_input_methods" msgid="9091652157722495116">"ตั้งค่าวิธีการป้อนข้อมูล"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"ตัวเลือก"</u></string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 2addf86..31ad6c8 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Pinapayagan ang app na baguhin ang pag-ikot ng screen anumang oras. Hindi kailanman dapat na kailanganin para sa normal na apps."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"baguhin ang bilis ng pointer"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Pinapayagan ang app na baguhin ang bilis ng mouse o trackpad pointer anumang oras. Hindi kailanman dapat na kailanganin para sa normal na apps."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"magpadala ng mga signal ng Linux sa apps"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Pinapayagan ang app na hilinging maipadala ang ibinigay na signal sa lahat ng nagpapatuloy na proseso."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"palaging patakbuhin ang app"</string> @@ -1019,8 +1023,7 @@ <string name="time_picker_dialog_title" msgid="8349362623068819295">"Magtakda ng oras"</string> <string name="date_picker_dialog_title" msgid="5879450659453782278">"Itakda ang petsa"</string> <string name="date_time_set" msgid="5777075614321087758">"Itakda"</string> - <!-- no translation found for date_time_done (2507683751759308828) --> - <skip /> + <string name="date_time_done" msgid="2507683751759308828">"Tapos na"</string> <string name="default_permission_group" msgid="2690160991405646128">"Default"</string> <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"BAGO: "</font></string> <string name="no_permissions" msgid="7283357728219338112">"Walang mga kinakailangang pahintulot"</string> @@ -1060,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Pindutin upang huwag paganahin ang pag-debug ng USB."</string> <string name="select_input_method" msgid="4653387336791222978">"Pumili ng pamamaraan ng pag-input"</string> <string name="configure_input_methods" msgid="9091652157722495116">"I-set up paraan ng pag-input"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"mga kandidato"</u></string> @@ -1170,35 +1177,22 @@ <string name="add_account_label" msgid="2935267344849993553">"Magdagdag ng account"</string> <string name="choose_account_text" msgid="6303348737197849675">"Aling account ang nais mong gamitin?"</string> <string name="add_account_button_label" msgid="3611982894853435874">"Magdagdag ng account"</string> - <!-- no translation found for number_picker_increment_button (2412072272832284313) --> - <skip /> - <!-- no translation found for number_picker_decrement_button (476050778386779067) --> - <skip /> + <string name="number_picker_increment_button" msgid="2412072272832284313">"Dagdagan"</string> + <string name="number_picker_decrement_button" msgid="476050778386779067">"Bawasan"</string> <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> pindutin nang matagal."</string> - <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) --> - <skip /> - <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) --> - <skip /> - <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) --> - <skip /> - <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) --> - <skip /> - <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) --> - <skip /> + <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Mag-slide pataas upang magdagdag at pababa upang magbawas."</string> + <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Dagdagan ang minuto"</string> + <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Bawasan ang minuto"</string> + <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Dagdagan ang oras"</string> + <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Bawasan ang oras"</string> <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Itakda ang PM"</string> <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Itakda ang AM"</string> - <!-- no translation found for date_picker_increment_month_button (5369998479067934110) --> - <skip /> - <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) --> - <skip /> - <!-- no translation found for date_picker_increment_day_button (7130465412308173903) --> - <skip /> - <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) --> - <skip /> - <!-- no translation found for date_picker_increment_year_button (6318697384310808899) --> - <skip /> - <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) --> - <skip /> + <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Dagdagan ang buwan"</string> + <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Bawasan ang buwan"</string> + <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Dagdagan ang araw"</string> + <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Bawasan ang araw"</string> + <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Dagdagdan ang taon"</string> + <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Bawasan ang taon"</string> <string name="checkbox_checked" msgid="7222044992652711167">"nilagyan ng check"</string> <string name="checkbox_not_checked" msgid="5174639551134444056">"hindi nilagyan ng check"</string> <string name="radiobutton_selected" msgid="8603599808486581511">"pinili"</string> @@ -1218,20 +1212,15 @@ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Ibahagi sa"</string> <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Ibahagi sa <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> <string name="content_description_sliding_handle" msgid="415975056159262248">"Hawakan sa pag-slide. Pindutin nang matagal."</string> - <!-- no translation found for description_direction_up (7169032478259485180) --> - <skip /> - <!-- no translation found for description_direction_down (5087739728639014595) --> - <skip /> - <!-- no translation found for description_direction_left (7207478719805562165) --> - <skip /> - <!-- no translation found for description_direction_right (8034433242579600980) --> - <skip /> + <string name="description_direction_up" msgid="7169032478259485180">"Mag-slide pataas para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_down" msgid="5087739728639014595">"Mag-slide pababa para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_left" msgid="7207478719805562165">"Mag-slide pakaliwa para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_right" msgid="8034433242579600980">"Mag-slide pakanan para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="description_target_unlock" msgid="2228524900439801453">"I-unlock"</string> <string name="description_target_camera" msgid="969071997552486814">"Camera"</string> <string name="description_target_silent" msgid="893551287746522182">"Tahimik"</string> <string name="description_target_soundon" msgid="30052466675500172">"I-on ang tunog"</string> - <!-- no translation found for description_target_search (3091587249776033139) --> - <skip /> + <string name="description_target_search" msgid="3091587249776033139">"Maghanap"</string> <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Mag-swipe upang i-unlock."</string> <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Mag-plug in ng isang headset upang marinig ang mga password key na binabanggit."</string> <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Dot."</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 29cde7d..959d8bd 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Uygulamaya, istediği zaman ekran dönüşünü değiştirme izni verir. Normal uygulamalar için gerekli değildir."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"işaretçi hızını değiştir"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Uygulamaya, istediği zaman fare veya izleme yüzeyi işaretçi hızını değiştirme izni verir. Normal uygulamalar için gerekli değildir."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"uygulamalara Linux sinyalleri gönder"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Uygulamaya, sağlanan sinyalin tüm kalıcı işlemlere gönderilmesini isteme izni verir."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"uygulamayı her zaman çalıştır"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"USB hata ayıklama özelliğini devre dışı bırakmak için dokunun."</string> <string name="select_input_method" msgid="4653387336791222978">"Giriş yöntemini seçin"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Giriş yöntemlerini ayarla"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"adaylar"</u></string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index f2ef429..f9d372e 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Дозволяє програмі будь-коли змінювати обертання екрана. Ніколи не застосовується для звичайних програм."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"змінювати швидкість указівника"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Дозволяє програмі будь-коли змінювати швидкість вказівника миші чи сенсорної панелі. Ніколи не застосовується для звичайних програм."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"надсилати сигнали Linux програмам"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Дозволяє програмі подавати запит щодо надсилання наданого сигналу всім сталим процесам."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"заставляти програму постійно функціонувати"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Торкніться, щоб вимкнути налагодження USB."</string> <string name="select_input_method" msgid="4653387336791222978">"Вибрати метод введення"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Налаштувати методи введення"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string> @@ -1173,18 +1181,18 @@ <string name="number_picker_decrement_button" msgid="476050778386779067">"Зменшити"</string> <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> – торкніться й утримуйте."</string> <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Проведіть пальцем угору, щоб збільшити, і вниз, щоб зменшити."</string> - <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Вибрати хвилину в майбутньому"</string> - <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Вибрати хвилину в минулому"</string> - <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Вибрати годину в майбутньому"</string> - <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Вибрати годину в минулому"</string> + <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"На хвилину вперед"</string> + <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"На хвилину назад"</string> + <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"На годину вперед"</string> + <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"На годину назад"</string> <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Установити час \"пп\""</string> <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Установити час \"дп\""</string> - <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Вибрати місяць у майбутньому"</string> - <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Вибрати місяць у минулому"</string> - <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Вибрати день у майбутньому"</string> - <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Вибрати день у минулому"</string> - <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Вибрати рік у майбутньому"</string> - <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Вибрати рік у минулому"</string> + <string name="date_picker_increment_month_button" msgid="5369998479067934110">"На місяць уперед"</string> + <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"На місяць назад"</string> + <string name="date_picker_increment_day_button" msgid="7130465412308173903">"На день уперед"</string> + <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"На день назад"</string> + <string name="date_picker_increment_year_button" msgid="6318697384310808899">"На рік уперед"</string> + <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"На рік назад"</string> <string name="checkbox_checked" msgid="7222044992652711167">"перевірено"</string> <string name="checkbox_not_checked" msgid="5174639551134444056">"не перевірено"</string> <string name="radiobutton_selected" msgid="8603599808486581511">"вибрано"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 94ce574..dde1ad4 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Cho phép ứng dụng thay đổi độ xoay màn hình bất cứ lúc nào. Không cần thiết cho các ứng dụng thông thường."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"thay đổi tốc độ con trỏ"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Cho phép ứng dụng thay đổi tốc độ của chuột hoặc con trỏ trên ô di chuột bất kỳ lúc nào. Không cần thiết cho các ứng dụng thông thường."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"gửi tín hiệu Linux đến ứng dụng"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Cho phép ứng dụng yêu cầu tín hiệu đã cung cấp được gửi đến tất cả các quá trình liên tục."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"đặt ứng dụng luôn chạy"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Chạm để vô hiệu hóa gỡ lỗi USB."</string> <string name="select_input_method" msgid="4653387336791222978">"Chọn phương thức nhập"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Thiết lập phương thức nhập"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"ứng viên"</u></string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index fd69a3e..0c338bb 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"允许应用随时更改屏幕的旋转状态。普通应用绝不需要此权限。"</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"更改指针速度"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"允许应用随时更改鼠标或触控板指针速度。普通应用绝不需要此权限。"</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"向应用发送 Linux 信号"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"允许应用请求将提供的信号发送给所有持续的进程。"</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"让应用始终运行"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"触摸以停用 USB 调试。"</string> <string name="select_input_method" msgid="4653387336791222978">"选择输入法"</string> <string name="configure_input_methods" msgid="9091652157722495116">"设置输入法"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"候选"</u></string> @@ -1172,7 +1180,7 @@ <string name="number_picker_increment_button" msgid="2412072272832284313">"增大"</string> <string name="number_picker_decrement_button" msgid="476050778386779067">"减小"</string> <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"触摸 <xliff:g id="VALUE">%s</xliff:g> 次并按住。"</string> - <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"向上滑动可增大值,向下滑动可减小值。"</string> + <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"向上滑动可增大数值,向下滑动可减小数值。"</string> <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"增大分钟值"</string> <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"减小分钟值"</string> <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"增大小时值"</string> @@ -1181,8 +1189,8 @@ <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"设置上午时间"</string> <string name="date_picker_increment_month_button" msgid="5369998479067934110">"增大月份值"</string> <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"减小月份值"</string> - <string name="date_picker_increment_day_button" msgid="7130465412308173903">"增大日的值"</string> - <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"减小日的值"</string> + <string name="date_picker_increment_day_button" msgid="7130465412308173903">"增大日期值"</string> + <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"减小日期值"</string> <string name="date_picker_increment_year_button" msgid="6318697384310808899">"增大年份值"</string> <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"减小年份值"</string> <string name="checkbox_checked" msgid="7222044992652711167">"已选中"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 9283fa9..c36b1b5 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"允許應用程式隨時變更螢幕旋轉狀態 (一般應用程式不需使用)。"</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"變更指標速度"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"允許應用程式隨時變更滑鼠或觸控板游標的移動速度 (一般應用程式不需使用)。"</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"將 Linux 訊號傳送給應用程式"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"允許應用程式要求將提供的訊號傳送給所有持續運作中的處理程序。"</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"一律執行應用程式"</string> @@ -1059,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"輕觸即可停用 USB 偵錯。"</string> <string name="select_input_method" msgid="4653387336791222978">"選擇輸入法"</string> <string name="configure_input_methods" msgid="9091652157722495116">"設定輸入法"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"待選項目"</u></string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 6fe919d..3b3b1e1 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -286,6 +286,10 @@ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Ivumela insiza ukuthi iguqule ukujikeleza kweskrini nganoma isiphi isikhathi. Akudingakeli izinsiza ezejwayelekile."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"guqula isivinini sesikhombi"</string> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Ivumela insiza ukuthi iguqule ijubane legundane noma lendawo yokukhomba ngomunwe. Akufanele kudingakele izinsiza ezijwayelekile."</string> + <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) --> + <skip /> + <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) --> + <skip /> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"Thumela imifanekiso ye-Linu ezinsizeni"</string> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Ivumela insiza ukuthi icele ukuthi isiginali ethunyelwe idluliselwe kuzo zonke izinqubeko ezisalelayo."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"yenza insiza ukuthi ihlale isebenza"</string> @@ -1019,8 +1023,7 @@ <string name="time_picker_dialog_title" msgid="8349362623068819295">"Hlela isikhathi"</string> <string name="date_picker_dialog_title" msgid="5879450659453782278">"Setha idethi"</string> <string name="date_time_set" msgid="5777075614321087758">"Hlela"</string> - <!-- no translation found for date_time_done (2507683751759308828) --> - <skip /> + <string name="date_time_done" msgid="2507683751759308828">"Kwenziwe"</string> <string name="default_permission_group" msgid="2690160991405646128">"Okuzenzakalelayo"</string> <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"OKUSHA: "</font></string> <string name="no_permissions" msgid="7283357728219338112">"Ayikho imvume edingekayo"</string> @@ -1060,6 +1063,10 @@ <string name="adb_active_notification_message" msgid="1016654627626476142">"Thinta ukwenza ukuthi ukudibhaga kwe-USB kungasebenzi."</string> <string name="select_input_method" msgid="4653387336791222978">"Khetha indlela yokufaka"</string> <string name="configure_input_methods" msgid="9091652157722495116">"Izilungiselelo zezindlela zokufakwayo"</string> + <!-- no translation found for use_physical_keyboard (6203112478095117625) --> + <skip /> + <!-- no translation found for hardware (7517821086888990278) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"abahlanganyeli"</u></string> @@ -1170,35 +1177,22 @@ <string name="add_account_label" msgid="2935267344849993553">"Yengeza i-akhawunti"</string> <string name="choose_account_text" msgid="6303348737197849675">"Ingabe iyiphi i-akhawunti ofuna ukuyisebenzisa?"</string> <string name="add_account_button_label" msgid="3611982894853435874">"Engeza i-akhawunti"</string> - <!-- no translation found for number_picker_increment_button (2412072272832284313) --> - <skip /> - <!-- no translation found for number_picker_decrement_button (476050778386779067) --> - <skip /> + <string name="number_picker_increment_button" msgid="2412072272832284313">"Khulisa"</string> + <string name="number_picker_decrement_button" msgid="476050778386779067">"Yehlisa"</string> <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> thinta bese ucindezela."</string> - <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) --> - <skip /> - <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) --> - <skip /> - <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) --> - <skip /> - <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) --> - <skip /> - <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) --> - <skip /> + <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Shelelisela phezulu ukuze ungeze futhi phansi ukuze wehlise."</string> + <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Khulisa iminithi"</string> + <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Yehlisa iminithi"</string> + <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Khulisa ihora"</string> + <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Yehlisa ihora"</string> <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Setha Ntambama"</string> <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Setha Ekuseni"</string> - <!-- no translation found for date_picker_increment_month_button (5369998479067934110) --> - <skip /> - <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) --> - <skip /> - <!-- no translation found for date_picker_increment_day_button (7130465412308173903) --> - <skip /> - <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) --> - <skip /> - <!-- no translation found for date_picker_increment_year_button (6318697384310808899) --> - <skip /> - <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) --> - <skip /> + <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Khulisa inyanga"</string> + <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Yehlisa inyanga"</string> + <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Khulisa usuku"</string> + <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Yehlisa usuku"</string> + <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Khulisa unyaka"</string> + <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Yehlisa unyaka"</string> <string name="checkbox_checked" msgid="7222044992652711167">"kuhloliwe"</string> <string name="checkbox_not_checked" msgid="5174639551134444056">"akuhloliwe"</string> <string name="radiobutton_selected" msgid="8603599808486581511">"Okukhethiwe"</string> @@ -1218,20 +1212,15 @@ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Yabelana no"</string> <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Yabelana no <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> <string name="content_description_sliding_handle" msgid="415975056159262248">"Ihaambis isibambo. Thinta & ubambe."</string> - <!-- no translation found for description_direction_up (7169032478259485180) --> - <skip /> - <!-- no translation found for description_direction_down (5087739728639014595) --> - <skip /> - <!-- no translation found for description_direction_left (7207478719805562165) --> - <skip /> - <!-- no translation found for description_direction_right (8034433242579600980) --> - <skip /> + <string name="description_direction_up" msgid="7169032478259485180">"Shelelisela ngenhla ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_down" msgid="5087739728639014595">"Shelelisela ngezansi ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_left" msgid="7207478719805562165">"Shelelisela ngakwesokunxele ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> + <string name="description_direction_right" msgid="8034433242579600980">"Shelelisela ngakwesokudla ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="description_target_unlock" msgid="2228524900439801453">"Vula"</string> <string name="description_target_camera" msgid="969071997552486814">"Ikhamera"</string> <string name="description_target_silent" msgid="893551287746522182">"Thulile"</string> <string name="description_target_soundon" msgid="30052466675500172">"Umsindo uvuliwe"</string> - <!-- no translation found for description_target_search (3091587249776033139) --> - <skip /> + <string name="description_target_search" msgid="3091587249776033139">"Sesha"</string> <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Swayipha ukuze uvule."</string> <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Plaka ku-headset ukuze uzwe okhiye bephasiwedi ezindlebeni zakho bezwakala kakhulu."</string> <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Icashazi."</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index e80e30a..acf63a1 100755 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -323,8 +323,9 @@ true here reverses that logic. --> <bool name="config_reverseDefaultRotation">false</bool> - <!-- The number of degrees to rotate the display when the keyboard is open. --> - <integer name="config_lidOpenRotation">90</integer> + <!-- The number of degrees to rotate the display when the keyboard is open. + A value of -1 means no change in orientation by default. --> + <integer name="config_lidOpenRotation">-1</integer> <!-- The number of degrees to rotate the display when the device is in a desk dock. A value of -1 means no change in orientation by default. --> @@ -370,8 +371,8 @@ <!-- Indicate whether the lid state impacts the accessibility of the physical keyboard. 0 means it doesn't, 1 means it is accessible when the lid is open, 2 means it is accessible when the lid is - closed. The default is 1. --> - <integer name="config_lidKeyboardAccessibility">1</integer> + closed. The default is 0. --> + <integer name="config_lidKeyboardAccessibility">0</integer> <!-- Indicate whether the lid state impacts the accessibility of the physical keyboard. 0 means it doesn't, 1 means it is accessible @@ -817,7 +818,7 @@ <bool name="config_allowActionMenuItemTextWithIcon">false</bool> <!-- Remote server that can provide NTP responses. --> - <string translatable="false" name="config_ntpServer">pool.ntp.org</string> + <string translatable="false" name="config_ntpServer">2.android.pool.ntp.org</string> <!-- Timeout to wait for NTP server response. --> <integer name="config_ntpTimeout">20000</integer> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index cbfc1a4..aaef701 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -85,6 +85,8 @@ <java-symbol type="id" name="fillInIntent" /> <java-symbol type="id" name="find" /> <java-symbol type="id" name="fullscreenArea" /> + <java-symbol type="id" name="hard_keyboard_section" /> + <java-symbol type="id" name="hard_keyboard_switch" /> <java-symbol type="id" name="headers" /> <java-symbol type="id" name="hour" /> <java-symbol type="id" name="icon" /> @@ -1042,6 +1044,7 @@ <java-symbol type="layout" name="icon_menu_layout" /> <java-symbol type="layout" name="input_method" /> <java-symbol type="layout" name="input_method_extract_view" /> + <java-symbol type="layout" name="input_method_switch_dialog_title" /> <java-symbol type="layout" name="js_prompt" /> <java-symbol type="layout" name="list_content_simple" /> <java-symbol type="layout" name="list_menu_item_checkbox" /> @@ -1449,6 +1452,7 @@ <java-symbol type="string" name="factorytest_no_action" /> <java-symbol type="string" name="factorytest_not_system" /> <java-symbol type="string" name="factorytest_reboot" /> + <java-symbol type="string" name="hardware" /> <java-symbol type="string" name="heavy_weight_notification" /> <java-symbol type="string" name="heavy_weight_notification_detail" /> <java-symbol type="string" name="input_method_binding_label" /> @@ -1471,6 +1475,7 @@ <java-symbol type="string" name="usb_cd_installer_notification_title" /> <java-symbol type="string" name="usb_mtp_notification_title" /> <java-symbol type="string" name="usb_notification_message" /> + <java-symbol type="string" name="use_physical_keyboard" /> <java-symbol type="string" name="usb_ptp_notification_title" /> <java-symbol type="string" name="vpn_text" /> <java-symbol type="string" name="vpn_text_long" /> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 44f2ade..0eb46bd 100755 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -768,6 +768,12 @@ the mouse or trackpad pointer speed at any time. Should never be needed for normal apps.</string> + <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=30] --> + <string name="permlab_setKeyboardLayout">change keyboard layout</string> + <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE] --> + <string name="permdesc_setKeyboardLayout">Allows the app to change + the keyboard layout. Should never be needed for normal apps.</string> + <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permlab_signalPersistentProcesses">send Linux signals to apps</string> <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> @@ -2921,6 +2927,10 @@ <string name="select_input_method">Choose input method</string> <!-- Title of a button to open the settings for input methods [CHAR LIMIT=30] --> <string name="configure_input_methods">Set up input methods</string> + <!-- Summary text of a toggle switch to enable/disable use of the physical keyboard in the input method selector [CHAR LIMIT=25] --> + <string name="use_physical_keyboard">Physical keyboard</string> + <!-- Title of the physical keyboard category in the input method selector [CHAR LIMIT=10] --> + <string name="hardware">Hardware</string> <string name="fast_scroll_alphabet">\u0020ABCDEFGHIJKLMNOPQRSTUVWXYZ</string> <string name="fast_scroll_numeric_alphabet">\u00200123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ</string> diff --git a/docs/html/guide/topics/renderscript/index.jd b/docs/html/guide/topics/renderscript/index.jd index 24b9750..b2d9f84 100644 --- a/docs/html/guide/topics/renderscript/index.jd +++ b/docs/html/guide/topics/renderscript/index.jd @@ -638,8 +638,10 @@ not generated.</p> <code>rs_program_fragment</code> and <code>rs_allocation</code>, you have to obtain an object of the corresponding Android framework class first and then call the <code>set</code> method for that structure to bind the memory to the Renderscript runtime. You cannot directly manipulate these structures -at the Renderscript runtime layer. Keep in mind that user-defined structures -cannot contain pointers, so this restriction only applies to certain structures that are provided by Renderscript. +at the Renderscript runtime layer. This restriction is not applicable to user-defined structures +that contain pointers, because they cannot be exported to a reflected layer class +in the first place. A compiler error is generated if you try to declare a non-static, global +struct that contains a pointer. </p> <p>Renderscript also has support for pointers, but you must explicitly allocate the memory in your diff --git a/docs/html/guide/topics/wireless/wifip2p.jd b/docs/html/guide/topics/wireless/wifip2p.jd index ec8e71e..82c9abd 100644 --- a/docs/html/guide/topics/wireless/wifip2p.jd +++ b/docs/html/guide/topics/wireless/wifip2p.jd @@ -491,10 +491,10 @@ manager.connect(channel, config, new ActionListener() { </ol> <p>The following example, modified from the <a href= - "{@docRoot}resources/samples/WifiDirectDemo/index.html">Wi-Fi Direct Demo</a> sample, shows you how + "{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi Direct Demo</a> sample, shows you how to create this client-server socket communication and transfer JPEG images from a client to a server with a service. For a complete working example, compile and run the <a href= - "{@docRoot}resources/samples/WifiDirectDemo/index.html">Wi-Fi Direct Demo</a> sample.</p> + "{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi Direct Demo</a> sample.</p> <pre> public static class FileServerAsyncTask extends AsyncTask<Void, Void, String> { diff --git a/docs/html/images/training/basics/intents-choice.png b/docs/html/images/training/basics/intents-choice.png Binary files differnew file mode 100644 index 0000000..f99596d --- /dev/null +++ b/docs/html/images/training/basics/intents-choice.png diff --git a/docs/html/sdk/ndk/overview.jd b/docs/html/sdk/ndk/overview.jd index c98e600..d2a9746 100644 --- a/docs/html/sdk/ndk/overview.jd +++ b/docs/html/sdk/ndk/overview.jd @@ -270,11 +270,11 @@ page.title=What is the NDK? <ul> <li>If you are developing in Eclipse with ADT, use the New Project Wizard to create a new Android project for each sample, using the "Import from Existing Source" option and importing - the source from <code><ndk>/apps/<app_name>/project/</code>. Then, set up an AVD, + the source from <code><ndk>/samples/<name>/</code>. Then, set up an AVD, if necessary, and build/run the application in the emulator.</li> <li>If you are developing with Ant, use the <code>android</code> tool to create the build file - for each of the sample projects at <code><ndk>/apps/<app_name>/project/</code>. + for each of the sample projects at <code><ndk>/samples/<name>/</code>. Then set up an AVD, if necessary, build your project in the usual way, and run it in the emulator.</li> diff --git a/docs/html/training/basics/intents/filters.jd b/docs/html/training/basics/intents/filters.jd new file mode 100644 index 0000000..0090c98 --- /dev/null +++ b/docs/html/training/basics/intents/filters.jd @@ -0,0 +1,244 @@ +page.title=Allowing Other Apps to Start Your Activity +parent.title=Interacting with Other Apps +parent.link=index.html + +trainingnavtop=true +previous.title=Getting a Result from an Activity +previous.link=result.html + +@jd:body + +<div id="tb-wrapper"> + <div id="tb"> + +<h2>This lesson teaches you to</h2> +<ol> + <li><a href="#AddIntentFilter">Add an Intent Filter</a></li> + <li><a href="#HandleIntent">Handle the Intent in Your Activity</a></li> + <li><a href="#ReturnResult">Return a Result</a></li> +</ol> + +<h2>You should also read</h2> +<ul> + <li><a href="{@docRoot}training/sharing/index.html">Sharing Content</a></li> +</ul> + </div> +</div> + +<p>The previous two lessons focused on one side of the story: starting another app's activity from +your app. But if your app can perform an action that might be useful to another app, +your app should be prepared to respond to action requests from other apps. For instance, if you +build a social app that can share messages or photos with the user's friends, it's in your best +interest to support the {@link android.content.Intent#ACTION_SEND} intent so users can initiate a +"share" action from another app and launch your app to perform the action.</p> + +<p>To allow other apps to start your activity, you need to add an <a +href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code <intent-filter>}</a> +element in your manifest file for the corresponding <a +href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> element.</p> + +<p>When your app is installed on a device, the system identifies your intent +filters and adds the information to an internal catalog of intents supported by all installed apps. +When an app calls {@link android.app.Activity#startActivity +startActivity()} or {@link android.app.Activity#startActivityForResult startActivityForResult()}, +with an implicit intent, the system finds which activity (or activities) can respond to the +intent.</p> + + + +<h2 id="AddIntentFilter">Add an Intent Filter</h2> + +<p>In order to properly define which intents your activity can handle, each intent filter you add +should be as specific as possible in terms of the type of action and data the activity +accepts.</p> + +<p>The system may send a given {@link android.content.Intent} to an activity if that activity has +an intent filter fulfills the following criteria of the {@link android.content.Intent} object:</p> + +<dl> + <dt>Action</dt> + <dd>A string naming the action to perform. Usually one of the platform-defined values such +as {@link android.content.Intent#ACTION_SEND} or {@link android.content.Intent#ACTION_VIEW}. + <p>Specify this in your intent filter with the <a +href="{@docRoot}guide/topics/manifest/action-element.html">{@code <action>}</a> element. +The value you specify in this element must be the full string name for the action, instead of the +API constant (see the examples below).</p></dd> + + <dt>Data</dt> + <dd>A description of the data associated with the intent. + <p>Specify this in your intent filter with the <a +href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a> element. Using one +or more attributes in this element, you can specify just the MIME type, just a URI prefix, +just a URI scheme, or a combination of these and others that indicate the data type +accepted.</p> + <p class="note"><strong>Note:</strong> If you don't need to declare specifics about the data +{@link android.net.Uri} (such as when your activity handles to other kind of "extra" data, instead +of a URI), you should specify only the {@code android:mimeType} attribute to declare the type of +data your activity handles, such as {@code text/plain} or {@code image/jpeg}.</p> +</dd> + <dt>Category</dt> + <dd>Provides an additional way to characterize the activity handling the intent, usually related +to the user gesture or location from which it's started. There are several different categories +supported by the system, but most are rarely used. However, all implicit intents are defined with +{@link android.content.Intent#CATEGORY_DEFAULT} by default. + <p>Specify this in your intent filter with the <a +href="{@docRoot}guide/topics/manifest/category-element.html">{@code <category>}</a> +element.</p></dd> +</dl> + +<p>In your intent filter, you can declare which criteria your activity accepts +by declaring each of them with corresponding XML elements nested in the <a +href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code <intent-filter>}</a> +element.</p> + +<p>For example, here's an activity with an intent filter that handles the {@link +android.content.Intent#ACTION_SEND} intent when the data type is either text or an image:</p> + +<pre> +<activity android:name="ShareActivity"> + <intent-filter> + <action android:name="android.intent.action.SEND"/> + <category android:name="android.intent.category.DEFAULT"/> + <data android:mimeType="text/plain"/> + <data android:mimeType="image/*"/> + </intent-filter> +</activity> +</pre> + +<p>Each incoming intent specifies only one action and one data type, but it's OK to declare multiple +instances of the <a href="{@docRoot}guide/topics/manifest/action-element.html">{@code +<action>}</a>, <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code +<category>}</a>, and <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code +<data>}</a> elements in each +<a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code +<intent-filter>}</a>.</p> + +<p>If any two pairs of action and data are mutually exclusive in +their behaviors, you should create separate intent filters to specify which actions are acceptable +when paired with which data types.</p> + +<p>For example, suppose your activity handles both text and images for both the {@link +android.content.Intent#ACTION_SEND} and {@link +android.content.Intent#ACTION_SENDTO} intents. In this case, you must define two separate +intent filters for the two actions because a {@link +android.content.Intent#ACTION_SENDTO} intent must use the data {@link android.net.Uri} to specify +the recipient's address using the {@code send} or {@code sendto} URI scheme. For example:</p> + +<pre> +<activity android:name="ShareActivity"> + <!-- filter for sending text; accepts SENDTO action with sms URI schemes --> + <intent-filter> + <action android:name="android.intent.action.SENDTO"/> + <category android:name="android.intent.category.DEFAULT"/> + <data android:scheme="sms" /> + <data android:scheme="smsto" /> + </intent-filter> + <!-- filter for sending text or images; accepts SEND action and text or image data --> + <intent-filter> + <action android:name="android.intent.action.SEND"/> + <category android:name="android.intent.category.DEFAULT"/> + <data android:mimeType="image/*"/> + <data android:mimeType="text/plain"/> + </intent-filter> +</activity> +</pre> + +<p class="note"><strong>Note:</strong> In order to receive implicit intents, you must include the +{@link android.content.Intent#CATEGORY_DEFAULT} category in the intent filter. The methods {@link +android.app.Activity#startActivity startActivity()} and {@link +android.app.Activity#startActivityForResult startActivityForResult()} treat all intents as if they +contained the {@link android.content.Intent#CATEGORY_DEFAULT} category. If you do not declare it, no +implicit intents will resolve to your activity.</p> + +<p>For more information about sending and receiving {@link android.content.Intent#ACTION_SEND} +intents that perform social sharing behaviors, see the lesson about <a +href="{@docRoot}training/sharing/receive.html">Receiving Content from Other Apps</a>.</p> + + +<h2 id="HandleIntent">Handle the Intent in Your Activity</h2> + +<p>In order to decide what action to take in your activity, you can read the {@link +android.content.Intent} that was used to start it.</p> + +<p>As your activity starts, call {@link android.app.Activity#getIntent()} to retrieve the +{@link android.content.Intent} that started the activity. You can do so at any time during the +lifecycle of the activity, but you should generally do so during early callbacks such as +{@link android.app.Activity#onCreate onCreate()} or {@link android.app.Activity#onStart()}.</p> + +<p>For example:</p> + +<pre> +@Override +protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.main); + + // Get the intent that started this activity + Intent intent = getIntent(); + Uri data = intent.getData(); + + // Figure out what to do based on the intent type + if (intent.getType().indexOf("image/") != -1) { + // Handle intents with image data ... + } else if (intent.getType().equals("text/plain")) { + // Handle intents with text ... + } +} +</pre> + + +<h2 id="ReturnResult">Return a Result</h2> + +<p>If you want to return a result to the activity that invoked yours, simply call {@link +android.app.Activity#setResult(int,Intent) setResult()} to specify the result code and result {@link +android.content.Intent}. When your operation is done and the user should return to the original +activity, call {@link android.app.Activity#finish()} to close (and destroy) your activity. For +example:</p> + +<pre> +// Create intent to deliver some kind of result data +Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri"); +setResult(Activity.RESULT_OK, result); +finish(); +</pre> + +<p>You must always specify a result code with the result. Generally, it's either {@link +android.app.Activity#RESULT_OK} or {@link android.app.Activity#RESULT_CANCELED}. You can then +provide additional data with an {@link android.content.Intent}, as necessary.</p> + +<p class="note"><strong>Note:</strong> The result is set to {@link +android.app.Activity#RESULT_CANCELED} by default. So, if the user presses the <em>Back</em> +button before completing the action and before you set the result, the original activity receives +the "canceled" result.</p> + +<p>If you simply need to return an integer that indicates one of several result options, you can set +the result code to any value higher than 0. If you use the result code to deliver an integer and you +have no need to include the {@link android.content.Intent}, you can call {@link +android.app.Activity#setResult(int) setResult()} and pass only a result code. For example:</p> + +<pre> +setResult(RESULT_COLOR_RED); +finish(); +</pre> + +<p>In this case, there might be only a handful of possible results, so the result code is a locally +defined integer (greater than 0). This works well when you're returning a result to an activity +in your own app, because the activity that receives the result can reference the public +constant to determine the value of the result code.</p> + +<p class="note"><strong>Note:</strong> There's no need to check whether your activity was started +with {@link +android.app.Activity#startActivity startActivity()} or {@link +android.app.Activity#startActivityForResult startActivityForResult()}. Simply call {@link +android.app.Activity#setResult(int,Intent) setResult()} if the intent that started your activity +might expect a result. If the originating activity had called {@link +android.app.Activity#startActivityForResult startActivityForResult()}, then the system delivers it +the result you supply to {@link android.app.Activity#setResult(int,Intent) setResult()}; otherwise, +the result is ignored.</p> + + + + + + diff --git a/docs/html/training/basics/intents/index.jd b/docs/html/training/basics/intents/index.jd new file mode 100644 index 0000000..c661d98 --- /dev/null +++ b/docs/html/training/basics/intents/index.jd @@ -0,0 +1,64 @@ +page.title=Interacting with Other Apps + +trainingnavtop=true +startpage=true +next.title=Sending the User to Another App +next.link=sending.html + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + +<h2>Dependencies and prerequisites</h2> +<ul> + <li>Basic understanding of the Activity lifecycle (see <a +href="{@docRoot}training/basics/activity-lifecycle/index.html">Managing the Activity +Lifecycle</a>)</li> +</ul> + + +<h2>You should also read</h2> +<ul> + <li><a href="{@docRoot}training/sharing/index.html">Sharing Content</a></li> + <li><a +href="http://android-developers.blogspot.com/2009/11/integrating-application-with-intents.html"> +Integrating Application with Intents (blog post)</a></li> + <li><a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent +Filters</a></li> +</ul> + +</div> +</div> + +<p>An Android app typically has several <a +href="{@docRoot}guide/topics/fundamentals/activities.html">activities</a>. Each activity displays a +user interface that allows the user to perform a specific task (such as view a map or take a photo). +To take the user from one activity to another, your app must use an {@link +android.content.Intent} to define your app's "intent" to do something. When you pass an +{@link android.content.Intent} to the system with a method such as {@link +android.app.Activity#startActivity startActivity()}, the system uses the {@link +android.content.Intent} to identify and start the appropriate app component. Using intents even +allows your app to start an activity that is contained in a separate app.</p> + +<p>An {@link android.content.Intent} can be <em>explicit</em> in order to start a specific component +(a specific {@link android.app.Activity} instance) or <em>implicit</em> in order to start any +component that can handle the intended action (such as "capture a photo").</p> + +<p>This class shows you how to use an {@link android.content.Intent} to perform some basic +interactions with other apps, such as start another app, receive a result from that app, and +make your app able to respond to intents from other apps.</p> + +<h2>Lessons</h2> + +<dl> + <dt><b><a href="sending.html">Sending the User to Another App</a></b></dt> + <dd>Shows how you can create implicit intents to launch other apps that can perform an +action.</dd> + <dt><b><a href="result.html">Getting a Result from an Activity</a></b></dt> + <dd>Shows how to start another activity and receive a result from the activity.</dd> + <dt><b><a href="filters.html">Allowing Other Apps to Start Your Activity</a></b></dt> + <dd>Shows how to make activities in your app open for use by other apps by defining +intent filters that declare the implicit intents your app accepts.</dd> +</dl> + diff --git a/docs/html/training/basics/intents/result.jd b/docs/html/training/basics/intents/result.jd new file mode 100644 index 0000000..0086913 --- /dev/null +++ b/docs/html/training/basics/intents/result.jd @@ -0,0 +1,182 @@ +page.title=Getting a Result from an Activity +parent.title=Interacting with Other Apps +parent.link=index.html + +trainingnavtop=true +previous.title=Sending the User to Another App +previous.link=sending.html +next.title=Allowing Other Apps to Start Your Activity +next.link=filters.html + +@jd:body + +<div id="tb-wrapper"> + <div id="tb"> + +<h2>This lesson teaches you to</h2> +<ol> + <li><a href="#StartActivity">Start the Activity</a></li> + <li><a href="#ReceiveResult">Receive the Result</a></li> +</ol> + +<h2>You should also read</h2> +<ul> + <li><a href="{@docRoot}training/sharing/index.html">Sharing Content</a></li> +</ul> + + </div> +</div> + +<p>Starting another activity doesn't have to be one-way. You can also start another activity and +receive a result back. To receive a result, call {@link android.app.Activity#startActivityForResult +startActivityForResult()} (instead of {@link android.app.Activity#startActivity +startActivity()}).</p> + +<p>For example, your app can start a camera app and receive the captured photo as a result. Or, you +might start the People app in order for the user to select a +contact and you'll receive the contact details as a result.</p> + +<p>Of course, the activity that responds must be designed to return a result. When it does, it +sends the result as another {@link android.content.Intent} object. Your activity receives it in +the {@link android.app.Activity#onActivityResult onActivityResult()} callback.</p> + +<p class="note"><strong>Note:</strong> You can use explicit or implicit intents when you call +{@link android.app.Activity#startActivityForResult startActivityForResult()}. When starting one of +your own activities to receive a result, you should use an explicit intent to ensure that you +receive the expected result.</p> + + +<h2 id="StartActivity">Start the Activity</h2> + +<p>There's nothing special about the {@link android.content.Intent} object you use when starting +an activity for a result, but you do need to pass an additional integer argument to the {@link +android.app.Activity#startActivityForResult startActivityForResult()} method.</p> + +<p>The integer argument is a "request code" that identifies your request. When you receive the +result {@link android.content.Intent}, the callback provides the same request code so that your +app can properly identify the result and determine how to handle it.</p> + +<p>For example, here's how to start an activity that allows the user to pick a contact:</p> + +<pre> +static final int PICK_CONTACT_REQUEST = 1; // The request code +... +private void pickContact() { + Intent pickContactIntent = new Intent(Intent.ACTION_PICK, new Uri("content://contacts")); + pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers + startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST); +} +</pre> + + +<h2 id="ReceiveResult">Receive the Result</h2> + +<p>When the user is done with the subsequent activity and returns, the system calls your activity's +{@link android.app.Activity#onActivityResult onActivityResult()} method. This method includes three +arguments:</p> + +<ul> + <li>The request code you passed to {@link +android.app.Activity#startActivityForResult startActivityForResult()}.</li> + <li>A result code specified by the second activity. This is either {@link +android.app.Activity#RESULT_OK} if the operation was successful or {@link +android.app.Activity#RESULT_CANCELED} if the user backed out or the operation failed for some +reason.</li> + <li>An {@link android.content.Intent} that carries the result data.</li> +</ul> + +<p>For example, here's how you can handle the result for the "pick a contact" intent:</p> + +<pre> +@Override +protected void onActivityResult(int requestCode, int resultCode, Intent data) { + // Check which request we're responding to + if (requestCode == PICK_CONTACT_REQUEST) { + // Make sure the request was successful + if (resultCode == RESULT_OK) { + // The user picked a contact. + // The Intent's data Uri identifies which contact was selected. + + // Do something with the contact here (bigger example below) + } + } +} +</pre> + +<p>In this example, the result {@link android.content.Intent} returned by +Android's Contacts or People app provides a content {@link android.net.Uri} that identifies the +contact the user selected.</p> + +<p>In order to successfully handle the result, you must understand what the format of the result +{@link android.content.Intent} will be. Doing so is easy when the activity returning a result is +one of your own activities. Apps included with the Android platform offer their own APIs that +you can count on for specific result data. For instance, the People app (Contacts app on some older +versions) always returns a result with the content URI that identifies the selected contact, and the +Camera app returns a {@link android.graphics.Bitmap} in the {@code "data"} extra (see the class +about <a href="{@docRoot}training/camera/index.html">Capturing Photos</a>).</p> + + +<h4>Bonus: Read the contact data</h4> + +<p>The code above showing how to get a result from the People app doesn't go into +details about how to actually read the data from the result, because it requires more advanced +discussion about <a href="{@docRoot}guide/topics/providers/content-providers.html">content +providers</a>. However, if you're curious, here's some more code that shows how to query the +result data to get the phone number from the selected contact:</p> + +<pre> +@Override +protected void onActivityResult(int requestCode, int resultCode, Intent data) { + // Check which request it is that we're responding to + if (requestCode == PICK_CONTACT_REQUEST) { + // Make sure the request was successful + if (resultCode == RESULT_OK) { + // Get the URI that points to the selected contact + Uri contactUri = data.getData(); + // We only need the NUMBER column, because there will be only one row in the result + String[] projection = {Phone.NUMBER}; + + // Perform the query on the contact to get the NUMBER column + // We don't need a selection or sort order (there's only one result for the given URI) + // CAUTION: The query() method should be called from a separate thread to avoid blocking + // your app's UI thread. (For simplicity of the sample, this code doesn't do that.) + // Consider using {@link android.content.CursorLoader} to perform the query. + Cursor cursor = getContentResolver() + .query(contactUri, projection, null, null, null); + cursor.moveToFirst(); + + // Retrieve the phone number from the NUMBER column + int column = cursor.getColumnIndex(Phone.NUMBER); + String number = cursor.getString(column); + + // Do something with the phone number... + } + } +} +</pre> + +<p class="note"><strong>Note:</strong> Before Android 2.3 (API level 9), performing a query +on the {@link android.provider.ContactsContract.Contacts Contacts Provider} (like the one shown +above) requires that your app declare the {@link +android.Manifest.permission#READ_CONTACTS} permission (see <a +href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a>). However, +beginning with Android 2.3, the Contacts/People app grants your app a temporary +permission to read from the Contacts Provider when it returns you a result. The temporary permission +applies only to the specific contact requested, so you cannot query a contact other than the one +specified by the intent's {@link android.net.Uri}, unless you do declare the {@link +android.Manifest.permission#READ_CONTACTS} permission.</p> + + + + + + + + + + + + + + + diff --git a/docs/html/training/basics/intents/sending.jd b/docs/html/training/basics/intents/sending.jd new file mode 100644 index 0000000..a71c8f9 --- /dev/null +++ b/docs/html/training/basics/intents/sending.jd @@ -0,0 +1,211 @@ +page.title=Sending the User to Another App +parent.title=Interacting with Other Apps +parent.link=index.html + +trainingnavtop=true +next.title=Getting a Result from an Activity +next.link=result.html + +@jd:body + + +<div id="tb-wrapper"> + <div id="tb"> + +<h2>This lesson teaches you to</h2> +<ol> + <li><a href="#Build">Build an Implicit Intent</a></li> + <li><a href="#Verify">Verify There is an App to Receive the Intent</a></li> + <li><a href="#StartActivity">Start an Activity with the Intent</a></li> +</ol> + +<h2>You should also read</h2> +<ul> + <li><a href="{@docRoot}training/sharing/index.html">Sharing Content</a></li> +</ul> + + </div> +</div> + +<p>One of Android's most important features is an app's ability to send the user to another app +based on an "action" it would like to perform. For example, if +your app has the address of a business that you'd like to show on a map, you don't have to build +an activity in your app that shows a map. Instead, you can send a out a request to view the address +using an {@link android.content.Intent}. The Android system then starts an app that's able to view +the address on a map.</p> + +<p>As shown in the first class, <a href="{@docRoot}training/basics/firstapp/index.html">Building +Your First App</a>, you must use intents to navigate between activities in your own app. You +generally do so with an <em>explicit intent</em>, which defines the exact class name of the +component you want to start. However, when you want to have a separate app perform an action, such +as "view a map," you must use an <em>implicit intent</em>.</p> + +<p>This lesson shows you how to create an implicit intent for a particular action, and how to use it +to start an activity that performs the action in another app.</p> + + + +<h2 id="Build">Build an Implicit Intent</h2> + +<p>Implicit intents do not declare the class name of the component to start, but instead declare an +action to perform. The action specifies the thing you want to do, such as <em>view</em>, +<em>edit</em>, <em>send</em>, or <em>get</em> something. Intents often also include data associated +with the action, such as the address you want to view, or the email message you want to send. +Depending on the intent you want to create, the data might be a {@link android.net.Uri}, +one of several other data types, or the intent might not need data at all.</p> + +<p>If your data is a {@link android.net.Uri}, there's a simple {@link +android.content.Intent#Intent(String,Uri) Intent()} constructor you can use define the action and +data.</p> + +<p>For example, here's how to create an intent to initiate a phone call using the {@link +android.net.Uri} data to specify the telephone number:</p> + +<pre> +Uri number = Uri.parse("tel:5551234"); +Intent callIntent = new Intent(Intent.ACTION_DIAL, number); +</pre> + +<p>When your app invokes this intent by calling {@link android.app.Activity#startActivity +startActivity()}, the Phone app initiates a call to the given phone number.</p> + +<p>Here are a couple other intents and their action and {@link android.net.Uri} data +pairs:</p> + +<ul> + <li>View a map: +<pre> +// Map point based on address +Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California"); +// Or map point based on latitude/longitude +// Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level +Intent mapIntent = new Intent(Intent.ACTION_VIEW, location); +</pre> + </li> + <li>View a web page: +<pre> +Uri webpage = Uri.parse("http://www.android.com"); +Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage); +</pre> + </li> +</ul> + +<p>Other kinds of implicit intents require "extra" data that provide different data types, +such as a string. You can add one or more pieces of extra data using the various {@link +android.content.Intent#putExtra(String,String) putExtra()} methods.</p> + +<p>By default, the system determines the appropriate MIME type required by an intent based on the +{@link android.net.Uri} data that's included. If you don't include a {@link android.net.Uri} in the +intent, you should usually use {@link android.content.Intent#setType setType()} to specify the type +of data associated with the intent. Setting the MIME type further specifies which kinds of +activities should receive the intent.</p> + +<p>Here are some more intents that add extra data to specify the desired action:</p> + +<ul> + <li>Send an email with an attachment: +<pre> +Intent emailIntent = new Intent(Intent.ACTION_SEND); +// The intent does not have a URI, so declare the "text/plain" MIME type +emailIntent.setType(HTTP.PLAIN_TEXT_TYPE); +emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // recipients +emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject"); +emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text"); +emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment"); +// You can also attach multiple items by passing an ArrayList of Uris +</pre> + </li> + <li>Create a calendar event: +<pre> +Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI); +Calendar beginTime = Calendar.getInstance().set(2012, 0, 19, 7, 30); +Calendar endTime = Calendar.getInstance().set(2012, 0, 19, 10, 30); +calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis()); +calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis()); +calendarIntent.putExtra(Events.TITLE, "Ninja class"); +calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo"); +</pre> +<p class="note"><strong>Note:</strong> This intent for a calendar event is supported only with API +level 14 and higher.</p> + </li> +</ul> + +<p class="note"><strong>Note:</strong> It's important that you define your {@link +android.content.Intent} to be as specific as possible. For example, if you want to display an image +using the {@link android.content.Intent#ACTION_VIEW} intent, you should specify a MIME type of +{@code image/*}. This prevents apps that can "view" other types of data (like a map app) from being +triggered by the intent.</p> + + + +<h2 id="Verify">Verify There is an App to Receive the Intent</h2> + +<p>Although the Android platform guarantees that certain intents will resolve to one of the +built-in apps (such as the Phone, Email, or Calendar app), you should always include a +verification step before invoking an intent.</p> + +<p class="caution"><strong>Caution:</strong> If you invoke an intent and there is no app +available on the device that can handle the intent, your app will crash.</p> + +<p>To verify there is an activity available that can respond to the intent, call {@link +android.content.pm.PackageManager#queryIntentActivities queryIntentActivities()} to get a list +of activities capable of handling your {@link android.content.Intent}. If the returned {@link +java.util.List} is not empty, you can safely use the intent. For example:</p> + +<pre> +PackageManager packageManager = {@link android.content.Context#getPackageManager()}; +List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0); +boolean isIntentSafe = activities.size() > 0; +</pre> + +<p>If <code>isIntentSafe</code> is <code>true</code>, then at least one app will respond to +the intent. If it is <code>false</code>, then there aren't any apps to handle the intent.</p> + +<p class="note"><strong>Note:</strong> You should perform this check when your activity first +starts in case you need to disable the feature that uses the intent before the user attempts to use +it. If you know of a specific app that can handle the intent, you can also provide a link for the +user to download the app (see how to <a +href="{@docRoot}guide/publishing/publishing.html#marketintent">link to an app on Google +Play</a>).</p> + + +<h2 id="StartActivity">Start an Activity with the Intent</h2> + +<div class="figure" style="width:200px"> + <img src="{@docRoot}images/training/basics/intents-choice.png" alt="" /> + <p class="img-caption"><strong>Figure 1.</strong> Example of the selection dialog that appears +when more than one app can handle an intent.</p> +</div> + +<p>Once you have created your {@link android.content.Intent} and set the extra info, call {@link +android.app.Activity#startActivity startActivity()} to send it to the system. If the system +identifies more than one activity that can handle the intent, it displays a dialog for the user to +select which app to use, as shown in figure 1. If there is only one activity that handles the +intent, the system immediately starts it.</p> + +<pre> +startActivity(intent); +</pre> + +<p>Here's a complete example that shows how to create an intent to view a map, verify that an +app exists to handle the intent, then start it:</p> + +<pre> +// Build the intent +Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California"); +Intent mapIntent = new Intent(Intent.ACTION_VIEW, location); + +// Verify it resolves +PackageManager packageManager = {@link android.content.Context#getPackageManager()}; +List<ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0); +boolean isIntentSafe = activities.size() > 0; + +// Start an activity if it's safe +if (isIntentSafe) { + startActivity(mapIntent); +} +</pre> + + + + diff --git a/include/androidfw/Input.h b/include/androidfw/Input.h index f8cbdde..a98e1a2 100644 --- a/include/androidfw/Input.h +++ b/include/androidfw/Input.h @@ -811,117 +811,6 @@ private: VelocityTracker mVelocityTracker; }; -/* - * Identifies a device. - */ -struct InputDeviceIdentifier { - inline InputDeviceIdentifier() : - bus(0), vendor(0), product(0), version(0) { - } - - // Information provided by the kernel. - String8 name; - String8 location; - String8 uniqueId; - uint16_t bus; - uint16_t vendor; - uint16_t product; - uint16_t version; - - // A composite input device descriptor string that uniquely identifies the device - // even across reboots or reconnections. The value of this field is used by - // upper layers of the input system to associate settings with individual devices. - // It is hashed from whatever kernel provided information is available. - // Ideally, the way this value is computed should not change between Android releases - // because that would invalidate persistent settings that rely on it. - String8 descriptor; -}; - -/* - * Describes the characteristics and capabilities of an input device. - */ -class InputDeviceInfo { -public: - InputDeviceInfo(); - InputDeviceInfo(const InputDeviceInfo& other); - ~InputDeviceInfo(); - - struct MotionRange { - int32_t axis; - uint32_t source; - float min; - float max; - float flat; - float fuzz; - }; - - void initialize(int32_t id, const String8& name, const String8& descriptor); - - inline int32_t getId() const { return mId; } - inline const String8 getName() const { return mName; } - inline const String8 getDescriptor() const { return mDescriptor; } - inline uint32_t getSources() const { return mSources; } - - const MotionRange* getMotionRange(int32_t axis, uint32_t source) const; - - void addSource(uint32_t source); - void addMotionRange(int32_t axis, uint32_t source, - float min, float max, float flat, float fuzz); - void addMotionRange(const MotionRange& range); - - inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; } - inline int32_t getKeyboardType() const { return mKeyboardType; } - - inline void setKeyCharacterMapFile(const String8& value) { mKeyCharacterMapFile = value; } - inline const String8& getKeyCharacterMapFile() const { return mKeyCharacterMapFile; } - - inline const Vector<MotionRange>& getMotionRanges() const { - return mMotionRanges; - } - -private: - int32_t mId; - String8 mName; - String8 mDescriptor; - uint32_t mSources; - int32_t mKeyboardType; - String8 mKeyCharacterMapFile; - - Vector<MotionRange> mMotionRanges; -}; - -/* Types of input device configuration files. */ -enum InputDeviceConfigurationFileType { - INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION = 0, /* .idc file */ - INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT = 1, /* .kl file */ - INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP = 2, /* .kcm file */ -}; - -/* - * Gets the path of an input device configuration file, if one is available. - * Considers both system provided and user installed configuration files. - * - * The device identifier is used to construct several default configuration file - * names to try based on the device name, vendor, product, and version. - * - * Returns an empty string if not found. - */ -extern String8 getInputDeviceConfigurationFilePathByDeviceIdentifier( - const InputDeviceIdentifier& deviceIdentifier, - InputDeviceConfigurationFileType type); - -/* - * Gets the path of an input device configuration file, if one is available. - * Considers both system provided and user installed configuration files. - * - * The name is case-sensitive and is used to construct the filename to resolve. - * All characters except 'a'-'z', 'A'-'Z', '0'-'9', '-', and '_' are replaced by underscores. - * - * Returns an empty string if not found. - */ -extern String8 getInputDeviceConfigurationFilePathByName( - const String8& name, InputDeviceConfigurationFileType type); - } // namespace android #endif // _ANDROIDFW_INPUT_H diff --git a/include/androidfw/InputDevice.h b/include/androidfw/InputDevice.h new file mode 100644 index 0000000..c9554dc --- /dev/null +++ b/include/androidfw/InputDevice.h @@ -0,0 +1,143 @@ +/* + * 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. + */ + +#ifndef _ANDROIDFW_INPUT_DEVICE_H +#define _ANDROIDFW_INPUT_DEVICE_H + +#include <androidfw/Input.h> +#include <androidfw/KeyCharacterMap.h> + +namespace android { + +/* + * Identifies a device. + */ +struct InputDeviceIdentifier { + inline InputDeviceIdentifier() : + bus(0), vendor(0), product(0), version(0) { + } + + // Information provided by the kernel. + String8 name; + String8 location; + String8 uniqueId; + uint16_t bus; + uint16_t vendor; + uint16_t product; + uint16_t version; + + // A composite input device descriptor string that uniquely identifies the device + // even across reboots or reconnections. The value of this field is used by + // upper layers of the input system to associate settings with individual devices. + // It is hashed from whatever kernel provided information is available. + // Ideally, the way this value is computed should not change between Android releases + // because that would invalidate persistent settings that rely on it. + String8 descriptor; +}; + +/* + * Describes the characteristics and capabilities of an input device. + */ +class InputDeviceInfo { +public: + InputDeviceInfo(); + InputDeviceInfo(const InputDeviceInfo& other); + ~InputDeviceInfo(); + + struct MotionRange { + int32_t axis; + uint32_t source; + float min; + float max; + float flat; + float fuzz; + }; + + void initialize(int32_t id, const String8& name, const String8& descriptor); + + inline int32_t getId() const { return mId; } + inline const String8 getName() const { return mName; } + inline const String8 getDescriptor() const { return mDescriptor; } + inline uint32_t getSources() const { return mSources; } + + const MotionRange* getMotionRange(int32_t axis, uint32_t source) const; + + void addSource(uint32_t source); + void addMotionRange(int32_t axis, uint32_t source, + float min, float max, float flat, float fuzz); + void addMotionRange(const MotionRange& range); + + inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; } + inline int32_t getKeyboardType() const { return mKeyboardType; } + + inline void setKeyCharacterMap(const sp<KeyCharacterMap>& value) { + mKeyCharacterMap = value; + } + + inline sp<KeyCharacterMap> getKeyCharacterMap() const { + return mKeyCharacterMap; + } + + inline const Vector<MotionRange>& getMotionRanges() const { + return mMotionRanges; + } + +private: + int32_t mId; + String8 mName; + String8 mDescriptor; + uint32_t mSources; + int32_t mKeyboardType; + sp<KeyCharacterMap> mKeyCharacterMap; + + Vector<MotionRange> mMotionRanges; +}; + +/* Types of input device configuration files. */ +enum InputDeviceConfigurationFileType { + INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION = 0, /* .idc file */ + INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT = 1, /* .kl file */ + INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP = 2, /* .kcm file */ +}; + +/* + * Gets the path of an input device configuration file, if one is available. + * Considers both system provided and user installed configuration files. + * + * The device identifier is used to construct several default configuration file + * names to try based on the device name, vendor, product, and version. + * + * Returns an empty string if not found. + */ +extern String8 getInputDeviceConfigurationFilePathByDeviceIdentifier( + const InputDeviceIdentifier& deviceIdentifier, + InputDeviceConfigurationFileType type); + +/* + * Gets the path of an input device configuration file, if one is available. + * Considers both system provided and user installed configuration files. + * + * The name is case-sensitive and is used to construct the filename to resolve. + * All characters except 'a'-'z', 'A'-'Z', '0'-'9', '-', and '_' are replaced by underscores. + * + * Returns an empty string if not found. + */ +extern String8 getInputDeviceConfigurationFilePathByName( + const String8& name, InputDeviceConfigurationFileType type); + +} // namespace android + +#endif // _ANDROIDFW_INPUT_DEVICE_H diff --git a/include/androidfw/KeyCharacterMap.h b/include/androidfw/KeyCharacterMap.h index 679dd2c..3cc1cb2 100644 --- a/include/androidfw/KeyCharacterMap.h +++ b/include/androidfw/KeyCharacterMap.h @@ -19,12 +19,17 @@ #include <stdint.h> +#if HAVE_ANDROID_OS +#include <binder/IBinder.h> +#endif + #include <androidfw/Input.h> #include <utils/Errors.h> #include <utils/KeyedVector.h> #include <utils/Tokenizer.h> #include <utils/String8.h> #include <utils/Unicode.h> +#include <utils/RefBase.h> namespace android { @@ -32,8 +37,10 @@ namespace android { * Describes a mapping from Android key codes to characters. * Also specifies other functions of the keyboard such as the keyboard type * and key modifier semantics. + * + * This object is immutable after it has been loaded. */ -class KeyCharacterMap { +class KeyCharacterMap : public RefBase { public: enum KeyboardType { KEYBOARD_TYPE_UNKNOWN = 0, @@ -50,9 +57,11 @@ public: int32_t metaState; }; - ~KeyCharacterMap(); + /* Loads a key character map from a file. */ + static status_t load(const String8& filename, sp<KeyCharacterMap>* outMap); - static status_t load(const String8& filename, KeyCharacterMap** outMap); + /* Returns an empty key character map. */ + static sp<KeyCharacterMap> empty(); /* Gets the keyboard type. */ int32_t getKeyboardType() const; @@ -92,6 +101,17 @@ public: bool getEvents(int32_t deviceId, const char16_t* chars, size_t numChars, Vector<KeyEvent>& outEvents) const; +#if HAVE_ANDROID_OS + /* Reads a key map from a parcel. */ + static sp<KeyCharacterMap> readFromParcel(Parcel* parcel); + + /* Writes a key map to a parcel. */ + void writeToParcel(Parcel* parcel) const; +#endif + +protected: + virtual ~KeyCharacterMap(); + private: struct Behavior { Behavior(); @@ -162,6 +182,8 @@ private: status_t parseCharacterLiteral(char16_t* outCharacter); }; + static sp<KeyCharacterMap> sEmpty; + KeyedVector<int32_t, Key*> mKeys; int mType; diff --git a/include/androidfw/KeyLayoutMap.h b/include/androidfw/KeyLayoutMap.h index 5a6f550..5408680 100644 --- a/include/androidfw/KeyLayoutMap.h +++ b/include/androidfw/KeyLayoutMap.h @@ -21,6 +21,7 @@ #include <utils/Errors.h> #include <utils/KeyedVector.h> #include <utils/Tokenizer.h> +#include <utils/RefBase.h> namespace android { @@ -56,18 +57,21 @@ struct AxisInfo { /** * Describes a mapping from keyboard scan codes and joystick axes to Android key codes and axes. + * + * This object is immutable after it has been loaded. */ -class KeyLayoutMap { +class KeyLayoutMap : public RefBase { public: - ~KeyLayoutMap(); - - static status_t load(const String8& filename, KeyLayoutMap** outMap); + static status_t load(const String8& filename, sp<KeyLayoutMap>* outMap); status_t mapKey(int32_t scanCode, int32_t* keyCode, uint32_t* flags) const; status_t findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const; status_t mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const; +protected: + virtual ~KeyLayoutMap(); + private: struct Key { int32_t keyCode; diff --git a/include/androidfw/Keyboard.h b/include/androidfw/Keyboard.h index ae65198..6537a8f 100644 --- a/include/androidfw/Keyboard.h +++ b/include/androidfw/Keyboard.h @@ -18,6 +18,7 @@ #define _ANDROIDFW_KEYBOARD_H #include <androidfw/Input.h> +#include <androidfw/InputDevice.h> #include <utils/Errors.h> #include <utils/String8.h> #include <utils/PropertyMap.h> @@ -42,10 +43,10 @@ class KeyCharacterMap; class KeyMap { public: String8 keyLayoutFile; - KeyLayoutMap* keyLayoutMap; + sp<KeyLayoutMap> keyLayoutMap; String8 keyCharacterMapFile; - KeyCharacterMap* keyCharacterMap; + sp<KeyCharacterMap> keyCharacterMap; KeyMap(); ~KeyMap(); diff --git a/include/androidfw/VirtualKeyMap.h b/include/androidfw/VirtualKeyMap.h index 66340e3..dd3ad1e 100644 --- a/include/androidfw/VirtualKeyMap.h +++ b/include/androidfw/VirtualKeyMap.h @@ -43,6 +43,8 @@ struct VirtualKeyDefinition { /** * Describes a collection of virtual keys on a touch screen in terms of * virtual scan codes and hit rectangles. + * + * This object is immutable after it has been loaded. */ class VirtualKeyMap { public: diff --git a/include/private/hwui/DrawGlInfo.h b/include/private/hwui/DrawGlInfo.h index 8028bf3..e33823e 100644 --- a/include/private/hwui/DrawGlInfo.h +++ b/include/private/hwui/DrawGlInfo.h @@ -31,6 +31,10 @@ struct DrawGlInfo { int clipRight; int clipBottom; + // Input: current width/height of destination surface + int width; + int height; + // Input: is the render target an FBO bool isLayer; diff --git a/libs/androidfw/Android.mk b/libs/androidfw/Android.mk index a3f92cb..95c77d4 100644 --- a/libs/androidfw/Android.mk +++ b/libs/androidfw/Android.mk @@ -29,6 +29,7 @@ commonUtilsSources:= \ # formerly in libui commonUiSources:= \ Input.cpp \ + InputDevice.cpp \ Keyboard.cpp \ KeyCharacterMap.cpp \ KeyLayoutMap.cpp \ diff --git a/libs/androidfw/Input.cpp b/libs/androidfw/Input.cpp index 2e4b26f..1617a3f 100644 --- a/libs/androidfw/Input.cpp +++ b/libs/androidfw/Input.cpp @@ -1,8 +1,19 @@ -// -// Copyright 2010 The Android Open Source Project -// -// Provides a pipe-based transport for native events in the NDK. -// +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #define LOG_TAG "Input" //#define LOG_NDEBUG 0 @@ -39,106 +50,6 @@ namespace android { -static const char* CONFIGURATION_FILE_DIR[] = { - "idc/", - "keylayout/", - "keychars/", -}; - -static const char* CONFIGURATION_FILE_EXTENSION[] = { - ".idc", - ".kl", - ".kcm", -}; - -static bool isValidNameChar(char ch) { - return isascii(ch) && (isdigit(ch) || isalpha(ch) || ch == '-' || ch == '_'); -} - -static void appendInputDeviceConfigurationFileRelativePath(String8& path, - const String8& name, InputDeviceConfigurationFileType type) { - path.append(CONFIGURATION_FILE_DIR[type]); - for (size_t i = 0; i < name.length(); i++) { - char ch = name[i]; - if (!isValidNameChar(ch)) { - ch = '_'; - } - path.append(&ch, 1); - } - path.append(CONFIGURATION_FILE_EXTENSION[type]); -} - -String8 getInputDeviceConfigurationFilePathByDeviceIdentifier( - const InputDeviceIdentifier& deviceIdentifier, - InputDeviceConfigurationFileType type) { - if (deviceIdentifier.vendor !=0 && deviceIdentifier.product != 0) { - if (deviceIdentifier.version != 0) { - // Try vendor product version. - String8 versionPath(getInputDeviceConfigurationFilePathByName( - String8::format("Vendor_%04x_Product_%04x_Version_%04x", - deviceIdentifier.vendor, deviceIdentifier.product, - deviceIdentifier.version), - type)); - if (!versionPath.isEmpty()) { - return versionPath; - } - } - - // Try vendor product. - String8 productPath(getInputDeviceConfigurationFilePathByName( - String8::format("Vendor_%04x_Product_%04x", - deviceIdentifier.vendor, deviceIdentifier.product), - type)); - if (!productPath.isEmpty()) { - return productPath; - } - } - - // Try device name. - return getInputDeviceConfigurationFilePathByName(deviceIdentifier.name, type); -} - -String8 getInputDeviceConfigurationFilePathByName( - const String8& name, InputDeviceConfigurationFileType type) { - // Search system repository. - String8 path; - path.setTo(getenv("ANDROID_ROOT")); - path.append("/usr/"); - appendInputDeviceConfigurationFileRelativePath(path, name, type); -#if DEBUG_PROBE - ALOGD("Probing for system provided input device configuration file: path='%s'", path.string()); -#endif - if (!access(path.string(), R_OK)) { -#if DEBUG_PROBE - ALOGD("Found"); -#endif - return path; - } - - // Search user repository. - // TODO Should only look here if not in safe mode. - path.setTo(getenv("ANDROID_DATA")); - path.append("/system/devices/"); - appendInputDeviceConfigurationFileRelativePath(path, name, type); -#if DEBUG_PROBE - ALOGD("Probing for system user input device configuration file: path='%s'", path.string()); -#endif - if (!access(path.string(), R_OK)) { -#if DEBUG_PROBE - ALOGD("Found"); -#endif - return path; - } - - // Not found. -#if DEBUG_PROBE - ALOGD("Probe failed to find input device configuration file: name='%s', type=%d", - name.string(), type); -#endif - return String8(); -} - - // --- InputEvent --- void InputEvent::initialize(int32_t deviceId, int32_t source) { @@ -1222,57 +1133,4 @@ void VelocityControl::move(nsecs_t eventTime, float* deltaX, float* deltaY) { } } - -// --- InputDeviceInfo --- - -InputDeviceInfo::InputDeviceInfo() { - initialize(-1, String8("uninitialized device info"), String8("unknown")); -} - -InputDeviceInfo::InputDeviceInfo(const InputDeviceInfo& other) : - mId(other.mId), mName(other.mName), mDescriptor(other.mDescriptor), - mSources(other.mSources), - mKeyboardType(other.mKeyboardType), - mKeyCharacterMapFile(other.mKeyCharacterMapFile), - mMotionRanges(other.mMotionRanges) { -} - -InputDeviceInfo::~InputDeviceInfo() { -} - -void InputDeviceInfo::initialize(int32_t id, const String8& name, const String8& descriptor) { - mId = id; - mName = name; - mDescriptor = descriptor; - mSources = 0; - mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE; - mMotionRanges.clear(); -} - -const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange( - int32_t axis, uint32_t source) const { - size_t numRanges = mMotionRanges.size(); - for (size_t i = 0; i < numRanges; i++) { - const MotionRange& range = mMotionRanges.itemAt(i); - if (range.axis == axis && range.source == source) { - return ⦥ - } - } - return NULL; -} - -void InputDeviceInfo::addSource(uint32_t source) { - mSources |= source; -} - -void InputDeviceInfo::addMotionRange(int32_t axis, uint32_t source, float min, float max, - float flat, float fuzz) { - MotionRange range = { axis, source, min, max, flat, fuzz }; - mMotionRanges.add(range); -} - -void InputDeviceInfo::addMotionRange(const MotionRange& range) { - mMotionRanges.add(range); -} - } // namespace android diff --git a/libs/androidfw/InputDevice.cpp b/libs/androidfw/InputDevice.cpp new file mode 100644 index 0000000..698feb6 --- /dev/null +++ b/libs/androidfw/InputDevice.cpp @@ -0,0 +1,179 @@ +/* + * 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 "InputDevice" + +#include <stdlib.h> +#include <unistd.h> +#include <ctype.h> + +#include <androidfw/InputDevice.h> + +namespace android { + +static const char* CONFIGURATION_FILE_DIR[] = { + "idc/", + "keylayout/", + "keychars/", +}; + +static const char* CONFIGURATION_FILE_EXTENSION[] = { + ".idc", + ".kl", + ".kcm", +}; + +static bool isValidNameChar(char ch) { + return isascii(ch) && (isdigit(ch) || isalpha(ch) || ch == '-' || ch == '_'); +} + +static void appendInputDeviceConfigurationFileRelativePath(String8& path, + const String8& name, InputDeviceConfigurationFileType type) { + path.append(CONFIGURATION_FILE_DIR[type]); + for (size_t i = 0; i < name.length(); i++) { + char ch = name[i]; + if (!isValidNameChar(ch)) { + ch = '_'; + } + path.append(&ch, 1); + } + path.append(CONFIGURATION_FILE_EXTENSION[type]); +} + +String8 getInputDeviceConfigurationFilePathByDeviceIdentifier( + const InputDeviceIdentifier& deviceIdentifier, + InputDeviceConfigurationFileType type) { + if (deviceIdentifier.vendor !=0 && deviceIdentifier.product != 0) { + if (deviceIdentifier.version != 0) { + // Try vendor product version. + String8 versionPath(getInputDeviceConfigurationFilePathByName( + String8::format("Vendor_%04x_Product_%04x_Version_%04x", + deviceIdentifier.vendor, deviceIdentifier.product, + deviceIdentifier.version), + type)); + if (!versionPath.isEmpty()) { + return versionPath; + } + } + + // Try vendor product. + String8 productPath(getInputDeviceConfigurationFilePathByName( + String8::format("Vendor_%04x_Product_%04x", + deviceIdentifier.vendor, deviceIdentifier.product), + type)); + if (!productPath.isEmpty()) { + return productPath; + } + } + + // Try device name. + return getInputDeviceConfigurationFilePathByName(deviceIdentifier.name, type); +} + +String8 getInputDeviceConfigurationFilePathByName( + const String8& name, InputDeviceConfigurationFileType type) { + // Search system repository. + String8 path; + path.setTo(getenv("ANDROID_ROOT")); + path.append("/usr/"); + appendInputDeviceConfigurationFileRelativePath(path, name, type); +#if DEBUG_PROBE + ALOGD("Probing for system provided input device configuration file: path='%s'", path.string()); +#endif + if (!access(path.string(), R_OK)) { +#if DEBUG_PROBE + ALOGD("Found"); +#endif + return path; + } + + // Search user repository. + // TODO Should only look here if not in safe mode. + path.setTo(getenv("ANDROID_DATA")); + path.append("/system/devices/"); + appendInputDeviceConfigurationFileRelativePath(path, name, type); +#if DEBUG_PROBE + ALOGD("Probing for system user input device configuration file: path='%s'", path.string()); +#endif + if (!access(path.string(), R_OK)) { +#if DEBUG_PROBE + ALOGD("Found"); +#endif + return path; + } + + // Not found. +#if DEBUG_PROBE + ALOGD("Probe failed to find input device configuration file: name='%s', type=%d", + name.string(), type); +#endif + return String8(); +} + + +// --- InputDeviceInfo --- + +InputDeviceInfo::InputDeviceInfo() { + initialize(-1, String8("uninitialized device info"), String8("unknown")); +} + +InputDeviceInfo::InputDeviceInfo(const InputDeviceInfo& other) : + mId(other.mId), mName(other.mName), mDescriptor(other.mDescriptor), + mSources(other.mSources), + mKeyboardType(other.mKeyboardType), + mKeyCharacterMap(other.mKeyCharacterMap), + mMotionRanges(other.mMotionRanges) { +} + +InputDeviceInfo::~InputDeviceInfo() { +} + +void InputDeviceInfo::initialize(int32_t id, const String8& name, const String8& descriptor) { + mId = id; + mName = name; + mDescriptor = descriptor; + mSources = 0; + mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE; + mMotionRanges.clear(); +} + +const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange( + int32_t axis, uint32_t source) const { + size_t numRanges = mMotionRanges.size(); + for (size_t i = 0; i < numRanges; i++) { + const MotionRange& range = mMotionRanges.itemAt(i); + if (range.axis == axis && range.source == source) { + return ⦥ + } + } + return NULL; +} + +void InputDeviceInfo::addSource(uint32_t source) { + mSources |= source; +} + +void InputDeviceInfo::addMotionRange(int32_t axis, uint32_t source, float min, float max, + float flat, float fuzz) { + MotionRange range = { axis, source, min, max, flat, fuzz }; + mMotionRanges.add(range); +} + +void InputDeviceInfo::addMotionRange(const MotionRange& range) { + mMotionRanges.add(range); +} + +} // namespace android diff --git a/libs/androidfw/KeyCharacterMap.cpp b/libs/androidfw/KeyCharacterMap.cpp index 6984084..9abbf38 100644 --- a/libs/androidfw/KeyCharacterMap.cpp +++ b/libs/androidfw/KeyCharacterMap.cpp @@ -21,6 +21,11 @@ #include <android/keycodes.h> #include <androidfw/Keyboard.h> #include <androidfw/KeyCharacterMap.h> + +#if HAVE_ANDROID_OS +#include <binder/Parcel.h> +#endif + #include <utils/Log.h> #include <utils/Errors.h> #include <utils/Tokenizer.h> @@ -78,6 +83,8 @@ static String8 toString(const char16_t* chars, size_t numChars) { // --- KeyCharacterMap --- +sp<KeyCharacterMap> KeyCharacterMap::sEmpty = new KeyCharacterMap(); + KeyCharacterMap::KeyCharacterMap() : mType(KEYBOARD_TYPE_UNKNOWN) { } @@ -89,23 +96,23 @@ KeyCharacterMap::~KeyCharacterMap() { } } -status_t KeyCharacterMap::load(const String8& filename, KeyCharacterMap** outMap) { - *outMap = NULL; +status_t KeyCharacterMap::load(const String8& filename, sp<KeyCharacterMap>* outMap) { + outMap->clear(); Tokenizer* tokenizer; status_t status = Tokenizer::open(filename, &tokenizer); if (status) { ALOGE("Error %d opening key character map file %s.", status, filename.string()); } else { - KeyCharacterMap* map = new KeyCharacterMap(); - if (!map) { + sp<KeyCharacterMap> map = new KeyCharacterMap(); + if (!map.get()) { ALOGE("Error allocating key character map."); status = NO_MEMORY; } else { #if DEBUG_PARSER_PERFORMANCE nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC); #endif - Parser parser(map, tokenizer); + Parser parser(map.get(), tokenizer); status = parser.parse(); #if DEBUG_PARSER_PERFORMANCE nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime; @@ -113,9 +120,7 @@ status_t KeyCharacterMap::load(const String8& filename, KeyCharacterMap** outMap tokenizer->getFilename().string(), tokenizer->getLineNumber(), elapsedTime / 1000000.0); #endif - if (status) { - delete map; - } else { + if (!status) { *outMap = map; } } @@ -124,6 +129,10 @@ status_t KeyCharacterMap::load(const String8& filename, KeyCharacterMap** outMap return status; } +sp<KeyCharacterMap> KeyCharacterMap::empty() { + return sEmpty; +} + int32_t KeyCharacterMap::getKeyboardType() const { return mType; } @@ -419,6 +428,79 @@ void KeyCharacterMap::addLockedMetaKey(Vector<KeyEvent>& outEvents, } } +#if HAVE_ANDROID_OS +sp<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel) { + sp<KeyCharacterMap> map = new KeyCharacterMap(); + map->mType = parcel->readInt32(); + size_t numKeys = parcel->readInt32(); + if (parcel->errorCheck()) { + return NULL; + } + + for (size_t i = 0; i < numKeys; i++) { + int32_t keyCode = parcel->readInt32(); + char16_t label = parcel->readInt32(); + char16_t number = parcel->readInt32(); + if (parcel->errorCheck()) { + return NULL; + } + + Key* key = new Key(); + key->label = label; + key->number = number; + map->mKeys.add(keyCode, key); + + Behavior* lastBehavior = NULL; + while (parcel->readInt32()) { + int32_t metaState = parcel->readInt32(); + char16_t character = parcel->readInt32(); + int32_t fallbackKeyCode = parcel->readInt32(); + if (parcel->errorCheck()) { + return NULL; + } + + Behavior* behavior = new Behavior(); + behavior->metaState = metaState; + behavior->character = character; + behavior->fallbackKeyCode = fallbackKeyCode; + if (lastBehavior) { + lastBehavior->next = behavior; + } else { + key->firstBehavior = behavior; + } + lastBehavior = behavior; + } + + if (parcel->errorCheck()) { + return NULL; + } + } + return map; +} + +void KeyCharacterMap::writeToParcel(Parcel* parcel) const { + parcel->writeInt32(mType); + + size_t numKeys = mKeys.size(); + parcel->writeInt32(numKeys); + for (size_t i = 0; i < numKeys; i++) { + int32_t keyCode = mKeys.keyAt(i); + const Key* key = mKeys.valueAt(i); + parcel->writeInt32(keyCode); + parcel->writeInt32(key->label); + parcel->writeInt32(key->number); + for (const Behavior* behavior = key->firstBehavior; behavior != NULL; + behavior = behavior->next) { + parcel->writeInt32(1); + parcel->writeInt32(behavior->metaState); + parcel->writeInt32(behavior->character); + parcel->writeInt32(behavior->fallbackKeyCode); + } + parcel->writeInt32(0); + } +} +#endif + // --- KeyCharacterMap::Key --- diff --git a/libs/androidfw/KeyLayoutMap.cpp b/libs/androidfw/KeyLayoutMap.cpp index 15d81ee..1809412 100644 --- a/libs/androidfw/KeyLayoutMap.cpp +++ b/libs/androidfw/KeyLayoutMap.cpp @@ -47,23 +47,23 @@ KeyLayoutMap::KeyLayoutMap() { KeyLayoutMap::~KeyLayoutMap() { } -status_t KeyLayoutMap::load(const String8& filename, KeyLayoutMap** outMap) { - *outMap = NULL; +status_t KeyLayoutMap::load(const String8& filename, sp<KeyLayoutMap>* outMap) { + outMap->clear(); Tokenizer* tokenizer; status_t status = Tokenizer::open(filename, &tokenizer); if (status) { ALOGE("Error %d opening key layout map file %s.", status, filename.string()); } else { - KeyLayoutMap* map = new KeyLayoutMap(); - if (!map) { + sp<KeyLayoutMap> map = new KeyLayoutMap(); + if (!map.get()) { ALOGE("Error allocating key layout map."); status = NO_MEMORY; } else { #if DEBUG_PARSER_PERFORMANCE nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC); #endif - Parser parser(map, tokenizer); + Parser parser(map.get(), tokenizer); status = parser.parse(); #if DEBUG_PARSER_PERFORMANCE nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime; @@ -71,9 +71,7 @@ status_t KeyLayoutMap::load(const String8& filename, KeyLayoutMap** outMap) { tokenizer->getFilename().string(), tokenizer->getLineNumber(), elapsedTime / 1000000.0); #endif - if (status) { - delete map; - } else { + if (!status) { *outMap = map; } } diff --git a/libs/androidfw/Keyboard.cpp b/libs/androidfw/Keyboard.cpp index e97a5eb..a84a8c7 100644 --- a/libs/androidfw/Keyboard.cpp +++ b/libs/androidfw/Keyboard.cpp @@ -24,6 +24,7 @@ #include <androidfw/KeycodeLabels.h> #include <androidfw/KeyLayoutMap.h> #include <androidfw/KeyCharacterMap.h> +#include <androidfw/InputDevice.h> #include <utils/Errors.h> #include <utils/Log.h> #include <cutils/properties.h> @@ -32,13 +33,10 @@ namespace android { // --- KeyMap --- -KeyMap::KeyMap() : - keyLayoutMap(NULL), keyCharacterMap(NULL) { +KeyMap::KeyMap() { } KeyMap::~KeyMap() { - delete keyLayoutMap; - delete keyCharacterMap; } status_t KeyMap::load(const InputDeviceIdentifier& deviceIdenfifier, @@ -114,14 +112,12 @@ status_t KeyMap::loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier, return NAME_NOT_FOUND; } - KeyLayoutMap* map; - status_t status = KeyLayoutMap::load(path, &map); + status_t status = KeyLayoutMap::load(path, &keyLayoutMap); if (status) { return status; } keyLayoutFile.setTo(path); - keyLayoutMap = map; return OK; } @@ -133,14 +129,12 @@ status_t KeyMap::loadKeyCharacterMap(const InputDeviceIdentifier& deviceIdentifi return NAME_NOT_FOUND; } - KeyCharacterMap* map; - status_t status = KeyCharacterMap::load(path, &map); + status_t status = KeyCharacterMap::load(path, &keyCharacterMap); if (status) { return status; } keyCharacterMapFile.setTo(path); - keyCharacterMap = map; return OK; } diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 2a908ab..06928df 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -249,6 +249,8 @@ status_t OpenGLRenderer::invokeFunctors(Rect& dirty) { info.clipRight = 0; info.clipBottom = 0; info.isLayer = false; + info.width = 0; + info.height = 0; memset(info.transform, 0, sizeof(float) * 16); size_t count = functors.size(); @@ -292,6 +294,8 @@ status_t OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) { info.clipRight = clip.right; info.clipBottom = clip.bottom; info.isLayer = hasLayer(); + info.width = getSnapshot()->viewport.getWidth(); + info.height = getSnapshot()->height; getSnapshot()->transform->copyTo(&info.transform[0]); status_t result = (*functor)(DrawGlInfo::kModeDraw, &info); diff --git a/media/java/android/media/audiofx/AcousticEchoCanceler.java b/media/java/android/media/audiofx/AcousticEchoCanceler.java index 7197dd2..e31f84c 100644 --- a/media/java/android/media/audiofx/AcousticEchoCanceler.java +++ b/media/java/android/media/audiofx/AcousticEchoCanceler.java @@ -16,6 +16,8 @@ package android.media.audiofx; +import android.util.Log; + /** * Acoustic Echo Canceler (AEC). * <p>Acoustic Echo Canceler (AEC) is an audio pre-processing which removes the contribution of the @@ -26,14 +28,13 @@ package android.media.audiofx; * <p>An application creates an AcousticEchoCanceler object to instantiate and control an AEC * engine in the audio capture path. * <p>To attach the AcousticEchoCanceler to a particular {@link android.media.AudioRecord}, - * specify the audio session ID of this AudioRecord when constructing the AcousticEchoCanceler. + * specify the audio session ID of this AudioRecord when creating the AcousticEchoCanceler. * The audio session is retrieved by calling * {@link android.media.AudioRecord#getAudioSessionId()} on the AudioRecord instance. * <p>On some devices, an AEC can be inserted by default in the capture path by the platform - * according to the {@link android.media.MediaRecorder.AudioSource} used. The application can - * query which pre-processings are currently applied to an AudioRecord instance by calling - * {@link android.media.audiofx.AudioEffect#queryPreProcessings(int)} with the audio session of the - * AudioRecord. + * according to the {@link android.media.MediaRecorder.AudioSource} used. The application should + * call AcousticEchoCanceler.getEnable() after creating the AEC to check the default AEC activation + * state on a particular AudioRecord session. * <p>See {@link android.media.audiofx.AudioEffect} class for more details on * controlling audio effects. * @hide @@ -44,13 +45,43 @@ public class AcousticEchoCanceler extends AudioEffect { private final static String TAG = "AcousticEchoCanceler"; /** + * Checks if the device implements acoustic echo cancellation. + * @return true if the device implements acoustic echo cancellation, false otherwise. + */ + public static boolean isAvailable() { + return AudioEffect.isEffectTypeAvailable(AudioEffect.EFFECT_TYPE_AEC); + } + + /** + * Creates an AcousticEchoCanceler and attaches it to the AudioRecord on the audio + * session specified. + * @param audioSession system wide unique audio session identifier. The AcousticEchoCanceler + * will be applied to the AudioRecord with the same audio session. + * @return AcousticEchoCanceler created or null if the device does not implement AEC. + */ + public static AcousticEchoCanceler create(int audioSession) { + AcousticEchoCanceler aec = null; + try { + aec = new AcousticEchoCanceler(audioSession); + } catch (IllegalArgumentException e) { + Log.w(TAG, "not implemented on this device"+ aec); + } catch (UnsupportedOperationException e) { + Log.w(TAG, "not enough resources"); + } catch (RuntimeException e) { + Log.w(TAG, "not enough memory"); + } finally { + return aec; + } + } + + /** * Class constructor. - * <p> The application must catch exceptions when creating an AcousticEchoCanceler as the - * constructor is not guarantied to succeed: + * <p> The constructor is not guarantied to succeed and throws the following exceptions: * <ul> * <li>IllegalArgumentException is thrown if the device does not implement an AEC</li> * <li>UnsupportedOperationException is thrown is the resources allocated to audio * pre-procesing are currently exceeded.</li> + * <li>RuntimeException is thrown if a memory allocation error occurs.</li> * </ul> * * @param audioSession system wide unique audio session identifier. The AcousticEchoCanceler @@ -59,6 +90,7 @@ public class AcousticEchoCanceler extends AudioEffect { * @throws java.lang.IllegalArgumentException * @throws java.lang.UnsupportedOperationException * @throws java.lang.RuntimeException + * @hide */ public AcousticEchoCanceler(int audioSession) throws IllegalArgumentException, UnsupportedOperationException, RuntimeException { diff --git a/media/java/android/media/audiofx/AudioEffect.java b/media/java/android/media/audiofx/AudioEffect.java index 85be267..68a09de 100644 --- a/media/java/android/media/audiofx/AudioEffect.java +++ b/media/java/android/media/audiofx/AudioEffect.java @@ -452,6 +452,22 @@ public class AudioEffect { return (Descriptor[]) native_query_pre_processing(audioSession); } + /** + * Checks if the device implements the specified effect type. + * @param type the requested effect type. + * @return true if the device implements the specified effect type, false otherwise. + * @hide + */ + public static boolean isEffectTypeAvailable(UUID type) { + AudioEffect.Descriptor[] desc = AudioEffect.queryEffects(); + for (int i = 0; i < desc.length; i++) { + if (desc[i].type.equals(type)) { + return true; + } + } + return false; + } + // -------------------------------------------------------------------------- // Control methods // -------------------- diff --git a/media/java/android/media/audiofx/AutomaticGainControl.java b/media/java/android/media/audiofx/AutomaticGainControl.java index 44574f0..eca7eec 100644 --- a/media/java/android/media/audiofx/AutomaticGainControl.java +++ b/media/java/android/media/audiofx/AutomaticGainControl.java @@ -16,24 +16,25 @@ package android.media.audiofx; +import android.util.Log; + /** * Automatic Gain Control (AGC). * <p>Automatic Gain Control (AGC) is an audio pre-processing which automatically normalizes the * output of the captured signal by boosting or lowering input from the microphone to match a preset - * level so that that the output signal level is virtually constant. + * level so that the output signal level is virtually constant. * AGC can be used by applications where the input signal dynamic range is not important but where * a constant strong capture level is desired. * <p>An application creates a AutomaticGainControl object to instantiate and control an AGC * engine in the audio framework. * <p>To attach the AutomaticGainControl to a particular {@link android.media.AudioRecord}, - * specify the audio session ID of this AudioRecord when constructing the AutomaticGainControl. + * specify the audio session ID of this AudioRecord when creating the AutomaticGainControl. * The audio session is retrieved by calling * {@link android.media.AudioRecord#getAudioSessionId()} on the AudioRecord instance. * <p>On some devices, an AGC can be inserted by default in the capture path by the platform - * according to the {@link android.media.MediaRecorder.AudioSource} used. The application can - * query which pre-processings are currently applied to an AudioRecord instance by calling - * {@link android.media.audiofx.AudioEffect#queryPreProcessings(int)} with the audio session of the - * AudioRecord. + * according to the {@link android.media.MediaRecorder.AudioSource} used. The application should + * call AutomaticGainControl.getEnable() after creating the AGC to check the default AGC activation + * state on a particular AudioRecord session. * <p>See {@link android.media.audiofx.AudioEffect} class for more details on * controlling audio effects. * @hide @@ -44,13 +45,43 @@ public class AutomaticGainControl extends AudioEffect { private final static String TAG = "AutomaticGainControl"; /** + * Checks if the device implements automatic gain control. + * @return true if the device implements automatic gain control, false otherwise. + */ + public static boolean isAvailable() { + return AudioEffect.isEffectTypeAvailable(AudioEffect.EFFECT_TYPE_AGC); + } + + /** + * Creates an AutomaticGainControl and attaches it to the AudioRecord on the audio + * session specified. + * @param audioSession system wide unique audio session identifier. The AutomaticGainControl + * will be applied to the AudioRecord with the same audio session. + * @return AutomaticGainControl created or null if the device does not implement AGC. + */ + public static AutomaticGainControl create(int audioSession) { + AutomaticGainControl agc = null; + try { + agc = new AutomaticGainControl(audioSession); + } catch (IllegalArgumentException e) { + Log.w(TAG, "not implemented on this device "+agc); + } catch (UnsupportedOperationException e) { + Log.w(TAG, "not enough resources"); + } catch (RuntimeException e) { + Log.w(TAG, "not enough memory"); + } finally { + return agc; + } + } + + /** * Class constructor. - * <p> The application must catch exceptions when creating an AutomaticGainControl as the - * constructor is not guarantied to succeed: + * <p> The constructor is not guarantied to succeed and throws the following exceptions: * <ul> * <li>IllegalArgumentException is thrown if the device does not implement an AGC</li> * <li>UnsupportedOperationException is thrown is the resources allocated to audio * pre-procesing are currently exceeded.</li> + * <li>RuntimeException is thrown if a memory allocation error occurs.</li> * </ul> * * @param audioSession system wide unique audio session identifier. The AutomaticGainControl @@ -59,6 +90,7 @@ public class AutomaticGainControl extends AudioEffect { * @throws java.lang.IllegalArgumentException * @throws java.lang.UnsupportedOperationException * @throws java.lang.RuntimeException + * @hide */ public AutomaticGainControl(int audioSession) throws IllegalArgumentException, UnsupportedOperationException, RuntimeException { diff --git a/media/java/android/media/audiofx/NoiseSuppressor.java b/media/java/android/media/audiofx/NoiseSuppressor.java index 4e7a8b6..a2d3386 100644 --- a/media/java/android/media/audiofx/NoiseSuppressor.java +++ b/media/java/android/media/audiofx/NoiseSuppressor.java @@ -16,6 +16,8 @@ package android.media.audiofx; +import android.util.Log; + /** * Noise Suppressor (NS). * <p>Noise suppression (NS) is an audio pre-processing which removes background noise from the @@ -27,14 +29,13 @@ package android.media.audiofx; * <p>An application creates a NoiseSuppressor object to instantiate and control an NS * engine in the audio framework. * <p>To attach the NoiseSuppressor to a particular {@link android.media.AudioRecord}, - * specify the audio session ID of this AudioRecord when constructing the NoiseSuppressor. + * specify the audio session ID of this AudioRecord when creating the NoiseSuppressor. * The audio session is retrieved by calling * {@link android.media.AudioRecord#getAudioSessionId()} on the AudioRecord instance. * <p>On some devices, NS can be inserted by default in the capture path by the platform - * according to the {@link android.media.MediaRecorder.AudioSource} used. The application can - * query which pre-processings are currently applied to an AudioRecord instance by calling - * {@link android.media.audiofx.AudioEffect#queryPreProcessings(int)} with the audio session of the - * AudioRecord. + * according to the {@link android.media.MediaRecorder.AudioSource} used. The application should + * call NoiseSuppressor.getEnable() after creating the NS to check the default NS activation + * state on a particular AudioRecord session. * <p>See {@link android.media.audiofx.AudioEffect} class for more details on * controlling audio effects. * @hide @@ -45,13 +46,44 @@ public class NoiseSuppressor extends AudioEffect { private final static String TAG = "NoiseSuppressor"; /** + * Checks if the device implements noise suppression. + * @return true if the device implements noise suppression, false otherwise. + */ + public static boolean isAvailable() { + return AudioEffect.isEffectTypeAvailable(AudioEffect.EFFECT_TYPE_NS); + } + + /** + * Creates a NoiseSuppressor and attaches it to the AudioRecord on the audio + * session specified. + * @param audioSession system wide unique audio session identifier. The NoiseSuppressor + * will be applied to the AudioRecord with the same audio session. + * @return NoiseSuppressor created or null if the device does not implement noise + * suppression. + */ + public static NoiseSuppressor create(int audioSession) { + NoiseSuppressor ns = null; + try { + ns = new NoiseSuppressor(audioSession); + } catch (IllegalArgumentException e) { + Log.w(TAG, "not implemented on this device "+ns); + } catch (UnsupportedOperationException e) { + Log.w(TAG, "not enough resources"); + } catch (RuntimeException e) { + Log.w(TAG, "not enough memory"); + } finally { + return ns; + } + } + + /** * Class constructor. - * <p> The application must catch exceptions when creating an NoiseSuppressor as the - * constructor is not guarantied to succeed: + * <p> The constructor is not guarantied to succeed and throws the following exceptions: * <ul> * <li>IllegalArgumentException is thrown if the device does not implement an NS</li> * <li>UnsupportedOperationException is thrown is the resources allocated to audio * pre-procesing are currently exceeded.</li> + * <li>RuntimeException is thrown if a memory allocation error occurs.</li> * </ul> * * @param audioSession system wide unique audio session identifier. The NoiseSuppressor @@ -60,8 +92,9 @@ public class NoiseSuppressor extends AudioEffect { * @throws java.lang.IllegalArgumentException * @throws java.lang.UnsupportedOperationException * @throws java.lang.RuntimeException + * @hide */ - public NoiseSuppressor(int audioSession) + private NoiseSuppressor(int audioSession) throws IllegalArgumentException, UnsupportedOperationException, RuntimeException { super(EFFECT_TYPE_NS, EFFECT_TYPE_NULL, 0, audioSession); } diff --git a/native/android/input.cpp b/native/android/input.cpp index 6eb2990..accec64 100644 --- a/native/android/input.cpp +++ b/native/android/input.cpp @@ -32,7 +32,6 @@ using android::InputEvent; using android::KeyEvent; using android::MotionEvent; -using android::InputDeviceInfo; using android::sp; using android::Vector; diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java index c937a09..2a4d59b 100644 --- a/opengl/java/android/opengl/GLSurfaceView.java +++ b/opengl/java/android/opengl/GLSurfaceView.java @@ -1459,7 +1459,10 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback Log.w("GLThread", "egl createSurface"); } if (!mEglHelper.createSurface()) { - mSurfaceIsBad = true; + synchronized(sGLThreadManager) { + mSurfaceIsBad = true; + sGLThreadManager.notifyAll(); + } continue; } createEglSurface = false; @@ -1519,7 +1522,11 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback // but we haven't been notified yet. // Log the error to help developers understand why rendering stopped. EglHelper.logEglErrorAsWarning("GLThread", "eglSwapBuffers", swapError); - mSurfaceIsBad = true; + + synchronized(sGLThreadManager) { + mSurfaceIsBad = true; + sGLThreadManager.notifyAll(); + } break; } diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_input_methods_panel.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_input_methods_panel.xml index f6ed804..b712dba 100644 --- a/packages/SystemUI/res/layout-sw600dp/status_bar_input_methods_panel.xml +++ b/packages/SystemUI/res/layout-sw600dp/status_bar_input_methods_panel.xml @@ -21,7 +21,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="match_parent" android:layout_width="match_parent" - android:paddingBottom="28dip" + android:paddingBottom="7dip" android:orientation="vertical" android:visibility="gone"> <View @@ -38,7 +38,7 @@ android:layout_height="wrap_content" android:layout_marginLeft="20dip" android:orientation="vertical" - android:background="@*android:drawable/dialog_full_holo_dark"> + android:background="@drawable/notify_panel_clock_bg"> <!-- Hard keyboard switch --> <LinearLayout android:id="@+id/hard_keyboard_section" @@ -51,7 +51,7 @@ android:orientation="horizontal"> <TextView android:id="@+id/use_physical_keyboard_label" - android:layout_width="wrap_content" + android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:minHeight="?android:attr/listPreferredItemHeight" @@ -82,7 +82,7 @@ <!-- Input method list --> <ScrollView android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_height="0dip" android:overScrollMode="ifContentScrolls" android:layout_marginTop="3dip" android:layout_weight="1" diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 08dedfa..56826fa 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Kennisgewings"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth-verbind"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Stel invoer metodes op"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Gebruik fisiese sleutelbord"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Laat die program <xliff:g id="APPLICATION">%1$s</xliff:g> toe om toegang tot die USB-toestel te kry?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Laat die program <xliff:g id="APPLICATION">%1$s</xliff:g> toe om toegang tot die USB-toebehoorsel te kry?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Maak <xliff:g id="ACTIVITY">%1$s</xliff:g> oop wanneer hierdie USB-toestel gekoppel is?"</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index 13aaacb..7013862 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"ማሳወቂያዎች"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"ብሉቱዝ አያይዝ"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"የግቤት ስልቶችን አዘጋጅ"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"የቁልፍ ሰሌዳ ተጠቀም"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"መተግበሪያ <xliff:g id="APPLICATION">%1$s</xliff:g> የUSB መሣሪያን ለመድረስ ይፍቀድ?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"መተግበሪያ <xliff:g id="APPLICATION">%1$s</xliff:g> የUSB ተቀጥላ ላይ እንዲደርስ ፍቀድ?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"የዚህ USB ተቀጥላ ሲያያዝ <xliff:g id="ACTIVITY">%1$s</xliff:g>ይከፈት?"</string> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 4bc56af..201f72c 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"التنبيهات"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"تم إنشاء الاتصال بالإنترنت عن طريق البلوتوث."</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"إعداد أسلوب الإدخال"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"استخدام لوحة المفاتيح الفعلية"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"هل تريد السماح للتطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> بالدخول إلى جهاز USB؟"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"هل تريد السماح للتطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> بالدخول إلى ملحق USB؟"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"هل تريد فتح <xliff:g id="ACTIVITY">%1$s</xliff:g> عند توصيل جهاز USB هذا؟"</string> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index d083467..b885503 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Паведамленні"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Прывязаныя праз Bluetooth"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Налада метадаў уводу"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Выкарыст. фiзiч. клав."</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Дазволіць праыкладанню <xliff:g id="APPLICATION">%1$s</xliff:g> атрымлiваць доступ да прылады USB?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Дазволіць прыкладанню <xliff:g id="APPLICATION">%1$s</xliff:g> доступ да прылады USB?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Адкрыць <xliff:g id="ACTIVITY">%1$s</xliff:g>, калі гэтая USB-прылада падлучаная?"</string> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 33aca92..e5167a5 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Известия"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth има връзка с тетъринг"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Методи на въвеждане: Настройка"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Използване на физ. клав."</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Да се разреши ли на приложението <xliff:g id="APPLICATION">%1$s</xliff:g> достъп до USB устройството?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Да се разреши ли на приложението <xliff:g id="APPLICATION">%1$s</xliff:g> достъп до аксесоара за USB?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Да се отвори ли <xliff:g id="ACTIVITY">%1$s</xliff:g>, когато това USB устройство е свързано?"</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 775e610..0ebced0 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Notificacions"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth sense fil"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configura els mètodes d\'entrada"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utilitza un teclat físic"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Vols permetre que l\'aplicació <xliff:g id="APPLICATION">%1$s</xliff:g> accedeixi al dispositiu USB?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Vols permetre que l\'aplicació <xliff:g id="APPLICATION">%1$s</xliff:g> accedeixi a l\'accessori USB?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Vols que s\'obri <xliff:g id="ACTIVITY">%1$s</xliff:g> quan aquest dispositiu USB estigui connectat?"</string> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 0f48f35..847bfc4 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Oznámení"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Datové připojení Bluetooth se sdílí"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Nastavit metody vstupu"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Použít fyz. klávesnici"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Povolit aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> přístup k zařízení USB?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Povolit aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> přístup k perifernímu zařízení USB?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Chcete při připojení tohoto zařízení USB otevřít aplikaci <xliff:g id="ACTIVITY">%1$s</xliff:g>?"</string> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index b518898..ac58b06 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Underretninger"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth-tethering anvendt"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfigurer inputmetoder"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Brug fysisk tastatur"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Tillad, at appen <xliff:g id="APPLICATION">%1$s</xliff:g> kan få adgang til USB-enheden?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Vil du tillade, at appen <xliff:g id="APPLICATION">%1$s</xliff:g> får adgang til USB-enheden?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Vil du åbne <xliff:g id="ACTIVITY">%1$s</xliff:g>, når denne USB-enhed er tilsluttet?"</string> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index ab4eeb4..39d5c33 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Benachrichtigungen"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth-Tethering aktiv"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Eingabemethoden einrichten"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Physische Tastatur"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"App <xliff:g id="APPLICATION">%1$s</xliff:g> Zugriff auf USB-Gerät gewähren?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"App <xliff:g id="APPLICATION">%1$s</xliff:g> Zugriff auf USB-Zubehör gewähren?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"<xliff:g id="ACTIVITY">%1$s</xliff:g> öffnen, wenn dieses USB-Gerät verbunden ist?"</string> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index cc9dce1..48158db 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Ειδοποιήσεις"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Έγινε σύνδεση μέσω Bluetooth"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Ρύθμιση μεθόδων εισαγωγής"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Χρήση κανονικού πληκτρολ."</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Να επιτρέπεται στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> η πρόσβαση στη συσκευή USB;"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Να επιτρέπεται στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> η πρόσβαση στο αξεσουάρ USB;"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Άνοιγμα του <xliff:g id="ACTIVITY">%1$s</xliff:g> κατά τη σύνδεση αυτής της συσκευής USB;"</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 3c70b15..148924a 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Notifications"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth tethered"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Set up input methods"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Use physical keyboard"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Allow the app <xliff:g id="APPLICATION">%1$s</xliff:g> to access the USB device?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Allow the app <xliff:g id="APPLICATION">%1$s</xliff:g> to access the USB accessory?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Open <xliff:g id="ACTIVITY">%1$s</xliff:g> when this USB device is connected?"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index a700908..4db7130 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Notificaciones"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth anclado"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurar métodos de intro."</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Usar teclado físico"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"¿Deseas que la aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> acceda al dispositivo USB?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"¿Deseas que la aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> acceda al accesorio USB?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"¿Abrir <xliff:g id="ACTIVITY">%1$s</xliff:g> cuando este dispositivo USB esté conectado?"</string> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index f0dcc23..f7f73d7 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Notificaciones"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth anclado"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurar métodos de introducción"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utilizar teclado físico"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"¿Permitir que la aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> acceda al dispositivo USB?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"¿Permitir que la aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> acceda al accesorio USB?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"¿Quieres abrir <xliff:g id="ACTIVITY">%1$s</xliff:g> al conectar este dispositivo USB?"</string> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index 16bb040..8e3a1e3 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Teatised"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth on jagatud"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Seadista sisestusmeetodeid"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Kasutage füüsilist klaviatuuri"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Kas lubate rakendusel <xliff:g id="APPLICATION">%1$s</xliff:g> USB-seadmele juurde pääseda?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Kas lubate rakendusel <xliff:g id="APPLICATION">%1$s</xliff:g> USB-seadmele juurde pääseda?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Kas avada <xliff:g id="ACTIVITY">%1$s</xliff:g>, kui see USB-seade on ühendatud?"</string> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 91a8f64..569e929 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"اعلان ها"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"اتصال اینترنتی با بلوتوث تلفن همراه"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"تنظیم روشهای ورودی"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"از صفحه کلید فیزیکی استفاده کنید"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"به برنامه <xliff:g id="APPLICATION">%1$s</xliff:g> اجازه می دهید به دستگاه USB دسترسی داشته باشد؟"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"به برنامه <xliff:g id="APPLICATION">%1$s</xliff:g> اجازه میدهد تا به وسیله جانبی USB دسترسی داشته باشد؟"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"وقتی این دستگاه USB وصل است، <xliff:g id="ACTIVITY">%1$s</xliff:g> باز شود؟"</string> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index cf9230c7..93e6b62 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Ilmoitukset"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth yhdistetty"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Määritä syöttötavat"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Käytä fyysistä näppäimistöä"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Annetaanko sovellukselle <xliff:g id="APPLICATION">%1$s</xliff:g> lupa käyttää USB-laitetta?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Annetaanko sovellukselle <xliff:g id="APPLICATION">%1$s</xliff:g> lupa käyttää USB-lisälaitetta?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Avataanko <xliff:g id="ACTIVITY">%1$s</xliff:g> tämän USB-laitteen ollessa kytkettynä?"</string> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index d313517..1a8c6a7 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Notifications"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Connexion Bluetooth partagée"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurer les modes de saisie"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utiliser clavier physique"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Autoriser l\'application <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder au périphérique USB ?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Autoriser l\'application <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à l\'accessoire USB ?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Ouvrir <xliff:g id="ACTIVITY">%1$s</xliff:g> lors de la connexion de ce périphérique USB ?"</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 42b901c..741f1b4 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"सूचनाएं"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth टीदर किया गया"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"इनपुट पद्धति सेट करें"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"भौतिक कीबोर्ड का उपयोग करें"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"एप्लिकेशन <xliff:g id="APPLICATION">%1$s</xliff:g> को USB उपकरण तक पहुंचने दें?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"एप्लिकेशन <xliff:g id="APPLICATION">%1$s</xliff:g> को USB सहायक उपकरण तक पहुंचने दें?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"जब यह USB उपकरण कनेक्ट किया जाए, तब <xliff:g id="ACTIVITY">%1$s</xliff:g> को खोलें?"</string> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 4e6d99c..f3d4043 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Obavijesti"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth posredno povezan"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Postavljanje načina unosa"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Rabi fizičku tipkovnicu"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Dopustiti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> da pristupi ovom USB uređaju?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Dopustiti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> da pristupi ovom USB dodatku?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Otvoriti <xliff:g id="ACTIVITY">%1$s</xliff:g> kad se spoji ovaj USB uređaj?"</string> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index e710d50..1c28b57 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Értesítések"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth megosztva"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Beviteli módok beállítása"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Valódi bill. használata"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"A(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazás hozzáférhet az USB-eszközhöz?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"A(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazás hozzáférhet az USB-kiegészítőhöz?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"<xliff:g id="ACTIVITY">%1$s</xliff:g> megnyitása, ha USB-kiegészítő csatlakoztatva van?"</string> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 2acf554..267f5e7 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Pemberitahuan"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth tertambat"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Menyiapkan metode masukan"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Gunakan keyboard fisik"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Izinkan apl <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses perangkat USB?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Izinkan apl <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses aksesori USB?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Buka <xliff:g id="ACTIVITY">%1$s</xliff:g> ketika perangkat USB ini tersambung?"</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 0119d5c..cdf7c9d 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Notifiche"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth con tethering"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configura metodi di immissione"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utilizza tastiera fisica"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Consentire all\'applicazione <xliff:g id="APPLICATION">%1$s</xliff:g> di accedere al dispositivo USB?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Consentire all\'applicazione <xliff:g id="APPLICATION">%1$s</xliff:g> di accedere all\'accessorio USB?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Aprire <xliff:g id="ACTIVITY">%1$s</xliff:g> quando questo dispositivo USB è collegato?"</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index b6376c8..bc5e873 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"התראות"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth קשור"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"הגדר שיטות קלט"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"השתמש במקלדת הפיזית"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"לאפשר ליישום <xliff:g id="APPLICATION">%1$s</xliff:g> גישה להתקן ה-USB?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"לאפשר ליישום <xliff:g id="APPLICATION">%1$s</xliff:g> גישה לאביזר ה-USB?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"האם לפתוח את <xliff:g id="ACTIVITY">%1$s</xliff:g> כאשר מכשיר USB זה מחובר?"</string> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index d9c9aa2..01d76eb 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"通知"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetoothテザリング接続"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"入力方法をセットアップ"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"物理キーボードを使用"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"アプリ「<xliff:g id="APPLICATION">%1$s</xliff:g>」にUSBデバイスへのアクセスを許可しますか?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"アプリ「<xliff:g id="APPLICATION">%1$s</xliff:g>」にUSBアクセサリへのアクセスを許可しますか?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"このUSBデバイスが接続されたときに<xliff:g id="ACTIVITY">%1$s</xliff:g>を開きますか?"</string> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 79569c5..88194df 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"알림"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"블루투스 테더링됨"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"입력 방법 설정"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"물리적 키보드 사용"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"<xliff:g id="APPLICATION">%1$s</xliff:g> 앱이 USB 기기에 액세스하도록 허용하시겠습니까?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"<xliff:g id="APPLICATION">%1$s</xliff:g> 앱이 USB 액세서리에 액세스하도록 허용하시겠습니까?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"USB 기기가 연결될 때 <xliff:g id="ACTIVITY">%1$s</xliff:g>(을)를 여시겠습니까?"</string> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index 490bd4a..942e159 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Pranešimai"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"„Bluetooth“ susieta"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Nustatyti įvesties metodus"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Naudoti fizinę klaviatūrą"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Leisti programai „<xliff:g id="APPLICATION">%1$s</xliff:g>“ pasiekti USB įrenginį?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Leisti programai „<xliff:g id="APPLICATION">%1$s</xliff:g>“ pasiekti USB priedą?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Atidaryti <xliff:g id="ACTIVITY">%1$s</xliff:g>, kai prijungtas šis USB įrenginys?"</string> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 62e99ee..b5c9130 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Paziņojumi"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth piesaiste"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Iestatīt ievades metodes"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Izmantot fizisku tastatūru"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Vai ļaut lietotnei <xliff:g id="APPLICATION">%1$s</xliff:g> piekļūt šai USB ierīcei?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Vai ļaut lietotnei <xliff:g id="APPLICATION">%1$s</xliff:g> piekļūt šim USB piederumam?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Vai atvērt darbību <xliff:g id="ACTIVITY">%1$s</xliff:g>, kad tiek pievienota šī USB ierīce?"</string> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index 5f64f7b..f08013d 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Pemberitahuan"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth ditambatkan"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Sediakan kaedah input"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Guna ppn kekunci fizikal"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Benarkan aplikasi <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses peranti USB?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Benarkan aplikasi <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses aksesori USB?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Buka <xliff:g id="ACTIVITY">%1$s</xliff:g> apabila peranti USB ini disambungkan?"</string> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index b90876a..fdd3b10 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Varslinger"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth tilknyttet"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfigurer inndatametoder"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Bruk fysisk tastatur"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Vil du gi appen <xliff:g id="APPLICATION">%1$s</xliff:g> tilgang til USB-enheten?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Vil du gi appen <xliff:g id="APPLICATION">%1$s</xliff:g> tilgang til USB-tilbehøret?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Vil du åpne <xliff:g id="ACTIVITY">%1$s</xliff:g> når denne USB-enheten er tilkoblet?"</string> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index cf85c75..5314ba3 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Meldingen"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth getetherd"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Invoermethoden instellen"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Fysiek toetsenbord gebruiken"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"De app <xliff:g id="APPLICATION">%1$s</xliff:g> toegang geven tot het USB-apparaat?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"De app <xliff:g id="APPLICATION">%1$s</xliff:g> toegang geven tot het USB-accessoire?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"<xliff:g id="ACTIVITY">%1$s</xliff:g> openen wanneer dit USB-apparaat wordt aangesloten?"</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index c65f99e..26e3989 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Powiadomienia"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth – podłączono"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfiguruj metody wprowadzania"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Używaj klawiatury fizycznej"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Zezwolić aplikacji <xliff:g id="APPLICATION">%1$s</xliff:g> na dostęp do urządzenia USB?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Zezwolić aplikacji <xliff:g id="APPLICATION">%1$s</xliff:g> na dostęp do urządzenia USB?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Czy otworzyć <xliff:g id="ACTIVITY">%1$s</xliff:g> po podłączeniu tego urządzenia USB?"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index e1340ec..a5999e3 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Notificações"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth ligado"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurar métodos introdução"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utilizar teclado físico"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Permitir que a aplicação <xliff:g id="APPLICATION">%1$s</xliff:g> aceda ao dispositivo USB?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Permitir que a aplicação <xliff:g id="APPLICATION">%1$s</xliff:g> aceda ao acessório USB?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Abrir <xliff:g id="ACTIVITY">%1$s</xliff:g> quando este dispositivo USB estiver ligado?"</string> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index dec4def..02bef77 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Notificações"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth vinculado"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurar métodos de entrada"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Usar o teclado físico"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Permitir que o aplicativo <xliff:g id="APPLICATION">%1$s</xliff:g> acesse o dispositivo USB?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Permitir que o aplicativo <xliff:g id="APPLICATION">%1$s</xliff:g> acesse o acessório USB?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Abrir <xliff:g id="ACTIVITY">%1$s</xliff:g> quando este dispositivo USB estiver conectado?"</string> diff --git a/packages/SystemUI/res/values-rm/strings.xml b/packages/SystemUI/res/values-rm/strings.xml index 983df47..3062d48 100644 --- a/packages/SystemUI/res/values-rm/strings.xml +++ b/packages/SystemUI/res/values-rm/strings.xml @@ -66,7 +66,7 @@ <skip /> <!-- no translation found for status_bar_input_method_settings_configure_input_methods (3504292471512317827) --> <skip /> - <!-- no translation found for status_bar_use_physical_keyboard (3695516942412442936) --> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> <skip /> <!-- no translation found for usb_device_permission_prompt (834698001271562057) --> <skip /> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index e4c55d6..ff6ca3d 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Notificări"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Conectat prin tethering prin Bluetooth"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configuraţi metode de intrare"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utilizaţi tastat. fizică"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Permiteţi aplicaţiei <xliff:g id="APPLICATION">%1$s</xliff:g> să acceseze dispozitivul USB?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Permiteţi aplicaţiei <xliff:g id="APPLICATION">%1$s</xliff:g> să acceseze accesoriul USB?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Deschideţi <xliff:g id="ACTIVITY">%1$s</xliff:g> la conectarea acestui dispozitiv USB?"</string> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 963976d..4057599 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Уведомления"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Общий модем доступен через Bluetooth"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Настройка способов ввода"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Использовать физическую клавиатуру"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Открыть приложению \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" доступ к USB-устройству?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Открыть приложению \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" доступ к USB-устройству?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Запускать <xliff:g id="ACTIVITY">%1$s</xliff:g> при подключении этого USB-устройства?"</string> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index f0ec8ff..67368ac 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Upozornenia"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Zdieľané dátové pripojenie cez Bluetooth"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Nastavenie metód vstupu"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Použiť fyzickú klávesnicu"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Povoliť aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g> prístup k zariadeniu USB?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Povoliť aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g> prístup k periférnemu zariadeniu USB?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Chcete pri pripojení tohto zariadenia USB otvoriť aplikáciu <xliff:g id="ACTIVITY">%1$s</xliff:g>?"</string> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 61b82c9..77aef3d 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Obvestila"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Internetna povezava prek Bluetootha"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Nastavi načine vnosa"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Uporabi fizično tipkovn."</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Želite programu <xliff:g id="APPLICATION">%1$s</xliff:g> dovoliti dostop do naprave USB?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Želite dovoliti programu <xliff:g id="APPLICATION">%1$s</xliff:g> dostop do dodatka USB?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Želite, da se odpre <xliff:g id="ACTIVITY">%1$s</xliff:g>, ko priključite to napravo USB?"</string> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index f341fba..3268544 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Обавештења"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Веза преко Bluetooth-а"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Подеси методе уноса"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Користи физичку тастатуру"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Желите ли да дозволите апликацији <xliff:g id="APPLICATION">%1$s</xliff:g> да приступа USB уређају?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Желите ли да дозволите апликацији <xliff:g id="APPLICATION">%1$s</xliff:g> да приступа USB помоћном уређају?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Желите ли да се отвори <xliff:g id="ACTIVITY">%1$s</xliff:g> када се прикључи овај USB уређај?"</string> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index f8fb054..ba4edea 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Aviseringar"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Internetdelning via Bluetooth"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfigurera inmatningsmetoder"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Använd fysiska tangenter"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Vill du tillåta att appen <xliff:g id="APPLICATION">%1$s</xliff:g> använder USB-enheten?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Vill du tillåta att appen <xliff:g id="APPLICATION">%1$s</xliff:g> använder USB-tillbehöret?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Vill du öppna <xliff:g id="ACTIVITY">%1$s</xliff:g> när den här USB-enheten ansluts?"</string> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 70e29eb..8a6b050 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -46,7 +46,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Arifa"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth imefungwa"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Weka mbinu za ingizo"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Tumia kibodi halisi"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Ruhusu programu <xliff:g id="APPLICATION">%1$s</xliff:g> kufikia kifaa cha USB?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Ruhusu programu <xliff:g id="APPLICATION">%1$s</xliff:g> kufikia kifaa cha ziada cha USB?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Je, ungetaka kufungua <xliff:g id="ACTIVITY">%1$s</xliff:g>wakati kifaa cha USB kimeunganishwa?"</string> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 3f37060..42c4721 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"การแจ้งเตือน"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"บลูทูธที่ปล่อยสัญญาณ"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ตั้งค่าวิธีการป้อนข้อมูล"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"ใช้แป้นพิมพ์จริง"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"อนุญาตให้แอปพลิเคชัน <xliff:g id="APPLICATION">%1$s</xliff:g> เข้าถึงอุปกรณ์ USB นี้หรือไม่"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"อนุญาตให้แอปพลิเคชัน <xliff:g id="APPLICATION">%1$s</xliff:g> เข้าถึงอุปกรณ์เสริม USB นี้หรือไม่"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"เปิด <xliff:g id="ACTIVITY">%1$s</xliff:g> เมื่อมีการเชื่อมต่ออุปกรณ์ USB นี้หรือไม่"</string> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 807d797..55ecfae 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Mga Notification"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Na-tether ang bluetooth"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"I-set up paraan ng pag-input"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Gamitin ang pisikal na keyboard"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Payagan ang app na <xliff:g id="APPLICATION">%1$s</xliff:g> na i-access ang USB device?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Payagan ang app na <xliff:g id="APPLICATION">%1$s</xliff:g> na i-access ang USB accessory?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Buksan ang <xliff:g id="ACTIVITY">%1$s</xliff:g> kapag nakakonekta ang USB device na ito?"</string> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 83567ae..f0aa516 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Bildirimler"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth paylaşımı tamam"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Giriş yöntemlerini ayarla"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Fiziksel klavyeyi kullan"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"<xliff:g id="APPLICATION">%1$s</xliff:g> uygulamasının USB cihazına erişmesine izin verilsin mi?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"<xliff:g id="APPLICATION">%1$s</xliff:g> uygulamasının USB aksesuarına erişmesine izin verilsin mi?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Bu USB cihaz bağlandığında <xliff:g id="ACTIVITY">%1$s</xliff:g> açılsın mı?"</string> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index bec231a..9a05919 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Сповіщення"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Створено прив\'язку Bluetooth"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Налаштувати методи введення"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Викор. реальну клавіатуру"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Надати програмі <xliff:g id="APPLICATION">%1$s</xliff:g> доступ до пристрою USB?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Надати програмі <xliff:g id="APPLICATION">%1$s</xliff:g> доступ до аксесуара USB?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Відкривати \"<xliff:g id="ACTIVITY">%1$s</xliff:g>\", коли під’єднано пристрій USB?"</string> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 34b84af..abd024a 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Thông báo"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth được dùng làm điểm truy cập Internet"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Thiết lập phương thức nhập"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Sử dụng bàn phím vật lý"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Cho phép ứng dụng <xliff:g id="APPLICATION">%1$s</xliff:g> truy cập thiết bị USB?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Cho phép ứng dụng <xliff:g id="APPLICATION">%1$s</xliff:g> truy cập phụ kiện USB?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Mở <xliff:g id="ACTIVITY">%1$s</xliff:g> khi thiết bị USB này được kết nối?"</string> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 1f9c959..ec92713 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"通知"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"已通过蓝牙共享网络"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"设置输入法"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"使用物理键盘"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"允许应用“<xliff:g id="APPLICATION">%1$s</xliff:g>”访问该 USB 设备吗?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"允许应用“<xliff:g id="APPLICATION">%1$s</xliff:g>”访问该 USB 配件吗?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"要在连接此 USB 设备时打开<xliff:g id="ACTIVITY">%1$s</xliff:g>吗?"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index 614f143..cabc243 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"通知"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"藍牙網路共用已開"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"設定輸入法"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"使用實體鍵盤"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"允許 <xliff:g id="APPLICATION">%1$s</xliff:g> 應用程式存取 USB 裝置嗎?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"允許 <xliff:g id="APPLICATION">%1$s</xliff:g> 應用程式存取 USB 配件嗎?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"連接這個 USB 裝置時啟用 <xliff:g id="ACTIVITY">%1$s</xliff:g> 嗎?"</string> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 0249e89..27dd8fd 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -48,7 +48,8 @@ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Izaziso"</string> <string name="bluetooth_tethered" msgid="7094101612161133267">"Ukusebenzisa i-Bluetooth njengemodemu"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Izilungiselelo zezindlela zokufakwayo"</string> - <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Sebenzisa ikhibhodi ebangekayo"</string> + <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) --> + <skip /> <string name="usb_device_permission_prompt" msgid="834698001271562057">"Vumela insiza <xliff:g id="APPLICATION">%1$s</xliff:g> ukuthi ufinyelele ezintweni eziphuma ne-USB?"</string> <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Vumela insiza <xliff:g id="APPLICATION">%1$s</xliff:g> ukuthi ufinyelele ezintweni eziphuma ne-USB?"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Vula <xliff:g id="ACTIVITY">%1$s</xliff:g> uma ledivayisi ye-USB ixhunyiwe?"</string> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index fc81f8e..6dbe9d3 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -125,7 +125,7 @@ <string name="status_bar_input_method_settings_configure_input_methods">Set up input methods</string> <!-- Label of a toggle switch to disable use of the physical keyboard in favor of the IME. [CHAR LIMIT=25] --> - <string name="status_bar_use_physical_keyboard">Use physical keyboard</string> + <string name="status_bar_use_physical_keyboard">Physical keyboard</string> <!-- Prompt for the USB device permission dialog [CHAR LIMIT=80] --> <string name="usb_device_permission_prompt">Allow the app <xliff:g id="application">%1$s</xliff:g> to access the USB device?</string> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 804ae06..3f611fc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -2047,7 +2047,10 @@ public class PhoneStatusBar extends BaseStatusBar { snapshot.add(child); } } - final int N = snapshot.size(); + if (snapshot.isEmpty()) { + animateCollapse(false); + return; + } new Thread(new Runnable() { @Override public void run() { @@ -2063,6 +2066,7 @@ public class PhoneStatusBar extends BaseStatusBar { mPile.setViewRemoval(false); mPostCollapseCleanup = new Runnable() { + @Override public void run() { try { mPile.setViewRemoval(true); @@ -2073,9 +2077,8 @@ public class PhoneStatusBar extends BaseStatusBar { View sampleView = snapshot.get(0); int width = sampleView.getWidth(); - final int velocity = (int)(width * 8); // 1000/8 = 125 ms duration - for (View v : snapshot) { - final View _v = v; + final int velocity = width * 8; // 1000/8 = 125 ms duration + for (final View _v : snapshot) { mHandler.postDelayed(new Runnable() { @Override public void run() { @@ -2091,6 +2094,7 @@ public class PhoneStatusBar extends BaseStatusBar { // synchronize the end of those animations with the start of the collaps // exactly. mHandler.postDelayed(new Runnable() { + @Override public void run() { animateCollapse(false); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java index 0c8208f..a00fab3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java @@ -273,7 +273,8 @@ public class KeyButtonView extends ImageView { 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, flags | KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, InputDevice.SOURCE_KEYBOARD); - InputManager.injectInputEvent(ev, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); + InputManager.getInstance().injectInputEvent(ev, + InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java index f793af9..2171329 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java @@ -201,7 +201,6 @@ public class InputMethodsPanel extends LinearLayout implements StatusBarPanel, if (closeKeyboard) { mImm.hideSoftInputFromWindow(getWindowToken(), 0); } - updateHardKeyboardEnabled(); } private void startActivity(Intent intent) { @@ -329,6 +328,7 @@ public class InputMethodsPanel extends LinearLayout implements StatusBarPanel, mHardKeyboardSection.setVisibility(View.VISIBLE); if (mHardKeyboardSwitch.isChecked() != mHardKeyboardEnabled) { mHardKeyboardSwitch.setChecked(mHardKeyboardEnabled); + updateHardKeyboardEnabled(); } } else { mHardKeyboardSection.setVisibility(View.GONE); diff --git a/policy/src/com/android/internal/policy/impl/FaceUnlock.java b/policy/src/com/android/internal/policy/impl/FaceUnlock.java index 985dcd3..31fbaaf 100644 --- a/policy/src/com/android/internal/policy/impl/FaceUnlock.java +++ b/policy/src/com/android/internal/policy/impl/FaceUnlock.java @@ -213,7 +213,8 @@ public class FaceUnlock implements Handler.Callback { if (DEBUG) Log.d(TAG, "before bind to FaceLock service"); mContext.bindService(new Intent(IFaceLockInterface.class.getName()), mConnection, - Context.BIND_AUTO_CREATE); + Context.BIND_AUTO_CREATE, + mLockPatternUtils.getCurrentUser()); if (DEBUG) Log.d(TAG, "after bind to FaceLock service"); mBoundToService = true; } else { diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java index 596040c..39ede89 100644 --- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java +++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java @@ -703,6 +703,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase { @Override public void onUserChanged(int userId) { + mFaceUnlock.stopAndUnbind(); mLockPatternUtils.setCurrentUser(userId); updateScreen(getInitialMode(), true); } @@ -817,7 +818,9 @@ public class LockPatternKeyguardView extends KeyguardViewBase { if (force || mUnlockScreen == null || unlockMode != mUnlockScreenMode) { boolean restartFaceLock = mFaceUnlock.stopIfRunning(); recreateUnlockScreen(unlockMode); - if (restartFaceLock) mFaceUnlock.activateIfAble(mHasOverlay); + if (restartFaceLock) { + mFaceUnlock.activateIfAble(mHasOverlay); + } } } diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index d150b5c..1891146 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -327,7 +327,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { RecentApplicationsDialog mRecentAppsDialog; int mRecentAppsDialogHeldModifiers; - int mLidOpen = LID_ABSENT; + int mLidState = LID_ABSENT; boolean mSystemReady; boolean mSystemBooted; @@ -1225,16 +1225,16 @@ public class PhoneWindowManager implements WindowManagerPolicy { } void readLidState() { - mLidOpen = mWindowManagerFuncs.getLidState(); + mLidState = mWindowManagerFuncs.getLidState(); } private int determineHiddenState(int mode, int hiddenValue, int visibleValue) { - if (mLidOpen != LID_ABSENT) { + if (mLidState != LID_ABSENT) { switch (mode) { case 1: - return mLidOpen == LID_OPEN ? visibleValue : hiddenValue; + return mLidState == LID_OPEN ? visibleValue : hiddenValue; case 2: - return mLidOpen == LID_OPEN ? hiddenValue : visibleValue; + return mLidState == LID_OPEN ? hiddenValue : visibleValue; } } return visibleValue; @@ -2797,7 +2797,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mHeadless) return; // lid changed state - mLidOpen = lidOpen ? LID_OPEN : LID_CLOSED; + mLidState = lidOpen ? LID_OPEN : LID_CLOSED; updateKeyboardVisibility(); boolean awakeNow = mKeyguardMediator.doLidChangeTq(lidOpen); @@ -3486,7 +3486,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } final int preferredRotation; - if (mLidOpen == LID_OPEN && mLidOpenRotation >= 0) { + if (mLidState == LID_OPEN && mLidOpenRotation >= 0) { // Ignore sensor when lid switch is open and rotation is forced. preferredRotation = mLidOpenRotation; } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR @@ -3878,7 +3878,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } private void updateKeyboardVisibility() { - mPowerManager.setKeyboardVisibility(mLidOpen == LID_OPEN); + mPowerManager.setKeyboardVisibility(mLidState == LID_OPEN); } void updateRotation(boolean alwaysSendConfiguration) { @@ -4132,7 +4132,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { pw.print(prefix); pw.print("mSafeMode="); pw.print(mSafeMode); pw.print(" mSystemReady="); pw.print(mSystemReady); pw.print(" mSystemBooted="); pw.println(mSystemBooted); - pw.print(prefix); pw.print("mLidOpen="); pw.print(mLidOpen); + pw.print(prefix); pw.print("mLidState="); pw.print(mLidState); pw.print(" mLidOpenRotation="); pw.print(mLidOpenRotation); pw.print(" mHdmiPlugged="); pw.println(mHdmiPlugged); if (mLastSystemUiFlags != 0 || mResettingSystemUiFlags != 0 diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp index 7060ae2..744f2ad 100644 --- a/services/input/EventHub.cpp +++ b/services/input/EventHub.cpp @@ -93,6 +93,32 @@ static String8 sha1(const String8& in) { return out; } +static void setDescriptor(InputDeviceIdentifier& identifier) { + // Compute a device descriptor that uniquely identifies the device. + // The descriptor is assumed to be a stable identifier. Its value should not + // change between reboots, reconnections, firmware updates or new releases of Android. + // Ideally, we also want the descriptor to be short and relatively opaque. + String8 rawDescriptor; + rawDescriptor.appendFormat(":%04x:%04x:", identifier.vendor, identifier.product); + if (!identifier.uniqueId.isEmpty()) { + rawDescriptor.append("uniqueId:"); + rawDescriptor.append(identifier.uniqueId); + } if (identifier.vendor == 0 && identifier.product == 0) { + // If we don't know the vendor and product id, then the device is probably + // built-in so we need to rely on other information to uniquely identify + // the input device. Usually we try to avoid relying on the device name or + // location but for built-in input device, they are unlikely to ever change. + if (!identifier.name.isEmpty()) { + rawDescriptor.append("name:"); + rawDescriptor.append(identifier.name); + } else if (!identifier.location.isEmpty()) { + rawDescriptor.append("location:"); + rawDescriptor.append(identifier.location); + } + } + identifier.descriptor = sha1(rawDescriptor); +} + // --- Global Functions --- uint32_t getAbsAxisUsage(int32_t axis, uint32_t deviceClasses) { @@ -164,7 +190,7 @@ const int EventHub::EPOLL_SIZE_HINT; const int EventHub::EPOLL_MAX_EVENTS; EventHub::EventHub(void) : - mBuiltInKeyboardId(-1), mNextDeviceId(1), + mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD), mNextDeviceId(1), mOpeningDevices(0), mClosingDevices(0), mNeedToSendFinishedDeviceScan(false), mNeedToReopenDevices(false), mNeedToScanDevices(true), @@ -256,7 +282,7 @@ status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis, AutoMutex _l(mLock); Device* device = getDeviceLocked(deviceId); - if (device && test_bit(axis, device->absBitmask)) { + if (device && !device->isVirtual() && test_bit(axis, device->absBitmask)) { struct input_absinfo info; if(ioctl(device->fd, EVIOCGABS(axis), &info)) { ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d", @@ -307,7 +333,7 @@ int32_t EventHub::getScanCodeState(int32_t deviceId, int32_t scanCode) const { AutoMutex _l(mLock); Device* device = getDeviceLocked(deviceId); - if (device && test_bit(scanCode, device->keyBitmask)) { + if (device && !device->isVirtual() && test_bit(scanCode, device->keyBitmask)) { uint8_t keyState[sizeof_bit_array(KEY_MAX + 1)]; memset(keyState, 0, sizeof(keyState)); if (ioctl(device->fd, EVIOCGKEY(sizeof(keyState)), keyState) >= 0) { @@ -322,7 +348,7 @@ int32_t EventHub::getKeyCodeState(int32_t deviceId, int32_t keyCode) const { AutoMutex _l(mLock); Device* device = getDeviceLocked(deviceId); - if (device && device->keyMap.haveKeyLayout()) { + if (device && !device->isVirtual() && device->keyMap.haveKeyLayout()) { Vector<int32_t> scanCodes; device->keyMap.keyLayoutMap->findScanCodesForKey(keyCode, &scanCodes); if (scanCodes.size() != 0) { @@ -347,7 +373,7 @@ int32_t EventHub::getSwitchState(int32_t deviceId, int32_t sw) const { AutoMutex _l(mLock); Device* device = getDeviceLocked(deviceId); - if (device && test_bit(sw, device->swBitmask)) { + if (device && !device->isVirtual() && test_bit(sw, device->swBitmask)) { uint8_t swState[sizeof_bit_array(SW_MAX + 1)]; memset(swState, 0, sizeof(swState)); if (ioctl(device->fd, EVIOCGSW(sizeof(swState)), swState) >= 0) { @@ -365,7 +391,7 @@ status_t EventHub::getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* AutoMutex _l(mLock); Device* device = getDeviceLocked(deviceId); - if (device && test_bit(axis, device->absBitmask)) { + if (device && !device->isVirtual() && test_bit(axis, device->absBitmask)) { struct input_absinfo info; if(ioctl(device->fd, EVIOCGABS(axis), &info)) { ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d", @@ -421,7 +447,7 @@ status_t EventHub::mapKey(int32_t deviceId, int scancode, } } - if (mBuiltInKeyboardId != -1) { + if (mBuiltInKeyboardId != NO_BUILT_IN_KEYBOARD) { device = getDeviceLocked(mBuiltInKeyboardId); if (device && device->keyMap.haveKeyLayout()) { @@ -449,7 +475,7 @@ status_t EventHub::mapAxis(int32_t deviceId, int scancode, AxisInfo* outAxisInfo } } - if (mBuiltInKeyboardId != -1) { + if (mBuiltInKeyboardId != NO_BUILT_IN_KEYBOARD) { device = getDeviceLocked(mBuiltInKeyboardId); if (device && device->keyMap.haveKeyLayout()) { @@ -494,7 +520,7 @@ bool EventHub::hasLed(int32_t deviceId, int32_t led) const { void EventHub::setLedState(int32_t deviceId, int32_t led, bool on) { AutoMutex _l(mLock); Device* device = getDeviceLocked(deviceId); - if (device && led >= 0 && led <= LED_MAX) { + if (device && !device->isVirtual() && led >= 0 && led <= LED_MAX) { struct input_event ev; ev.time.tv_sec = 0; ev.time.tv_usec = 0; @@ -520,17 +546,17 @@ void EventHub::getVirtualKeyDefinitions(int32_t deviceId, } } -String8 EventHub::getKeyCharacterMapFile(int32_t deviceId) const { +sp<KeyCharacterMap> EventHub::getKeyCharacterMap(int32_t deviceId) const { AutoMutex _l(mLock); Device* device = getDeviceLocked(deviceId); if (device) { - return device->keyMap.keyCharacterMapFile; + return device->keyMap.keyCharacterMap; } - return String8(); + return NULL; } EventHub::Device* EventHub::getDeviceLocked(int32_t deviceId) const { - if (deviceId == 0) { + if (deviceId == BUILT_IN_KEYBOARD_ID) { deviceId = mBuiltInKeyboardId; } ssize_t index = mDevices.indexOfKey(deviceId); @@ -578,7 +604,7 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz device->id, device->path.string()); mClosingDevices = device->next; event->when = now; - event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id; + event->deviceId = device->id == mBuiltInKeyboardId ? BUILT_IN_KEYBOARD_ID : device->id; event->type = DEVICE_REMOVED; event += 1; delete device; @@ -813,6 +839,9 @@ void EventHub::scanDevicesLocked() { if(res < 0) { ALOGE("scan dir failed for %s\n", DEVICE_PATH); } + if (mDevices.indexOfKey(VIRTUAL_KEYBOARD_ID) < 0) { + createVirtualKeyboardLocked(); + } } // ---------------------------------------------------------------------------- @@ -908,29 +937,8 @@ status_t EventHub::openDeviceLocked(const char *devicePath) { identifier.uniqueId.setTo(buffer); } - // Compute a device descriptor that uniquely identifies the device. - // The descriptor is assumed to be a stable identifier. Its value should not - // change between reboots, reconnections, firmware updates or new releases of Android. - // Ideally, we also want the descriptor to be short and relatively opaque. - String8 rawDescriptor; - rawDescriptor.appendFormat(":%04x:%04x:", identifier.vendor, identifier.product); - if (!identifier.uniqueId.isEmpty()) { - rawDescriptor.append("uniqueId:"); - rawDescriptor.append(identifier.uniqueId); - } if (identifier.vendor == 0 && identifier.product == 0) { - // If we don't know the vendor and product id, then the device is probably - // built-in so we need to rely on other information to uniquely identify - // the input device. Usually we try to avoid relying on the device name or - // location but for built-in input device, they are unlikely to ever change. - if (!identifier.name.isEmpty()) { - rawDescriptor.append("name:"); - rawDescriptor.append(identifier.name); - } else if (!identifier.location.isEmpty()) { - rawDescriptor.append("location:"); - rawDescriptor.append(identifier.location); - } - } - identifier.descriptor = sha1(rawDescriptor); + // Fill in the descriptor. + setDescriptor(identifier); // Make file descriptor non-blocking for use with poll(). if (fcntl(fd, F_SETFL, O_NONBLOCK)) { @@ -1048,7 +1056,7 @@ status_t EventHub::openDeviceLocked(const char *devicePath) { if (device->classes & INPUT_DEVICE_CLASS_KEYBOARD) { // Register the keyboard as a built-in keyboard if it is eligible. if (!keyMapStatus - && mBuiltInKeyboardId == -1 + && mBuiltInKeyboardId == NO_BUILT_IN_KEYBOARD && isEligibleBuiltInKeyboard(device->identifier, device->configuration, &device->keyMap)) { mBuiltInKeyboardId = device->id; @@ -1133,11 +1141,29 @@ status_t EventHub::openDeviceLocked(const char *devicePath) { toString(mBuiltInKeyboardId == deviceId), toString(usingSuspendBlockIoctl), toString(usingClockIoctl)); - mDevices.add(deviceId, device); + addDeviceLocked(device); + return 0; +} +void EventHub::createVirtualKeyboardLocked() { + InputDeviceIdentifier identifier; + identifier.name = "Virtual"; + identifier.uniqueId = "<virtual>"; + setDescriptor(identifier); + + Device* device = new Device(-1, VIRTUAL_KEYBOARD_ID, String8("<virtual>"), identifier); + device->classes = INPUT_DEVICE_CLASS_KEYBOARD + | INPUT_DEVICE_CLASS_ALPHAKEY + | INPUT_DEVICE_CLASS_DPAD + | INPUT_DEVICE_CLASS_VIRTUAL; + loadKeyMapLocked(device); + addDeviceLocked(device); +} + +void EventHub::addDeviceLocked(Device* device) { + mDevices.add(device->id, device); device->next = mOpeningDevices; mOpeningDevices = device; - return 0; } void EventHub::loadConfigurationLocked(Device* device) { @@ -1224,11 +1250,13 @@ void EventHub::closeDeviceLocked(Device* device) { if (device->id == mBuiltInKeyboardId) { ALOGW("built-in keyboard device %s (id=%d) is closing! the apps will not like this", device->path.string(), mBuiltInKeyboardId); - mBuiltInKeyboardId = -1; + mBuiltInKeyboardId = NO_BUILT_IN_KEYBOARD; } - if (epoll_ctl(mEpollFd, EPOLL_CTL_DEL, device->fd, NULL)) { - ALOGW("Could not remove device fd from epoll instance. errno=%d", errno); + if (!device->isVirtual()) { + if (epoll_ctl(mEpollFd, EPOLL_CTL_DEL, device->fd, NULL)) { + ALOGW("Could not remove device fd from epoll instance. errno=%d", errno); + } } mDevices.removeItem(device->id); diff --git a/services/input/EventHub.h b/services/input/EventHub.h index bd21a3d..c35df109 100644 --- a/services/input/EventHub.h +++ b/services/input/EventHub.h @@ -19,6 +19,7 @@ #define _RUNTIME_EVENT_HUB_H #include <androidfw/Input.h> +#include <androidfw/InputDevice.h> #include <androidfw/Keyboard.h> #include <androidfw/KeyLayoutMap.h> #include <androidfw/KeyCharacterMap.h> @@ -43,6 +44,13 @@ namespace android { +enum { + // Device id of a special "virtual" keyboard that is always present. + VIRTUAL_KEYBOARD_ID = -1, + // Device id of the "built-in" keyboard if there is one. + BUILT_IN_KEYBOARD_ID = 0, +}; + /* * A raw event as retrieved from the EventHub. */ @@ -107,6 +115,9 @@ enum { /* The input device is a joystick (implies gamepad, has joystick absolute axes). */ INPUT_DEVICE_CLASS_JOYSTICK = 0x00000100, + /* The input device is virtual (not a real device, not part of UI configuration). */ + INPUT_DEVICE_CLASS_VIRTUAL = 0x40000000, + /* The input device is external (not built-in). */ INPUT_DEVICE_CLASS_EXTERNAL = 0x80000000, }; @@ -208,7 +219,7 @@ public: virtual void getVirtualKeyDefinitions(int32_t deviceId, Vector<VirtualKeyDefinition>& outVirtualKeys) const = 0; - virtual String8 getKeyCharacterMapFile(int32_t deviceId) const = 0; + virtual sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const = 0; /* Requests the EventHub to reopen all input devices on the next call to getEvents(). */ virtual void requestReopenDevices() = 0; @@ -266,7 +277,7 @@ public: virtual void getVirtualKeyDefinitions(int32_t deviceId, Vector<VirtualKeyDefinition>& outVirtualKeys) const; - virtual String8 getKeyCharacterMapFile(int32_t deviceId) const; + virtual sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const; virtual void requestReopenDevices(); @@ -282,7 +293,7 @@ private: struct Device { Device* next; - int fd; + int fd; // may be -1 if device is virtual const int32_t id; const String8 path; const InputDeviceIdentifier identifier; @@ -305,11 +316,15 @@ private: ~Device(); void close(); + + inline bool isVirtual() const { return fd < 0; } }; status_t openDeviceLocked(const char *devicePath); - status_t closeDeviceByPathLocked(const char *devicePath); + void createVirtualKeyboardLocked(); + void addDeviceLocked(Device* device); + status_t closeDeviceByPathLocked(const char *devicePath); void closeDeviceLocked(Device* device); void closeAllDevicesLocked(); @@ -331,8 +346,13 @@ private: // Protect all internal state. mutable Mutex mLock; - // The actual id of the built-in keyboard, or -1 if none. + // The actual id of the built-in keyboard, or NO_BUILT_IN_KEYBOARD if none. // EventHub remaps the built-in keyboard to id 0 externally as required by the API. + enum { + // Must not conflict with any other assigned device ids, including + // the virtual keyboard id (-1). + NO_BUILT_IN_KEYBOARD = -2, + }; int32_t mBuiltInKeyboardId; int32_t mNextDeviceId; diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp index ddd870d..42512d8 100644 --- a/services/input/InputReader.cpp +++ b/services/input/InputReader.cpp @@ -523,19 +523,21 @@ void InputReader::updateInputConfigurationLocked() { InputDeviceInfo deviceInfo; for (size_t i = 0; i < mDevices.size(); i++) { InputDevice* device = mDevices.valueAt(i); - device->getDeviceInfo(& deviceInfo); - uint32_t sources = deviceInfo.getSources(); + if (!(device->getClasses() & INPUT_DEVICE_CLASS_VIRTUAL)) { + device->getDeviceInfo(& deviceInfo); + uint32_t sources = deviceInfo.getSources(); - if ((sources & AINPUT_SOURCE_TOUCHSCREEN) == AINPUT_SOURCE_TOUCHSCREEN) { - touchScreenConfig = InputConfiguration::TOUCHSCREEN_FINGER; - } - if ((sources & AINPUT_SOURCE_TRACKBALL) == AINPUT_SOURCE_TRACKBALL) { - navigationConfig = InputConfiguration::NAVIGATION_TRACKBALL; - } else if ((sources & AINPUT_SOURCE_DPAD) == AINPUT_SOURCE_DPAD) { - navigationConfig = InputConfiguration::NAVIGATION_DPAD; - } - if (deviceInfo.getKeyboardType() == AINPUT_KEYBOARD_TYPE_ALPHABETIC) { - keyboardConfig = InputConfiguration::KEYBOARD_QWERTY; + if ((sources & AINPUT_SOURCE_TOUCHSCREEN) == AINPUT_SOURCE_TOUCHSCREEN) { + touchScreenConfig = InputConfiguration::TOUCHSCREEN_FINGER; + } + if ((sources & AINPUT_SOURCE_TRACKBALL) == AINPUT_SOURCE_TRACKBALL) { + navigationConfig = InputConfiguration::NAVIGATION_TRACKBALL; + } else if ((sources & AINPUT_SOURCE_DPAD) == AINPUT_SOURCE_DPAD) { + navigationConfig = InputConfiguration::NAVIGATION_DPAD; + } + if (deviceInfo.getKeyboardType() == AINPUT_KEYBOARD_TYPE_ALPHABETIC) { + keyboardConfig = InputConfiguration::KEYBOARD_QWERTY; + } } } @@ -1789,7 +1791,7 @@ void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) { InputMapper::populateDeviceInfo(info); info->setKeyboardType(mKeyboardType); - info->setKeyCharacterMapFile(getEventHub()->getKeyCharacterMapFile(getDeviceId())); + info->setKeyCharacterMap(getEventHub()->getKeyCharacterMap(getDeviceId())); } void KeyboardInputMapper::dump(String8& dump) { diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp index 2cccf9f..057ad18 100644 --- a/services/input/tests/InputReader_test.cpp +++ b/services/input/tests/InputReader_test.cpp @@ -610,8 +610,8 @@ private: } } - virtual String8 getKeyCharacterMapFile(int32_t deviceId) const { - return String8(); + virtual sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const { + return NULL; } virtual bool isExternal(int32_t deviceId) const { diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java index 96ee2f0..ca7241c 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/java/com/android/server/InputMethodManagerService.java @@ -27,6 +27,7 @@ import com.android.internal.view.IInputMethodManager; import com.android.internal.view.IInputMethodSession; import com.android.internal.view.InputBindResult; import com.android.server.EventLogTags; +import com.android.server.wm.WindowManagerService; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -91,7 +92,10 @@ import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodSubtype; import android.widget.ArrayAdapter; +import android.widget.CompoundButton; +import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.RadioButton; +import android.widget.Switch; import android.widget.TextView; import java.io.File; @@ -134,6 +138,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub static final int MSG_UNBIND_METHOD = 3000; static final int MSG_BIND_METHOD = 3010; + static final int MSG_HARD_KEYBOARD_SWITCH_CHANGED = 4000; + static final long TIME_TO_RECONNECT = 10*1000; static final int SECURE_SUGGESTION_SPANS_MAX_SIZE = 20; @@ -156,6 +162,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub final HandlerCaller mCaller; private final InputMethodFileManager mFileManager; private final InputMethodAndSubtypeListManager mImListManager; + private final HardKeyboardListener mHardKeyboardListener; + private final WindowManagerService mWindowManagerService; final InputBindResult mNoBinding = new InputBindResult(null, null, -1); @@ -360,6 +368,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub private AlertDialog.Builder mDialogBuilder; private AlertDialog mSwitchingDialog; + private View mSwitchingDialogTitleView; private InputMethodInfo[] mIms; private int[] mSubtypeIds; @@ -528,7 +537,31 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } - public InputMethodManagerService(Context context) { + private class HardKeyboardListener + implements WindowManagerService.OnHardKeyboardStatusChangeListener { + @Override + public void onHardKeyboardStatusChange(boolean available, boolean enabled) { + mHandler.sendMessage(mHandler.obtainMessage( + MSG_HARD_KEYBOARD_SWITCH_CHANGED, available ? 1 : 0, enabled ? 1 : 0)); + } + + public void handleHardKeyboardStatusChange(boolean available, boolean enabled) { + if (DEBUG) { + Slog.w(TAG, "HardKeyboardStatusChanged: available = " + available + ", enabled = " + + enabled); + } + synchronized(mMethodMap) { + if (mSwitchingDialog != null && mSwitchingDialogTitleView != null + && mSwitchingDialog.isShowing()) { + mSwitchingDialogTitleView.findViewById( + com.android.internal.R.id.hard_keyboard_section).setVisibility( + available ? View.VISIBLE : View.GONE); + } + } + } + } + + public InputMethodManagerService(Context context, WindowManagerService windowManager) { mContext = context; mRes = context.getResources(); mHandler = new Handler(this); @@ -540,6 +573,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub handleMessage(msg); } }); + mWindowManagerService = windowManager; + mHardKeyboardListener = new HardKeyboardListener(); mImeSwitcherNotification = new Notification(); mImeSwitcherNotification.icon = com.android.internal.R.drawable.ic_notification_ime_default; @@ -633,6 +668,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub updateImeWindowStatusLocked(); mShowOngoingImeSwitcherForPhones = mRes.getBoolean( com.android.internal.R.bool.show_ongoing_ime_switcher); + if (mShowOngoingImeSwitcherForPhones) { + mWindowManagerService.setOnHardKeyboardStatusChangeListener( + mHardKeyboardListener); + } try { startInputInnerLocked(); } catch (RuntimeException e) { @@ -1994,6 +2033,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub Slog.w(TAG, "Client died receiving input method " + args.arg2); } return true; + + // -------------------------------------------------------------- + case MSG_HARD_KEYBOARD_SWITCH_CHANGED: + mHardKeyboardListener.handleHardKeyboardStatusChange( + msg.arg1 == 1, msg.arg2 == 1); + return true; } return false; } @@ -2204,12 +2249,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } } - final TypedArray a = context.obtainStyledAttributes(null, com.android.internal.R.styleable.DialogPreference, com.android.internal.R.attr.alertDialogStyle, 0); mDialogBuilder = new AlertDialog.Builder(context) - .setTitle(com.android.internal.R.string.select_input_method) .setOnCancelListener(new OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { @@ -2219,6 +2262,29 @@ public class InputMethodManagerService extends IInputMethodManager.Stub .setIcon(a.getDrawable( com.android.internal.R.styleable.DialogPreference_dialogTitle)); a.recycle(); + final LayoutInflater inflater = + (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + final View tv = inflater.inflate( + com.android.internal.R.layout.input_method_switch_dialog_title, null); + mDialogBuilder.setCustomTitle(tv); + + // Setup layout for a toggle switch of the hardware keyboard + mSwitchingDialogTitleView = tv; + mSwitchingDialogTitleView.findViewById( + com.android.internal.R.id.hard_keyboard_section).setVisibility( + mWindowManagerService.isHardKeyboardAvailable() ? + View.VISIBLE : View.GONE); + final Switch hardKeySwitch = ((Switch)mSwitchingDialogTitleView.findViewById( + com.android.internal.R.id.hard_keyboard_switch)); + hardKeySwitch.setChecked(mWindowManagerService.isHardKeyboardEnabled()); + hardKeySwitch.setOnCheckedChangeListener( + new OnCheckedChangeListener() { + @Override + public void onCheckedChanged( + CompoundButton buttonView, boolean isChecked) { + mWindowManagerService.setHardKeyboardEnabled(isChecked); + } + }); final ImeSubtypeListAdapter adapter = new ImeSubtypeListAdapter(context, com.android.internal.R.layout.simple_list_item_2_single_choice, imList, diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java index bebce7e..2d2a881 100644 --- a/services/java/com/android/server/PowerManagerService.java +++ b/services/java/com/android/server/PowerManagerService.java @@ -1795,7 +1795,7 @@ public class PowerManagerService extends IPowerManager.Stub final boolean stateChanged = mPowerState != newState; if (stateChanged && reason == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT) { - if (mPolicy.isScreenSaverEnabled()) { + if (mPolicy != null && mPolicy.isScreenSaverEnabled()) { if (mSpew) { Slog.d(TAG, "setPowerState: running screen saver instead of turning off screen"); } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 68bbb571..241d04f 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -276,7 +276,7 @@ class ServerThread extends Thread { if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { try { Slog.i(TAG, "Input Method Service"); - imm = new InputMethodManagerService(context); + imm = new InputMethodManagerService(context, wm); ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm); } catch (Throwable e) { reportWtf("starting Input Manager Service", e); diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 80e59cd..78b441a 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -3181,7 +3181,7 @@ public final class ActivityManagerService extends ActivityManagerNative } // Log the ANR to the main log. - StringBuilder info = mStringBuilder; + StringBuilder info = new StringBuilder(); info.setLength(0); info.append("ANR in ").append(app.processName); if (activity != null && activity.shortComponentName != null) { @@ -13444,7 +13444,7 @@ public final class ActivityManagerService extends ActivityManagerNative // an earlier hidden adjustment that isn't really for us... if // so, use the new hidden adjustment. if (!recursed && app.hidden) { - app.curAdj = app.curRawAdj = hiddenAdj; + app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj; } return app.curRawAdj; } @@ -13468,7 +13468,7 @@ public final class ActivityManagerService extends ActivityManagerNative // below foreground, so it is not worth doing work for it. app.adjType = "fixed"; app.adjSeq = mAdjSeq; - app.curRawAdj = app.maxAdj; + app.curRawAdj = app.nonStoppingAdj = app.maxAdj; app.foregroundActivities = false; app.keeping = true; app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; @@ -13545,6 +13545,8 @@ public final class ActivityManagerService extends ActivityManagerNative app.adjType = "bg-empty"; } + boolean hasStoppingActivities = false; + // Examine all activities if not already foreground. if (!app.foregroundActivities && activitiesSize > 0) { for (int j = 0; j < activitiesSize; j++) { @@ -13559,15 +13561,20 @@ public final class ActivityManagerService extends ActivityManagerNative app.hidden = false; app.foregroundActivities = true; break; - } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED - || r.state == ActivityState.STOPPING) { - // Only upgrade adjustment. + } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { adj = ProcessList.PERCEPTIBLE_APP_ADJ; - app.adjType = "stopping"; + app.adjType = "pausing"; } app.hidden = false; app.foregroundActivities = true; + } else if (r.state == ActivityState.STOPPING) { + // We will apply the actual adjustment later, because + // we want to allow this process to immediately go through + // any memory trimming that is in effect. + app.hidden = false; + app.foregroundActivities = true; + hasStoppingActivities = true; } } } @@ -13625,7 +13632,7 @@ public final class ActivityManagerService extends ActivityManagerNative // this gives us a baseline and makes sure we don't get into an // infinite recursion. app.adjSeq = mAdjSeq; - app.curRawAdj = adj; + app.curRawAdj = app.nonStoppingAdj = adj; if (mBackupTarget != null && app == mBackupTarget.app) { // If possible we want to avoid killing apps while they're being backed up @@ -13882,6 +13889,28 @@ public final class ActivityManagerService extends ActivityManagerNative } } + if (adj == ProcessList.SERVICE_ADJ) { + if (doingAll) { + app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); + mNewNumServiceProcs++; + } + if (app.serviceb) { + adj = ProcessList.SERVICE_B_ADJ; + } + } else { + app.serviceb = false; + } + + app.nonStoppingAdj = adj; + + if (hasStoppingActivities) { + // Only upgrade adjustment. + if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { + adj = ProcessList.PERCEPTIBLE_APP_ADJ; + app.adjType = "stopping"; + } + } + app.curRawAdj = adj; //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + @@ -13915,18 +13944,6 @@ public final class ActivityManagerService extends ActivityManagerNative } } - if (adj == ProcessList.SERVICE_ADJ) { - if (doingAll) { - app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); - mNewNumServiceProcs++; - } - if (app.serviceb) { - adj = ProcessList.SERVICE_B_ADJ; - } - } else { - app.serviceb = false; - } - app.curAdj = adj; app.curSchedGroup = schedGroup; @@ -14138,7 +14155,7 @@ public final class ActivityManagerService extends ActivityManagerNative } // If a process has held a wake lock for more // than 50% of the time during this period, - // that sounds pad. Kill! + // that sounds bad. Kill! if (doWakeKills && realtimeSince > 0 && ((wtimeUsed*100)/realtimeSince) >= 50) { synchronized (stats) { @@ -14186,23 +14203,6 @@ public final class ActivityManagerService extends ActivityManagerNative computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll); if (app.curRawAdj != app.setRawAdj) { - if (false) { - // Removing for now. Forcing GCs is not so useful anymore - // with Dalvik, and the new memory level hint facility is - // better for what we need to do these days. - if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ - && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) { - // If this app is transitioning from foreground to - // non-foreground, have it do a gc. - scheduleAppGcLocked(app); - } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ - && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { - // Likewise do a gc when an app is moving in to the - // background (such as a service stopping). - scheduleAppGcLocked(app); - } - } - if (wasKeeping && !app.keeping) { // This app is no longer something we want to keep. Note // its current wake lock time to later know to kill it if @@ -14319,6 +14319,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (factor < 1) factor = 1; int step = 0; int numHidden = 0; + int numTrimming = 0; // First update the OOM adjustment for each of the // application processes based on their current state. @@ -14363,6 +14364,11 @@ public final class ActivityManagerService extends ActivityManagerNative app.killedBackground = true; Process.killProcessQuiet(app.pid); } + if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ + && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ + && !app.killedBackground) { + numTrimming++; + } } } @@ -14376,7 +14382,7 @@ public final class ActivityManagerService extends ActivityManagerNative // memory they want. if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) { final int N = mLruProcesses.size(); - factor = numHidden/3; + factor = numTrimming/3; int minFactor = 2; if (mHomeProcess != null) minFactor++; if (mPreviousProcess != null) minFactor++; @@ -14393,8 +14399,8 @@ public final class ActivityManagerService extends ActivityManagerNative int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; for (i=0; i<N; i++) { ProcessRecord app = mLruProcesses.get(i); - if (app.curAdj >= ProcessList.HOME_APP_ADJ - && app.curAdj != ProcessList.SERVICE_B_ADJ + if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ + && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ && !app.killedBackground) { if (app.trimMemoryLevel < curLevel && app.thread != null) { try { @@ -14426,7 +14432,7 @@ public final class ActivityManagerService extends ActivityManagerNative break; } } - } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { + } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND && app.thread != null) { try { @@ -14437,7 +14443,7 @@ public final class ActivityManagerService extends ActivityManagerNative } app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; } else { - if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) + if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) && app.pendingUiClean) { // If this application is now in the background and it // had done UI, then give it the special trim level to @@ -14464,7 +14470,7 @@ public final class ActivityManagerService extends ActivityManagerNative final int N = mLruProcesses.size(); for (i=0; i<N; i++) { ProcessRecord app = mLruProcesses.get(i); - if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) + if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) && app.pendingUiClean) { if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN && app.thread != null) { diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index a01ed25..6596e1f 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -97,6 +97,11 @@ final class ActivityStack { // next activity. static final int PAUSE_TIMEOUT = 500; + // How long we wait for the activity to tell us it has stopped before + // giving up. This is a good amount of time because we really need this + // from the application in order to get its saved state. + static final int STOP_TIMEOUT = 10*1000; + // How long we can hold the sleep wake lock before giving up. static final int SLEEP_TIMEOUT = 5*1000; @@ -280,6 +285,7 @@ final class ActivityStack { static final int DESTROY_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 5; static final int RESUME_TOP_ACTIVITY_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 6; static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 7; + static final int STOP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 8; final Handler mHandler = new Handler() { //public Handler() { @@ -364,6 +370,17 @@ final class ActivityStack { resumeTopActivityLocked(null); } } break; + case STOP_TIMEOUT_MSG: { + ActivityRecord r = (ActivityRecord)msg.obj; + // We don't at this point know if the activity is fullscreen, + // so we need to be conservative and assume it isn't. + Slog.w(TAG, "Activity stop timeout for " + r); + synchronized (mService) { + if (r.isInHistory()) { + activityStoppedLocked(r, null, null, null); + } + } + } break; } } }; @@ -1000,31 +1017,38 @@ final class ActivityStack { final void activityStoppedLocked(ActivityRecord r, Bundle icicle, Bitmap thumbnail, CharSequence description) { if (DEBUG_SAVED_STATE) Slog.i(TAG, "Saving icicle of " + r + ": " + icicle); - r.icicle = icicle; - r.haveState = true; - r.updateThumbnail(thumbnail, description); - r.stopped = true; - if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r + " (stop complete)"); - r.state = ActivityState.STOPPED; - if (!r.finishing) { - if (r.configDestroy) { - destroyActivityLocked(r, true, false, "stop-config"); - resumeTopActivityLocked(null); - } else { - // Now that this process has stopped, we may want to consider - // it to be the previous app to try to keep around in case - // the user wants to return to it. - ProcessRecord fgApp = null; - if (mResumedActivity != null) { - fgApp = mResumedActivity.app; - } else if (mPausingActivity != null) { - fgApp = mPausingActivity.app; - } - if (r.app != null && fgApp != null && r.app != fgApp - && r.lastVisibleTime > mService.mPreviousProcessVisibleTime - && r.app != mService.mHomeProcess) { - mService.mPreviousProcess = r.app; - mService.mPreviousProcessVisibleTime = r.lastVisibleTime; + if (icicle != null) { + // If icicle is null, this is happening due to a timeout, so we + // haven't really saved the state. + r.icicle = icicle; + r.haveState = true; + r.updateThumbnail(thumbnail, description); + } + if (!r.stopped) { + if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r + " (stop complete)"); + mHandler.removeMessages(STOP_TIMEOUT_MSG, r); + r.stopped = true; + r.state = ActivityState.STOPPED; + if (!r.finishing) { + if (r.configDestroy) { + destroyActivityLocked(r, true, false, "stop-config"); + resumeTopActivityLocked(null); + } else { + // Now that this process has stopped, we may want to consider + // it to be the previous app to try to keep around in case + // the user wants to return to it. + ProcessRecord fgApp = null; + if (mResumedActivity != null) { + fgApp = mResumedActivity.app; + } else if (mPausingActivity != null) { + fgApp = mPausingActivity.app; + } + if (r.app != null && fgApp != null && r.app != fgApp + && r.lastVisibleTime > mService.mPreviousProcessVisibleTime + && r.app != mService.mHomeProcess) { + mService.mPreviousProcess = r.app; + mService.mPreviousProcessVisibleTime = r.lastVisibleTime; + } } } } @@ -3228,6 +3252,9 @@ final class ActivityStack { if (mService.isSleeping()) { r.setSleeping(true); } + Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG); + msg.obj = r; + mHandler.sendMessageDelayed(msg, STOP_TIMEOUT); } catch (Exception e) { // Maybe just ignore exceptions here... if the process // has crashed, our death notification will clean things @@ -3694,6 +3721,7 @@ final class ActivityStack { // Get rid of any pending idle timeouts. mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); + mHandler.removeMessages(STOP_TIMEOUT_MSG, r); mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r); r.finishLaunchTickingLocked(); diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java index b64261d..4529ecc 100644 --- a/services/java/com/android/server/am/ProcessRecord.java +++ b/services/java/com/android/server/am/ProcessRecord.java @@ -63,6 +63,7 @@ class ProcessRecord { int hiddenAdj; // If hidden, this is the adjustment to use int curRawAdj; // Current OOM unlimited adjustment for this process int setRawAdj; // Last set OOM unlimited adjustment for this process + int nonStoppingAdj; // Adjustment not counting any stopping activities int curAdj; // Current OOM adjustment for this process int setAdj; // Last set OOM adjustment for this process int curSchedGroup; // Currently desired scheduling class @@ -199,6 +200,7 @@ class ProcessRecord { pw.print(" hidden="); pw.print(hiddenAdj); pw.print(" curRaw="); pw.print(curRawAdj); pw.print(" setRaw="); pw.print(setRawAdj); + pw.print(" nonStopping="); pw.print(nonStoppingAdj); pw.print(" cur="); pw.print(curAdj); pw.print(" set="); pw.println(setAdj); pw.print(prefix); pw.print("curSchedGroup="); pw.print(curSchedGroup); diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java index b8cc65e..2f25df1 100644 --- a/services/java/com/android/server/input/InputManagerService.java +++ b/services/java/com/android/server/input/InputManagerService.java @@ -18,37 +18,45 @@ package com.android.server.input; import com.android.internal.util.XmlUtils; import com.android.server.Watchdog; -import com.android.server.input.InputFilter.Host; -import com.android.server.wm.WindowManagerService; import org.xmlpull.v1.XmlPullParser; +import android.content.ComponentName; import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Configuration; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.content.res.XmlResourceParser; import android.database.ContentObserver; import android.hardware.input.IInputManager; import android.hardware.input.InputManager; +import android.hardware.input.KeyboardLayout; import android.os.Binder; +import android.os.Bundle; import android.os.Environment; import android.os.Handler; -import android.os.Looper; import android.os.MessageQueue; import android.os.Process; -import android.os.SystemProperties; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; +import android.util.Log; import android.util.Slog; import android.util.Xml; import android.view.InputChannel; import android.view.InputDevice; import android.view.InputEvent; +import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.PointerIcon; import android.view.Surface; import android.view.ViewConfiguration; -import android.view.WindowManager; import android.view.WindowManagerPolicy; +import android.view.KeyCharacterMap.UnavailableException; import java.io.File; import java.io.FileDescriptor; @@ -57,6 +65,8 @@ import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; /* * Wraps the C++ InputManager and provides its callbacks. @@ -135,6 +145,10 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog. /** The key is down but is a virtual key press that is being emulated by the system. */ public static final int KEY_STATE_VIRTUAL = 2; + // Used to simulate a persistent data store for keyboard layouts. + // TODO: Replace with the real thing. + private final HashMap<String, String> mFakeRegistry = new HashMap<String, String>(); + // State for the currently installed input filter. final Object mInputFilterLock = new Object(); InputFilter mInputFilter; @@ -246,7 +260,7 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog. * key codes. * @return True if the lookup was successful, false otherwise. */ - @Override + @Override // Binder call public boolean hasKeys(int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists) { if (keyCodes == null) { throw new IllegalArgumentException("keyCodes must not be null."); @@ -337,7 +351,7 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog. } } - @Override + @Override // Binder call public boolean injectInputEvent(InputEvent event, int mode) { if (event == null) { throw new IllegalArgumentException("event must not be null"); @@ -380,7 +394,7 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog. * @param id The device id. * @return The input device or null if not found. */ - @Override + @Override // Binder call public InputDevice getInputDevice(int deviceId) { return nativeGetInputDevice(mPtr, deviceId); } @@ -389,11 +403,187 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog. * Gets the ids of all input devices in the system. * @return The input device ids. */ - @Override + @Override // Binder call public int[] getInputDeviceIds() { return nativeGetInputDeviceIds(mPtr); } - + + @Override // Binder call + public KeyboardLayout[] getKeyboardLayouts() { + ArrayList<KeyboardLayout> list = new ArrayList<KeyboardLayout>(); + + final PackageManager pm = mContext.getPackageManager(); + Intent intent = new Intent(InputManager.ACTION_QUERY_KEYBOARD_LAYOUTS); + for (ResolveInfo resolveInfo : pm.queryBroadcastReceivers(intent, + PackageManager.GET_META_DATA)) { + loadKeyboardLayouts(pm, resolveInfo.activityInfo, list, null); + } + return list.toArray(new KeyboardLayout[list.size()]); + } + + @Override // Binder call + public KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor) { + if (keyboardLayoutDescriptor == null) { + throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null"); + } + + KeyboardLayoutDescriptor d = KeyboardLayoutDescriptor.parse(keyboardLayoutDescriptor); + if (d == null) { + return null; + } + + final PackageManager pm = mContext.getPackageManager(); + try { + ActivityInfo receiver = pm.getReceiverInfo( + new ComponentName(d.packageName, d.receiverName), + PackageManager.GET_META_DATA); + return loadKeyboardLayouts(pm, receiver, null, d.keyboardLayoutName); + } catch (NameNotFoundException ex) { + Log.w(TAG, "Could not load keyboard layout '" + d.keyboardLayoutName + + "' from receiver " + d.packageName + "/" + d.receiverName, ex); + return null; + } + } + + private KeyboardLayout loadKeyboardLayouts( + PackageManager pm, ActivityInfo receiver, + List<KeyboardLayout> list, String keyboardName) { + Bundle metaData = receiver.metaData; + if (metaData == null) { + return null; + } + + int configResId = metaData.getInt(InputManager.META_DATA_KEYBOARD_LAYOUTS); + if (configResId == 0) { + Log.w(TAG, "Missing meta-data '" + InputManager.META_DATA_KEYBOARD_LAYOUTS + + "' on receiver " + receiver.packageName + "/" + receiver.name); + return null; + } + + try { + Resources resources = pm.getResourcesForApplication(receiver.applicationInfo); + XmlResourceParser parser = resources.getXml(configResId); + try { + XmlUtils.beginDocument(parser, "keyboard-layouts"); + + for (;;) { + XmlUtils.nextElement(parser); + String element = parser.getName(); + if (element == null) { + break; + } + if (element.equals("keyboard-layout")) { + TypedArray a = resources.obtainAttributes( + parser, com.android.internal.R.styleable.KeyboardLayout); + try { + String name = a.getString( + com.android.internal.R.styleable.KeyboardLayout_name); + String label = a.getString( + com.android.internal.R.styleable.KeyboardLayout_label); + int kcmResId = a.getResourceId( + com.android.internal.R.styleable.KeyboardLayout_kcm, 0); + if (name == null || label == null || kcmResId == 0) { + Log.w(TAG, "Missing required 'name', 'label' or 'kcm' " + + "attributes in keyboard layout " + + "resource from receiver " + + receiver.packageName + "/" + receiver.name); + } else { + String descriptor = KeyboardLayoutDescriptor.format( + receiver.packageName, receiver.name, name); + KeyboardLayout c = new KeyboardLayout(descriptor, label); + if (keyboardName != null && name.equals(keyboardName)) { + return c; + } + if (list != null) { + list.add(c); + } + } + } finally { + a.recycle(); + } + } else { + Log.w(TAG, "Skipping unrecognized element '" + element + + "' in keyboard layout resource from receiver " + + receiver.packageName + "/" + receiver.name); + } + } + } finally { + parser.close(); + } + } catch (Exception ex) { + Log.w(TAG, "Could not load keyboard layout resource from receiver " + + receiver.packageName + "/" + receiver.name, ex); + return null; + } + if (keyboardName != null) { + Log.w(TAG, "Could not load keyboard layout '" + keyboardName + + "' from receiver " + receiver.packageName + "/" + receiver.name + + " because it was not declared in the keyboard layout resource."); + } + return null; + } + + @Override // Binder call + public String getKeyboardLayoutForInputDevice(String inputDeviceDescriptor) { + if (inputDeviceDescriptor == null) { + throw new IllegalArgumentException("inputDeviceDescriptor must not be null"); + } + + return mFakeRegistry.get(inputDeviceDescriptor); + } + + @Override // Binder call + public void setKeyboardLayoutForInputDevice(String inputDeviceDescriptor, + String keyboardLayoutDescriptor) { + if (!checkCallingPermission(android.Manifest.permission.SET_KEYBOARD_LAYOUT, + "setKeyboardLayoutForInputDevice()")) { + throw new SecurityException("Requires SET_KEYBOARD_LAYOUT permission"); + } + + if (inputDeviceDescriptor == null) { + throw new IllegalArgumentException("inputDeviceDescriptor must not be null"); + } + + mFakeRegistry.put(inputDeviceDescriptor, keyboardLayoutDescriptor); + } + + /** + * Loads the key character map associated with the keyboard layout. + * + * @param pm The package manager. + * @return The key character map, or null if it could not be loaded for any reason. + * + public KeyCharacterMap loadKeyCharacterMap(PackageManager pm) { + if (pm == null) { + throw new IllegalArgumentException("pm must not be null"); + } + + if (mKeyCharacterMap == null) { + KeyboardLayoutDescriptor d = InputManager.parseKeyboardLayoutDescriptor(mDescriptor); + if (d == null) { + Log.e(InputManager.TAG, "Could not load key character map '" + mDescriptor + + "' because the descriptor could not be parsed."); + return null; + } + + CharSequence cs = pm.getText(d.packageName, mKeyCharacterMapResId, null); + if (cs == null) { + Log.e(InputManager.TAG, "Could not load key character map '" + mDescriptor + + "' because its associated resource could not be loaded."); + return null; + } + + try { + mKeyCharacterMap = KeyCharacterMap.load(cs); + } catch (UnavailableException ex) { + Log.e(InputManager.TAG, "Could not load key character map '" + mDescriptor + + "' due to an error while parsing.", ex); + return null; + } + } + return mKeyCharacterMap; + }*/ + public void setInputWindows(InputWindowHandle[] windowHandles) { nativeSetInputWindows(mPtr, windowHandles); } @@ -433,18 +623,17 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog. return nativeTransferTouchFocus(mPtr, fromChannel, toChannel); } - /** - * Set the pointer speed. - * @param speed The pointer speed as a value between -7 (slowest) and 7 (fastest) - * where 0 is the default speed. - */ - @Override + @Override // Binder call public void tryPointerSpeed(int speed) { if (!checkCallingPermission(android.Manifest.permission.SET_POINTER_SPEED, "tryPointerSpeed()")) { throw new SecurityException("Requires SET_POINTER_SPEED permission"); } + if (speed < InputManager.MIN_POINTER_SPEED || speed > InputManager.MAX_POINTER_SPEED) { + throw new IllegalArgumentException("speed out of range"); + } + setPointerSpeedUnchecked(speed); } @@ -740,4 +929,32 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog. } } } + + private static final class KeyboardLayoutDescriptor { + public String packageName; + public String receiverName; + public String keyboardLayoutName; + + public static String format(String packageName, + String receiverName, String keyboardName) { + return packageName + "/" + receiverName + "/" + keyboardName; + } + + public static KeyboardLayoutDescriptor parse(String descriptor) { + int pos = descriptor.indexOf('/'); + if (pos < 0 || pos + 1 == descriptor.length()) { + return null; + } + int pos2 = descriptor.indexOf('/', pos + 1); + if (pos2 < pos + 2 || pos2 + 1 == descriptor.length()) { + return null; + } + + KeyboardLayoutDescriptor result = new KeyboardLayoutDescriptor(); + result.packageName = descriptor.substring(0, pos); + result.receiverName = descriptor.substring(pos + 1, pos2); + result.keyboardLayoutName = descriptor.substring(pos2 + 1); + return result; + } + } } diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java index 0d64b68..0be6612 100644 --- a/services/java/com/android/server/wm/WindowAnimator.java +++ b/services/java/com/android/server/wm/WindowAnimator.java @@ -453,7 +453,7 @@ public class WindowAnimator { mDimAnimator.updateParameters(mContext.getResources(), mDimParams, mCurrentTime); } if (mDimAnimator != null && mDimAnimator.mDimShown) { - mAnimating |= mDimAnimator.updateSurface(mDimParams != null, mCurrentTime, + mAnimating |= mDimAnimator.updateSurface(isDimming(), mCurrentTime, !mService.okToDisplay()); } @@ -471,9 +471,7 @@ public class WindowAnimator { Surface.closeTransaction(); } - if (mBulkUpdateParams != 0) { - mService.bulkSetParameters(mBulkUpdateParams); - } + mService.bulkSetParameters(mBulkUpdateParams); } WindowState mCurrentFocus; @@ -503,6 +501,10 @@ public class WindowAnimator { mService.mH.sendMessage(mService.mH.obtainMessage(SET_DIM_PARAMETERS, null)); } + boolean isDimming() { + return mDimParams != null; + } + public void dump(PrintWriter pw, String prefix, boolean dumpAll) { if (mWindowDetachedWallpaper != null) { pw.print(" mWindowDetachedWallpaper="); pw.println(mWindowDetachedWallpaper); diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 00972fa..d9425aa 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -6882,22 +6882,33 @@ public class WindowManagerService extends IWindowManager.Stub case BULK_UPDATE_PARAMETERS: { // Used to send multiple changes from the animation side to the layout side. synchronized (mWindowMap) { + boolean doRequest = false; // TODO(cmautner): As the number of bits grows, use masks of bit groups to // eliminate unnecessary tests. if ((msg.arg1 & LayoutFields.SET_UPDATE_ROTATION) != 0) { mInnerFields.mUpdateRotation = true; + doRequest = true; } if ((msg.arg1 & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) { mInnerFields.mWallpaperMayChange = true; + doRequest = true; } if ((msg.arg1 & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) { mInnerFields.mWallpaperForceHidingChanged = true; + doRequest = true; } if ((msg.arg1 & LayoutFields.CLEAR_ORIENTATION_CHANGE_COMPLETE) != 0) { mInnerFields.mOrientationChangeComplete = false; + } else { + mInnerFields.mOrientationChangeComplete = true; + if (mWindowsFreezingScreen) { + doRequest = true; + } } - requestTraversalLocked(); + if (doRequest) { + requestTraversalLocked(); + } } break; } @@ -6908,8 +6919,6 @@ public class WindowManagerService extends IWindowManager.Stub (Pair<WindowStateAnimator, Region>) msg.obj; final WindowStateAnimator winAnimator = pair.first; winAnimator.setTransparentRegionHint(pair.second); - - scheduleAnimationLocked(); break; } @@ -8012,16 +8021,18 @@ public class WindowManagerService extends IWindowManager.Stub if (!mInnerFields.mDimming) { //Slog.i(TAG, "DIM BEHIND: " + w); mInnerFields.mDimming = true; - final int width, height; - if (attrs.type == WindowManager.LayoutParams.TYPE_BOOT_PROGRESS) { - width = mCurDisplayWidth; - height = mCurDisplayHeight; - } else { - width = innerDw; - height = innerDh; + if (!mAnimator.isDimming()) { + final int width, height; + if (attrs.type == WindowManager.LayoutParams.TYPE_BOOT_PROGRESS) { + width = mCurDisplayWidth; + height = mCurDisplayHeight; + } else { + width = innerDw; + height = innerDh; + } + mAnimator.startDimming(w.mWinAnimator, w.mExiting ? 0 : w.mAttrs.dimAmount, + width, height); } - mAnimator.startDimming(w.mWinAnimator, w.mExiting ? 0 : w.mAttrs.dimAmount, - width, height); } } } @@ -8171,7 +8182,7 @@ public class WindowManagerService extends IWindowManager.Stub updateWallpaperVisibilityLocked(); } } - if (!mInnerFields.mDimming && mAnimator.mDimParams != null) { + if (!mInnerFields.mDimming && mAnimator.isDimming()) { mAnimator.stopDimming(); } } catch (RuntimeException e) { @@ -8472,11 +8483,13 @@ public class WindowManagerService extends IWindowManager.Stub !mInnerFields.mUpdateRotation) { checkDrawnWindowsLocked(); } - mInnerFields.mOrientationChangeComplete = true; // Check to see if we are now in a state where the screen should // be enabled, because the window obscured flags have changed. enableScreenIfNeededLocked(); +// Slog.e(TAG, "performLayoutAndPlaceSurfacesLockedInner exit: mPendingLayoutChanges=" +// + Integer.toHexString(mPendingLayoutChanges) + " mLayoutNeeded=" + mLayoutNeeded +// + " animating=" + mAnimator.mAnimating); } void checkDrawnWindowsLocked() { @@ -9512,11 +9525,6 @@ public class WindowManagerService extends IWindowManager.Stub public void onHardKeyboardStatusChange(boolean available, boolean enabled); } - void notifyAnimationChangedLayout(final int pendingLayoutChanges) { - mPendingLayoutChanges |= pendingLayoutChanges; - requestTraversalLocked(); - } - void debugLayoutRepeats(final String msg, int pendingLayoutChanges) { if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) { Slog.v(TAG, "Layouts looping: " + msg + ", mPendingLayoutChanges = 0x" + diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java index 220f5e0..941a5e1 100644 --- a/services/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/java/com/android/server/wm/WindowStateAnimator.java @@ -943,6 +943,10 @@ class WindowStateAnimator { } void setTransparentRegionHint(final Region region) { + if (mSurface == null) { + Slog.w(TAG, "setTransparentRegionHint: null mSurface after mHasSurface true"); + return; + } if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setTransparentRegion"); Surface.openTransaction(); diff --git a/services/jni/com_android_server_input_InputManagerService.cpp b/services/jni/com_android_server_input_InputManagerService.cpp index c137a78..85d6e11 100644 --- a/services/jni/com_android_server_input_InputManagerService.cpp +++ b/services/jni/com_android_server_input_InputManagerService.cpp @@ -39,6 +39,7 @@ #include <input/SpriteController.h> #include <android_os_MessageQueue.h> +#include <android_view_InputDevice.h> #include <android_view_KeyEvent.h> #include <android_view_MotionEvent.h> #include <android_view_InputChannel.h> @@ -88,20 +89,6 @@ static struct { } gMotionEventClassInfo; static struct { - jclass clazz; - - jmethodID ctor; - jmethodID addMotionRange; - - jfieldID mId; - jfieldID mName; - jfieldID mDescriptor; - jfieldID mSources; - jfieldID mKeyboardType; - jfieldID mKeyCharacterMapFile; -} gInputDeviceClassInfo; - -static struct { jfieldID touchscreen; jfieldID keyboard; jfieldID navigation; @@ -1171,44 +1158,7 @@ static jobject nativeGetInputDevice(JNIEnv* env, return NULL; } - jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor); - if (!deviceObj) { - return NULL; - } - - jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string()); - if (!deviceNameObj) { - return NULL; - } - - jstring deviceDescriptorObj = env->NewStringUTF(deviceInfo.getDescriptor().string()); - if (!deviceDescriptorObj) { - return NULL; - } - - jstring fileStr = env->NewStringUTF(deviceInfo.getKeyCharacterMapFile()); - if (!fileStr) { - return NULL; - } - - env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId()); - env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj); - env->SetObjectField(deviceObj, gInputDeviceClassInfo.mDescriptor, deviceDescriptorObj); - env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources()); - env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType()); - env->SetObjectField(deviceObj, gInputDeviceClassInfo.mKeyCharacterMapFile, fileStr); - - const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges(); - for (size_t i = 0; i < ranges.size(); i++) { - const InputDeviceInfo::MotionRange& range = ranges.itemAt(i); - env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange, - range.axis, range.source, range.min, range.max, range.flat, range.fuzz); - if (env->ExceptionCheck()) { - return NULL; - } - } - - return deviceObj; + return android_view_InputDevice_create(env, deviceInfo); } static jintArray nativeGetInputDeviceIds(JNIEnv* env, @@ -1437,35 +1387,6 @@ int register_android_server_InputManager(JNIEnv* env) { FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent"); gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz)); - // InputDevice - - FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice"); - gInputDeviceClassInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceClassInfo.clazz)); - - GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz, - "<init>", "()V"); - - GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz, - "addMotionRange", "(IIFFFF)V"); - - GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz, - "mId", "I"); - - GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz, - "mName", "Ljava/lang/String;"); - - GET_FIELD_ID(gInputDeviceClassInfo.mDescriptor, gInputDeviceClassInfo.clazz, - "mDescriptor", "Ljava/lang/String;"); - - GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz, - "mSources", "I"); - - GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz, - "mKeyboardType", "I"); - - GET_FIELD_ID(gInputDeviceClassInfo.mKeyCharacterMapFile, gInputDeviceClassInfo.clazz, - "mKeyCharacterMapFile", "Ljava/lang/String;"); - // Configuration FIND_CLASS(clazz, "android/content/res/Configuration"); diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java index 22e1bff..7105f2d 100644 --- a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java @@ -79,6 +79,7 @@ public class RSTestCore { unitTests.add(new UT_atomic(this, mRes, mCtx)); unitTests.add(new UT_struct(this, mRes, mCtx)); unitTests.add(new UT_math(this, mRes, mCtx)); + unitTests.add(new UT_math_conformance(this, mRes, mCtx)); unitTests.add(new UT_mesh(this, mRes, mCtx)); unitTests.add(new UT_element(this, mRes, mCtx)); unitTests.add(new UT_sampler(this, mRes, mCtx)); diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_math_conformance.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_math_conformance.java new file mode 100644 index 0000000..f256a3a --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_math_conformance.java @@ -0,0 +1,42 @@ +/* + * 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 com.android.rs.test; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_math_conformance extends UnitTest { + private Resources mRes; + + protected UT_math_conformance(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Math Conformance", ctx); + mRes = res; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_math_conformance s = + new ScriptC_math_conformance(pRS, mRes, R.raw.math_conformance); + pRS.setMessageHandler(mRsMessage); + s.invoke_math_conformance_test(); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + passTest(); + } +} diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/math_conformance.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/math_conformance.rs new file mode 100644 index 0000000..2d62f34 --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/math_conformance.rs @@ -0,0 +1,57 @@ +#include "shared.rsh" + +// Testing math conformance + +static bool test_rootn() { + bool failed = false; + + // rootn(x, 0) -> NaN + _RS_ASSERT(isnan(rootn(1.0f, 0))); + + // rootn(+/-0, n) -> +/-inf for odd n < 0 + _RS_ASSERT(isposinf(rootn(0.f, -3))); + _RS_ASSERT(isneginf(rootn(-0.f, -3))); + + // rootn(+/-0, n) -> +inf for even n < 0 + _RS_ASSERT(isposinf(rootn(0.f, -8))); + _RS_ASSERT(isposinf(rootn(-0.f, -8))); + + // rootn(+/-0, n) -> +/-0 for odd n > 0 + _RS_ASSERT(isposzero(rootn(0.f, 3))); + _RS_ASSERT(isnegzero(rootn(-0.f, 3))); + + // rootn(+/-0, n) -> +0 for even n > 0 + _RS_ASSERT(isposzero(rootn(0.f, 8))); + _RS_ASSERT(isposzero(rootn(-0.f, 8))); + + // rootn(x, n) -> NaN for x < 0 and even n + _RS_ASSERT(isnan(rootn(-10000.f, -4))); + _RS_ASSERT(isnan(rootn(-10000.f, 4))); + + // rootn(x, n) -> value for x < 0 and odd n + _RS_ASSERT(!isnan(rootn(-10000.f, -3))); + _RS_ASSERT(!isnan(rootn(-10000.f, 3))); + + if (failed) { + rsDebug("test_rootn FAILED", -1); + } + else { + rsDebug("test_rootn PASSED", 0); + } + + return failed; +} + +void math_conformance_test() { + bool failed = false; + failed |= test_rootn(); + + if (failed) { + rsDebug("math_conformance_test FAILED", -1); + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsDebug("math_conformance_test PASSED", 0); + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/shared.rsh b/tests/RenderScriptTests/tests/src/com/android/rs/test/shared.rsh index 21be9af..8cdf0d8 100644 --- a/tests/RenderScriptTests/tests/src/com/android/rs/test/shared.rsh +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/shared.rsh @@ -32,6 +32,48 @@ do { \ \ } while (0) +static const int iposinf = 0x7f800000; +static const int ineginf = 0xff800000; + +static const float posinf() { + float f = *((float*)&iposinf); + return f; +} + +static const float neginf() { + float f = *((float*)&ineginf); + return f; +} + +static bool isposinf(float f) { + int i = *((int*)(void*)&f); + return (i == iposinf); +} + +static bool isneginf(float f) { + int i = *((int*)(void*)&f); + return (i == ineginf); +} + +static bool isnan(float f) { + int i = *((int*)(void*)&f); + return (((i & 0x7f800000) == 0x7f800000) && (i & 0x007fffff)); +} + +static bool isposzero(float f) { + int i = *((int*)(void*)&f); + return (i == 0x00000000); +} + +static bool isnegzero(float f) { + int i = *((int*)(void*)&f); + return (i == 0x80000000); +} + +static bool iszero(float f) { + return isposzero(f) || isnegzero(f); +} + /* These constants must match those in UnitTest.java */ static const int RS_MSG_TEST_PASSED = 100; static const int RS_MSG_TEST_FAILED = 101; diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp index 689aa8e..cbd591f 100644 --- a/tools/aapt/Command.cpp +++ b/tools/aapt/Command.cpp @@ -345,6 +345,7 @@ enum { LABEL_ATTR = 0x01010001, ICON_ATTR = 0x01010002, NAME_ATTR = 0x01010003, + DEBUGGABLE_ATTR = 0x0101000f, VERSION_CODE_ATTR = 0x0101021b, VERSION_NAME_ATTR = 0x0101021c, SCREEN_ORIENTATION_ATTR = 0x0101001e, @@ -830,6 +831,15 @@ int doDump(Bundle* bundle) if (testOnly != 0) { printf("testOnly='%d'\n", testOnly); } + + int32_t debuggable = getResolvedIntegerAttribute(&res, tree, DEBUGGABLE_ATTR, &error, 0); + if (error != "") { + fprintf(stderr, "ERROR getting 'android:debuggable' attribute: %s\n", error.string()); + goto bail; + } + if (debuggable != 0) { + printf("application-debuggable\n"); + } } else if (tag == "uses-sdk") { int32_t code = getIntegerAttribute(tree, MIN_SDK_VERSION_ATTR, &error); if (error != "") { diff --git a/tools/validatekeymaps/Main.cpp b/tools/validatekeymaps/Main.cpp index 3cc2467..563225e 100644 --- a/tools/validatekeymaps/Main.cpp +++ b/tools/validatekeymaps/Main.cpp @@ -78,7 +78,7 @@ static bool validateFile(const char* filename) { return false; case FILETYPE_KEYLAYOUT: { - KeyLayoutMap* map; + sp<KeyLayoutMap> map; status_t status = KeyLayoutMap::load(String8(filename), &map); if (status) { fprintf(stderr, "Error %d parsing key layout file.\n\n", status); @@ -88,7 +88,7 @@ static bool validateFile(const char* filename) { } case FILETYPE_KEYCHARACTERMAP: { - KeyCharacterMap* map; + sp<KeyCharacterMap> map; status_t status = KeyCharacterMap::load(String8(filename), &map); if (status) { fprintf(stderr, "Error %d parsing key character map file.\n\n", status); @@ -104,6 +104,7 @@ static bool validateFile(const char* filename) { fprintf(stderr, "Error %d parsing input device configuration file.\n\n", status); return false; } + delete map; break; } @@ -114,6 +115,7 @@ static bool validateFile(const char* filename) { fprintf(stderr, "Error %d parsing virtual key definition file.\n\n", status); return false; } + delete map; break; } } |
