Merge "fix functor flag parsing, tweak process delay"
diff --git a/Android.mk b/Android.mk
index f65f9e4..d27dbab 100644
--- a/Android.mk
+++ b/Android.mk
@@ -110,6 +110,7 @@
core/java/android/content/pm/IPackageStatsObserver.aidl \
core/java/android/database/IContentObserver.aidl \
core/java/android/hardware/ISerialManager.aidl \
+ core/java/android/hardware/input/IInputManager.aidl \
core/java/android/hardware/usb/IUsbManager.aidl \
core/java/android/net/IConnectivityManager.aidl \
core/java/android/net/INetworkManagementEventObserver.aidl \
@@ -171,6 +172,7 @@
core/java/com/android/internal/view/IInputMethodClient.aidl \
core/java/com/android/internal/view/IInputMethodManager.aidl \
core/java/com/android/internal/view/IInputMethodSession.aidl \
+ core/java/com/android/internal/widget/ILockSettings.aidl \
core/java/com/android/internal/widget/IRemoteViewsFactory.aidl \
core/java/com/android/internal/widget/IRemoteViewsAdapterConnection.aidl \
keystore/java/android/security/IKeyChainAliasCallback.aidl \
diff --git a/api/current.txt b/api/current.txt
index 9186952..e6a01a8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -80,7 +80,7 @@
field public static final java.lang.String READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE";
field public static final java.lang.String READ_FRAME_BUFFER = "android.permission.READ_FRAME_BUFFER";
field public static final java.lang.String READ_HISTORY_BOOKMARKS = "com.android.browser.permission.READ_HISTORY_BOOKMARKS";
- field public static final java.lang.String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE";
+ field public static final deprecated java.lang.String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE";
field public static final java.lang.String READ_LOGS = "android.permission.READ_LOGS";
field public static final java.lang.String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE";
field public static final java.lang.String READ_PROFILE = "android.permission.READ_PROFILE";
@@ -570,6 +570,7 @@
field public static final int itemIconDisabledAlpha = 16843057; // 0x1010131
field public static final int itemPadding = 16843565; // 0x101032d
field public static final int itemTextAppearance = 16843052; // 0x101012c
+ field public static final int kcm = 16843696; // 0x10103b0
field public static final int keepScreenOn = 16843286; // 0x1010216
field public static final int key = 16843240; // 0x10101e8
field public static final int keyBackground = 16843315; // 0x1010233
@@ -727,6 +728,7 @@
field public static final int panelColorForeground = 16842848; // 0x1010060
field public static final int panelFullBackground = 16842847; // 0x101005f
field public static final int panelTextAppearance = 16842850; // 0x1010062
+ field public static final int parentActivityName = 16843697; // 0x10103b1
field public static final deprecated int password = 16843100; // 0x101015c
field public static final int path = 16842794; // 0x101002a
field public static final int pathPattern = 16842796; // 0x101002c
@@ -932,6 +934,7 @@
field public static final int summaryOff = 16843248; // 0x10101f0
field public static final int summaryOn = 16843247; // 0x10101ef
field public static final int supportsRtl = 16843688; // 0x10103a8
+ field public static final int supportsSentenceSpellCheck = 16843698; // 0x10103b2
field public static final int supportsUploading = 16843419; // 0x101029b
field public static final int switchMinWidth = 16843632; // 0x1010370
field public static final int switchPadding = 16843633; // 0x1010371
@@ -2578,6 +2581,7 @@
method public java.lang.String getLocalClassName();
method public android.view.MenuInflater getMenuInflater();
method public final android.app.Activity getParent();
+ method public android.content.Intent getParentActivityIntent();
method public android.content.SharedPreferences getPreferences(int);
method public int getRequestedOrientation();
method public int getTaskId();
@@ -2594,6 +2598,8 @@
method public boolean isTaskRoot();
method public final deprecated android.database.Cursor managedQuery(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
method public boolean moveTaskToBack(boolean);
+ method public boolean navigateUpTo(android.content.Intent);
+ method public boolean navigateUpToFromChild(android.app.Activity, android.content.Intent);
method public void onActionModeFinished(android.view.ActionMode);
method public void onActionModeStarted(android.view.ActionMode);
method protected void onActivityResult(int, int, android.content.Intent);
@@ -2610,6 +2616,7 @@
method public java.lang.CharSequence onCreateDescription();
method protected deprecated android.app.Dialog onCreateDialog(int);
method protected deprecated android.app.Dialog onCreateDialog(int, android.os.Bundle);
+ method public void onCreateNavigateUpTaskStack(android.app.TaskStackBuilder);
method public boolean onCreateOptionsMenu(android.view.Menu);
method public boolean onCreatePanelMenu(int, android.view.Menu);
method public android.view.View onCreatePanelView(int);
@@ -2627,6 +2634,8 @@
method public void onLowMemory();
method public boolean onMenuItemSelected(int, android.view.MenuItem);
method public boolean onMenuOpened(int, android.view.Menu);
+ method public boolean onNavigateUp();
+ method public boolean onNavigateUpFromChild(android.app.Activity);
method protected void onNewIntent(android.content.Intent);
method public boolean onOptionsItemSelected(android.view.MenuItem);
method public void onOptionsMenuClosed(android.view.Menu);
@@ -2636,6 +2645,7 @@
method protected void onPostResume();
method protected deprecated void onPrepareDialog(int, android.app.Dialog);
method protected deprecated void onPrepareDialog(int, android.app.Dialog, android.os.Bundle);
+ method public void onPrepareNavigateUpTaskStack(android.app.TaskStackBuilder);
method public boolean onPrepareOptionsMenu(android.view.Menu);
method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
method protected void onRestart();
@@ -2686,6 +2696,7 @@
method public void setTitleColor(int);
method public void setVisible(boolean);
method public final void setVolumeControlStream(int);
+ method public boolean shouldUpRecreateTask(android.content.Intent);
method public final deprecated void showDialog(int);
method public final deprecated boolean showDialog(int, android.os.Bundle);
method public android.view.ActionMode startActionMode(android.view.ActionMode.Callback);
@@ -3932,6 +3943,18 @@
method public void setDefaultTab(int);
}
+ public class TaskStackBuilder implements java.lang.Iterable {
+ method public android.app.TaskStackBuilder addNextIntent(android.content.Intent);
+ method public android.app.TaskStackBuilder addParentStack(android.app.Activity);
+ method public android.app.TaskStackBuilder addParentStack(java.lang.Class<?>);
+ method public static android.app.TaskStackBuilder from(android.content.Context);
+ method public android.content.Intent getIntent(int);
+ method public int getIntentCount();
+ method public android.app.PendingIntent getPendingIntent(int, int);
+ method public java.util.Iterator<android.content.Intent> iterator();
+ method public void startActivities();
+ }
+
public class TimePickerDialog extends android.app.AlertDialog implements android.content.DialogInterface.OnClickListener android.widget.TimePicker.OnTimeChangedListener {
ctor public TimePickerDialog(android.content.Context, android.app.TimePickerDialog.OnTimeSetListener, int, int, boolean);
ctor public TimePickerDialog(android.content.Context, int, android.app.TimePickerDialog.OnTimeSetListener, int, int, boolean);
@@ -5211,6 +5234,7 @@
field public static final java.lang.String DOWNLOAD_SERVICE = "download";
field public static final java.lang.String DROPBOX_SERVICE = "dropbox";
field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
+ field public static final java.lang.String INPUT_SERVICE = "input";
field public static final java.lang.String KEYGUARD_SERVICE = "keyguard";
field public static final java.lang.String LAYOUT_INFLATER_SERVICE = "layout_inflater";
field public static final java.lang.String LOCATION_SERVICE = "location";
@@ -6102,6 +6126,7 @@
field public int configChanges;
field public int flags;
field public int launchMode;
+ field public java.lang.String parentActivityName;
field public java.lang.String permission;
field public int screenOrientation;
field public int softInputMode;
@@ -9795,6 +9820,15 @@
}
+package android.hardware.input {
+
+ public final class InputManager {
+ field public static final java.lang.String ACTION_QUERY_KEYBOARD_LAYOUTS = "android.hardware.input.action.QUERY_KEYBOARD_LAYOUTS";
+ field public static final java.lang.String META_DATA_KEYBOARD_LAYOUTS = "android.hardware.input.metadata.KEYBOARD_LAYOUTS";
+ }
+
+}
+
package android.hardware.usb {
public class UsbAccessory implements android.os.Parcelable {
@@ -22225,6 +22259,7 @@
public final class InputDevice implements android.os.Parcelable {
method public int describeContents();
+ method public java.lang.String getDescriptor();
method public static android.view.InputDevice getDevice(int);
method public static int[] getDeviceIds();
method public int getId();
@@ -24148,15 +24183,18 @@
}
public final class ViewTreeObserver {
+ method public void addOnDrawListener(android.view.ViewTreeObserver.OnDrawListener);
method public void addOnGlobalFocusChangeListener(android.view.ViewTreeObserver.OnGlobalFocusChangeListener);
method public void addOnGlobalLayoutListener(android.view.ViewTreeObserver.OnGlobalLayoutListener);
method public void addOnPreDrawListener(android.view.ViewTreeObserver.OnPreDrawListener);
method public void addOnScrollChangedListener(android.view.ViewTreeObserver.OnScrollChangedListener);
method public void addOnTouchModeChangeListener(android.view.ViewTreeObserver.OnTouchModeChangeListener);
+ method public final void dispatchOnDraw();
method public final void dispatchOnGlobalLayout();
method public final boolean dispatchOnPreDraw();
method public boolean isAlive();
method public deprecated void removeGlobalOnLayoutListener(android.view.ViewTreeObserver.OnGlobalLayoutListener);
+ method public void removeOnDrawListener(android.view.ViewTreeObserver.OnDrawListener);
method public void removeOnGlobalFocusChangeListener(android.view.ViewTreeObserver.OnGlobalFocusChangeListener);
method public void removeOnGlobalLayoutListener(android.view.ViewTreeObserver.OnGlobalLayoutListener);
method public void removeOnPreDrawListener(android.view.ViewTreeObserver.OnPreDrawListener);
@@ -24164,6 +24202,10 @@
method public void removeOnTouchModeChangeListener(android.view.ViewTreeObserver.OnTouchModeChangeListener);
}
+ public static abstract interface ViewTreeObserver.OnDrawListener {
+ method public abstract void onDraw();
+ }
+
public static abstract interface ViewTreeObserver.OnGlobalFocusChangeListener {
method public abstract void onGlobalFocusChanged(android.view.View, android.view.View);
}
@@ -25239,11 +25281,13 @@
method public android.view.textservice.SpellCheckerInfo getSpellChecker();
method public void getSuggestions(android.view.textservice.TextInfo, int);
method public void getSuggestions(android.view.textservice.TextInfo[], int, boolean);
+ method public boolean isSentenceSpellCheckSupported();
method public boolean isSessionDisconnected();
field public static final java.lang.String SERVICE_META_DATA = "android.view.textservice.scs";
}
public static abstract interface SpellCheckerSession.SpellCheckerSessionListener {
+ method public abstract void onGetSentenceSuggestions(android.view.textservice.SentenceSuggestionsInfo[]);
method public abstract void onGetSuggestions(android.view.textservice.SuggestionsInfo[]);
}
diff --git a/cmds/app_process/Android.mk b/cmds/app_process/Android.mk
index 2391b72..b39c335 100644
--- a/cmds/app_process/Android.mk
+++ b/cmds/app_process/Android.mk
@@ -13,3 +13,29 @@
LOCAL_MODULE:= app_process
include $(BUILD_EXECUTABLE)
+
+
+# Build a variant of app_process binary linked with ASan runtime.
+# ARM-only at the moment.
+ifeq ($(TARGET_ARCH),arm)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ app_main.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libcutils \
+ libutils \
+ libbinder \
+ libandroid_runtime
+
+LOCAL_MODULE := app_process__asan
+LOCAL_MODULE_TAGS := eng
+LOCAL_MODULE_PATH := $(TARGET_OUT_EXECUTABLES)/asan
+LOCAL_MODULE_STEM := app_process
+LOCAL_ADDRESS_SANITIZER := true
+
+include $(BUILD_EXECUTABLE)
+
+endif # ifeq($(TARGET_ARCH),arm)
diff --git a/cmds/input/src/com/android/commands/input/Input.java b/cmds/input/src/com/android/commands/input/Input.java
index c4c3b8a..3037881 100755
--- a/cmds/input/src/com/android/commands/input/Input.java
+++ b/cmds/input/src/com/android/commands/input/Input.java
@@ -16,11 +16,12 @@
package com.android.commands.input;
+import android.hardware.input.InputManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.util.Log;
-import android.view.IWindowManager;
+import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -33,8 +34,6 @@
public class Input {
private static final String TAG = "Input";
- private IWindowManager mWindowManager;
-
/**
* Command-line entry point.
*
@@ -44,13 +43,6 @@
(new Input()).run(args);
}
- private IWindowManager getWindowManager() {
- if (mWindowManager == null) {
- mWindowManager = (IWindowManager.Stub.asInterface(ServiceManager.getService("window")));
- }
- return mWindowManager;
- }
-
private void run(String[] args) {
if (args.length < 1) {
showUsage();
@@ -127,8 +119,10 @@
private void sendKeyEvent(int keyCode) {
long now = SystemClock.uptimeMillis();
- injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, 0));
- injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_UP, keyCode, 0));
+ injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, 0, 0,
+ KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD));
+ injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_UP, keyCode, 0, 0,
+ KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD));
}
private void sendTap(float x, float y) {
@@ -150,23 +144,14 @@
}
private void injectKeyEvent(KeyEvent event) {
- try {
- Log.i(TAG, "InjectKeyEvent: " + event);
- getWindowManager().injectKeyEvent(event, true);
- } catch (RemoteException ex) {
- Log.i(TAG, "RemoteException", ex);
- }
+ Log.i(TAG, "InjectKeyEvent: " + event);
+ InputManager.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
private void injectPointerEvent(MotionEvent event) {
- try {
- Log.i("Input", "InjectPointerEvent: " + event);
- getWindowManager().injectPointerEvent(event, true);
- } catch (RemoteException ex) {
- Log.i(TAG, "RemoteException", ex);
- } finally {
- event.recycle();
- }
+ event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+ Log.i("Input", "InjectPointerEvent: " + event);
+ InputManager.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
private static final float lerp(float a, float b, float alpha) {
@@ -174,7 +159,7 @@
}
private void showUsage() {
- System.err.println("usage: input [text|keyevent]");
+ System.err.println("usage: input ...");
System.err.println(" input text <string>");
System.err.println(" input keyevent <key code>");
System.err.println(" input tap <x> <y>");
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index b277efb..3e123ba 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -29,6 +29,8 @@
import android.content.IntentSender;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -65,13 +67,13 @@
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
-import android.view.WindowManagerImpl;
import android.view.View.OnCreateContextMenuListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewManager;
import android.view.Window;
import android.view.WindowManager;
+import android.view.WindowManagerImpl;
import android.view.accessibility.AccessibilityEvent;
import android.widget.AdapterView;
@@ -704,6 +706,7 @@
/*package*/ boolean mVisibleFromServer = false;
/*package*/ boolean mVisibleFromClient = true;
/*package*/ ActionBarImpl mActionBar = null;
+ private boolean mEnableDefaultActionBarUp;
private CharSequence mTitle;
private int mTitleColor = 0;
@@ -865,6 +868,13 @@
if (mLastNonConfigurationInstances != null) {
mAllLoaderManagers = mLastNonConfigurationInstances.loaders;
}
+ if (mActivityInfo.parentActivityName != null) {
+ if (mActionBar == null) {
+ mEnableDefaultActionBarUp = true;
+ } else {
+ mActionBar.setDefaultDisplayHomeAsUpEnabled(true);
+ }
+ }
if (savedInstanceState != null) {
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
@@ -1829,6 +1839,7 @@
}
mActionBar = new ActionBarImpl(this);
+ mActionBar.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp);
}
/**
@@ -2630,7 +2641,7 @@
* facilities.
*
* <p>Derived classes should call through to the base class for it to
- * perform the default menu handling.
+ * perform the default menu handling.</p>
*
* @param item The menu item that was selected.
*
@@ -2643,10 +2654,105 @@
if (mParent != null) {
return mParent.onOptionsItemSelected(item);
}
+ if (item.getItemId() == android.R.id.home && mActionBar != null &&
+ (mActionBar.getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
+ if (mParent == null) {
+ onNavigateUp();
+ } else {
+ mParent.onNavigateUpFromChild(this);
+ }
+ return true;
+ }
return false;
}
/**
+ * This method is called whenever the user chooses to navigate Up within your application's
+ * activity hierarchy from the action bar.
+ *
+ * <p>If the attribute {@link android.R.attr#parentActivityName parentActivityName}
+ * was specified in the manifest for this activity or an activity-alias to it,
+ * default Up navigation will be handled automatically. If any activity
+ * along the parent chain requires extra Intent arguments, the Activity subclass
+ * should override the method {@link #onPrepareNavigateUpTaskStack(TaskStackBuilder)}
+ * to supply those arguments.</p>
+ *
+ * <p>See <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a>
+ * from the developer guide and <a href="{@docRoot}design/patterns/navigation.html">Navigation</a>
+ * from the design guide for more information about navigating within your app.</p>
+ *
+ * <p>See the {@link TaskStackBuilder} class and the Activity methods
+ * {@link #getParentActivityIntent()}, {@link #shouldUpRecreateTask(Intent)}, and
+ * {@link #navigateUpTo(Intent)} for help implementing custom Up navigation.
+ * The AppNavigation sample application in the Android SDK is also available for reference.</p>
+ *
+ * @return true if Up navigation completed successfully and this Activity was finished,
+ * false otherwise.
+ */
+ public boolean onNavigateUp() {
+ // Automatically handle hierarchical Up navigation if the proper
+ // metadata is available.
+ Intent upIntent = getParentActivityIntent();
+ if (upIntent != null) {
+ if (shouldUpRecreateTask(upIntent)) {
+ TaskStackBuilder b = TaskStackBuilder.from(this);
+ onCreateNavigateUpTaskStack(b);
+ onPrepareNavigateUpTaskStack(b);
+ b.startActivities();
+ finish();
+ } else {
+ navigateUpTo(upIntent);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * This is called when a child activity of this one attempts to navigate up.
+ * The default implementation simply calls onNavigateUp() on this activity (the parent).
+ *
+ * @param child The activity making the call.
+ */
+ public boolean onNavigateUpFromChild(Activity child) {
+ return onNavigateUp();
+ }
+
+ /**
+ * Define the synthetic task stack that will be generated during Up navigation from
+ * a different task.
+ *
+ * <p>The default implementation of this method adds the parent chain of this activity
+ * as specified in the manifest to the supplied {@link TaskStackBuilder}. Applications
+ * may choose to override this method to construct the desired task stack in a different
+ * way.</p>
+ *
+ * <p>Applications that wish to supply extra Intent parameters to the parent stack defined
+ * by the manifest should override {@link #onPrepareNavigateUpTaskStack(TaskStackBuilder)}.</p>
+ *
+ * @param builder An empty TaskStackBuilder - the application should add intents representing
+ * the desired task stack
+ */
+ public void onCreateNavigateUpTaskStack(TaskStackBuilder builder) {
+ builder.addParentStack(this);
+ }
+
+ /**
+ * Prepare the synthetic task stack that will be generated during Up navigation
+ * from a different task.
+ *
+ * <p>This method receives the {@link TaskStackBuilder} with the constructed series of
+ * Intents as generated by {@link #onCreateNavigateUpTaskStack(TaskStackBuilder)}.
+ * If any extra data should be added to these intents before launching the new task,
+ * the application should override this method and add that data here.</p>
+ *
+ * @param builder A TaskStackBuilder that has been populated with Intents by
+ * onCreateNavigateUpTaskStack.
+ */
+ public void onPrepareNavigateUpTaskStack(TaskStackBuilder builder) {
+ }
+
+ /**
* This hook is called whenever the options menu is being closed (either by the user canceling
* the menu with the back/menu button, or when an item is selected).
*
@@ -4658,6 +4764,114 @@
public void onActionModeFinished(ActionMode mode) {
}
+ /**
+ * Returns true if the app should recreate the task when navigating 'up' from this activity
+ * by using targetIntent.
+ *
+ * <p>If this method returns false the app can trivially call
+ * {@link #navigateUpTo(Intent)} using the same parameters to correctly perform
+ * up navigation. If this method returns false, the app should synthesize a new task stack
+ * by using {@link TaskStackBuilder} or another similar mechanism to perform up navigation.</p>
+ *
+ * @param targetIntent An intent representing the target destination for up navigation
+ * @return true if navigating up should recreate a new task stack, false if the same task
+ * should be used for the destination
+ */
+ public boolean shouldUpRecreateTask(Intent targetIntent) {
+ try {
+ PackageManager pm = getPackageManager();
+ ComponentName cn = targetIntent.getComponent();
+ if (cn == null) {
+ cn = targetIntent.resolveActivity(pm);
+ }
+ ActivityInfo info = pm.getActivityInfo(cn, 0);
+ if (info.taskAffinity == null) {
+ return false;
+ }
+ return !ActivityManagerNative.getDefault()
+ .targetTaskAffinityMatchesActivity(mToken, info.taskAffinity);
+ } catch (RemoteException e) {
+ return false;
+ } catch (NameNotFoundException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Navigate from this activity to the activity specified by upIntent, finishing this activity
+ * in the process. If the activity indicated by upIntent already exists in the task's history,
+ * this activity and all others before the indicated activity in the history stack will be
+ * finished. If the indicated activity does not appear in the history stack, this is equivalent
+ * to simply calling finish() on this activity.
+ *
+ * <p>This method should be used when performing up navigation from within the same task
+ * as the destination. If up navigation should cross tasks in some cases, see
+ * {@link #shouldUpRecreateTask(Intent)}.</p>
+ *
+ * @param upIntent An intent representing the target destination for up navigation
+ *
+ * @return true if up navigation successfully reached the activity indicated by upIntent and
+ * upIntent was delivered to it. false if an instance of the indicated activity could
+ * not be found and this activity was simply finished normally.
+ */
+ public boolean navigateUpTo(Intent upIntent) {
+ if (mParent == null) {
+ ComponentName destInfo = upIntent.getComponent();
+ if (destInfo == null) {
+ destInfo = upIntent.resolveActivity(getPackageManager());
+ if (destInfo == null) {
+ return false;
+ }
+ upIntent = new Intent(upIntent);
+ upIntent.setComponent(destInfo);
+ }
+ int resultCode;
+ Intent resultData;
+ synchronized (this) {
+ resultCode = mResultCode;
+ resultData = mResultData;
+ }
+ if (resultData != null) {
+ resultData.setAllowFds(false);
+ }
+ try {
+ return ActivityManagerNative.getDefault().navigateUpTo(mToken, upIntent,
+ resultCode, resultData);
+ } catch (RemoteException e) {
+ return false;
+ }
+ } else {
+ return mParent.navigateUpToFromChild(this, upIntent);
+ }
+ }
+
+ /**
+ * This is called when a child activity of this one calls its
+ * {@link #navigateUpTo} method. The default implementation simply calls
+ * navigateUpTo(upIntent) on this activity (the parent).
+ *
+ * @param child The activity making the call.
+ * @param upIntent An intent representing the target destination for up navigation
+ *
+ * @return true if up navigation successfully reached the activity indicated by upIntent and
+ * upIntent was delivered to it. false if an instance of the indicated activity could
+ * not be found and this activity was simply finished normally.
+ */
+ public boolean navigateUpToFromChild(Activity child, Intent upIntent) {
+ return navigateUpTo(upIntent);
+ }
+
+ /**
+ * Obtain an {@link Intent} that will launch an explicit target activity specified by
+ * this activity's logical parent. The logical parent is named in the application's manifest
+ * by the {@link android.R.attr#parentActivityName parentActivityName} attribute.
+ *
+ * @return a new Intent targeting the defined parent of this activity
+ */
+ public Intent getParentActivityIntent() {
+ return new Intent().setClassName(this, mActivityInfo.parentActivityName);
+ }
+
// ------------------ Internal API ------------------
final void setParent(Activity parent) {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 531a695..11b4c3a 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1774,5 +1774,4 @@
return false;
}
}
-
}
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 5917cbf..000abc5 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -17,10 +17,10 @@
package android.app;
import android.content.ComponentName;
+import android.content.IIntentReceiver;
+import android.content.IIntentSender;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.IIntentSender;
-import android.content.IIntentReceiver;
import android.content.IntentSender;
import android.content.pm.ApplicationInfo;
import android.content.pm.ConfigurationInfo;
@@ -32,11 +32,11 @@
import android.os.Binder;
import android.os.Bundle;
import android.os.Debug;
-import android.os.Parcelable;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
import android.os.IBinder;
import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
+import android.os.Parcelable;
+import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.StrictMode;
import android.text.TextUtils;
@@ -1605,6 +1605,31 @@
return true;
}
+ case TARGET_TASK_AFFINITY_MATCHES_ACTIVITY_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IBinder token = data.readStrongBinder();
+ String destAffinity = data.readString();
+ boolean res = targetTaskAffinityMatchesActivity(token, destAffinity);
+ reply.writeNoException();
+ reply.writeInt(res ? 1 : 0);
+ return true;
+ }
+
+ case NAVIGATE_UP_TO_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IBinder token = data.readStrongBinder();
+ Intent target = Intent.CREATOR.createFromParcel(data);
+ int resultCode = data.readInt();
+ Intent resultData = null;
+ if (data.readInt() != 0) {
+ resultData = Intent.CREATOR.createFromParcel(data);
+ }
+ boolean res = navigateUpTo(token, target, resultCode, resultData);
+ reply.writeNoException();
+ reply.writeInt(res ? 1 : 0);
+ return true;
+ }
+
}
return super.onTransact(code, data, reply, flags);
@@ -3662,5 +3687,42 @@
reply.recycle();
}
+ public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity)
+ throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeStrongBinder(token);
+ data.writeString(destAffinity);
+ mRemote.transact(TARGET_TASK_AFFINITY_MATCHES_ACTIVITY_TRANSACTION, data, reply, 0);
+ reply.readException();
+ boolean result = reply.readInt() != 0;
+ data.recycle();
+ reply.recycle();
+ return result;
+ }
+
+ public boolean navigateUpTo(IBinder token, Intent target, int resultCode, Intent resultData)
+ throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeStrongBinder(token);
+ target.writeToParcel(data, 0);
+ data.writeInt(resultCode);
+ if (resultData != null) {
+ data.writeInt(1);
+ resultData.writeToParcel(data, 0);
+ } else {
+ data.writeInt(0);
+ }
+ mRemote.transact(NAVIGATE_UP_TO_TRANSACTION, data, reply, 0);
+ reply.readException();
+ boolean result = reply.readInt() != 0;
+ data.recycle();
+ reply.recycle();
+ return result;
+ }
+
private IBinder mRemote;
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 5ffceb3..c5d7b91 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -45,6 +45,8 @@
import android.hardware.ISerialManager;
import android.hardware.SensorManager;
import android.hardware.SerialManager;
+import android.hardware.input.IInputManager;
+import android.hardware.input.InputManager;
import android.hardware.usb.IUsbManager;
import android.hardware.usb.UsbManager;
import android.location.CountryDetector;
@@ -323,6 +325,11 @@
return createDropBoxManager();
}});
+ registerService(INPUT_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ return new InputManager(ctx);
+ }});
+
registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return InputMethodManager.getInstance(ctx);
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index ad8d41f..dd58397 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -1097,6 +1097,18 @@
}
}
+ /** {@hide} */
+ public static boolean isActiveNetworkExpensive(Context context) {
+ // TODO: connect to NetworkPolicyManager
+ return false;
+ }
+
+ /** {@hide} */
+ public static long getActiveNetworkWarningBytes(Context context) {
+ // TODO: connect to NetworkPolicyManager
+ return -1;
+ }
+
/**
* Adds a file to the downloads database system, so it could appear in Downloads App
* (and thus become eligible for management by the Downloads App).
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 2b1eb43..0f287c1 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -341,6 +341,12 @@
public void dismissKeyguardOnNextActivity() throws RemoteException;
+ public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity)
+ throws RemoteException;
+
+ public boolean navigateUpTo(IBinder token, Intent target, int resultCode, Intent resultData)
+ throws RemoteException;
+
/*
* Private non-Binder interfaces
*/
@@ -578,4 +584,6 @@
int GET_MY_MEMORY_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+142;
int KILL_PROCESSES_BELOW_FOREGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+143;
int GET_CURRENT_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+144;
+ int TARGET_TASK_AFFINITY_MATCHES_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+145;
+ int NAVIGATE_UP_TO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+146;
}
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index e4f7950..f955713 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -23,6 +23,7 @@
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
+import android.hardware.input.InputManager;
import android.os.Bundle;
import android.os.Debug;
import android.os.IBinder;
@@ -35,6 +36,7 @@
import android.util.AndroidRuntimeException;
import android.util.Log;
import android.view.IWindowManager;
+import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -859,11 +861,30 @@
*/
public void sendKeySync(KeyEvent event) {
validateNotAppThread();
- try {
- (IWindowManager.Stub.asInterface(ServiceManager.getService("window")))
- .injectKeyEvent(event, true);
- } catch (RemoteException e) {
+
+ long downTime = event.getDownTime();
+ long eventTime = event.getEventTime();
+ int action = event.getAction();
+ int code = event.getKeyCode();
+ int repeatCount = event.getRepeatCount();
+ int metaState = event.getMetaState();
+ int deviceId = event.getDeviceId();
+ int scancode = event.getScanCode();
+ int source = event.getSource();
+ int flags = event.getFlags();
+ if (source == InputDevice.SOURCE_UNKNOWN) {
+ source = InputDevice.SOURCE_KEYBOARD;
}
+ if (eventTime == 0) {
+ eventTime = SystemClock.uptimeMillis();
+ }
+ if (downTime == 0) {
+ downTime = eventTime;
+ }
+ KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
+ deviceId, scancode, flags | KeyEvent.FLAG_FROM_SYSTEM, source);
+ InputManager.injectInputEvent(newEvent,
+ InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
/**
@@ -902,11 +923,10 @@
*/
public void sendPointerSync(MotionEvent event) {
validateNotAppThread();
- try {
- (IWindowManager.Stub.asInterface(ServiceManager.getService("window")))
- .injectPointerEvent(event, true);
- } catch (RemoteException e) {
+ if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
+ event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
}
+ InputManager.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
/**
@@ -922,11 +942,10 @@
*/
public void sendTrackballEventSync(MotionEvent event) {
validateNotAppThread();
- try {
- (IWindowManager.Stub.asInterface(ServiceManager.getService("window")))
- .injectTrackballEvent(event, true);
- } catch (RemoteException e) {
+ if ((event.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) {
+ event.setSource(InputDevice.SOURCE_TRACKBALL);
}
+ InputManager.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
/**
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 096af93..04c64a0 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -26,6 +26,7 @@
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.SystemClock;
import android.text.TextUtils;
import android.util.IntProperty;
import android.util.Log;
@@ -808,6 +809,7 @@
@Deprecated
public void setLatestEventInfo(Context context,
CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) {
+ // TODO: rewrite this to use Builder
RemoteViews contentView = new RemoteViews(context.getPackageName(),
R.layout.notification_template_base);
if (this.icon != 0) {
@@ -820,6 +822,7 @@
contentView.setTextViewText(R.id.text, contentText);
}
if (this.when != 0) {
+ contentView.setViewVisibility(R.id.time, View.VISIBLE);
contentView.setLong(R.id.time, "setTime", when);
}
@@ -942,6 +945,7 @@
private ArrayList<Action> mActions = new ArrayList<Action>(3);
private boolean mCanHasIntruder;
private boolean mIntruderActionsShowText;
+ private boolean mUseChronometer;
/**
* Constructs a new Builder with the defaults:
@@ -983,6 +987,18 @@
}
/**
+ * @hide
+ *
+ * Show the {@link Notification#when} field as a countdown (or count-up) timer instead of a timestamp.
+ *
+ * @see Notification#when
+ */
+ public Builder setUsesChronometer(boolean b) {
+ mUseChronometer = b;
+ return this;
+ }
+
+ /**
* Set the small icon resource, which will be used to represent the notification in the
* status bar.
*
@@ -1434,7 +1450,15 @@
}
}
if (mWhen != 0) {
- contentView.setLong(R.id.time, "setTime", mWhen);
+ if (mUseChronometer) {
+ contentView.setViewVisibility(R.id.chronometer, View.VISIBLE);
+ contentView.setLong(R.id.chronometer, "setBase",
+ mWhen + (SystemClock.elapsedRealtime() - System.currentTimeMillis()));
+ contentView.setBoolean(R.id.chronometer, "setStarted", true);
+ } else {
+ contentView.setViewVisibility(R.id.time, View.VISIBLE);
+ contentView.setLong(R.id.time, "setTime", mWhen);
+ }
}
contentView.setViewVisibility(R.id.line3, hasLine3 ? View.VISIBLE : View.GONE);
return contentView;
diff --git a/core/java/android/app/TaskStackBuilder.java b/core/java/android/app/TaskStackBuilder.java
new file mode 100644
index 0000000..7fd4747
--- /dev/null
+++ b/core/java/android/app/TaskStackBuilder.java
@@ -0,0 +1,220 @@
+/*
+ * 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.app;
+
+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.PackageManager.NameNotFoundException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * Utility class for constructing synthetic back stacks for cross-task navigation
+ * on Android 3.0 and newer.
+ *
+ * <p>In API level 11 (Android 3.0/Honeycomb) the recommended conventions for
+ * app navigation using the back key changed. The back key's behavior is local
+ * to the current task and does not capture navigation across different tasks.
+ * Navigating across tasks and easily reaching the previous task is accomplished
+ * through the "recents" UI, accessible through the software-provided Recents key
+ * on the navigation or system bar. On devices with the older hardware button configuration
+ * the recents UI can be accessed with a long press on the Home key.</p>
+ *
+ * <p>When crossing from one task stack to another post-Android 3.0,
+ * the application should synthesize a back stack/history for the new task so that
+ * the user may navigate out of the new task and back to the Launcher by repeated
+ * presses of the back key. Back key presses should not navigate across task stacks.</p>
+ *
+ * <p>TaskStackBuilder provides a way to obey the correct conventions
+ * around cross-task navigation.</p>
+ *
+ * <div class="special reference">
+ * <h3>About Navigation</h3>
+ * For more detailed information about tasks, the back stack, and navigation design guidelines,
+ * please read
+ * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a>
+ * from the developer guide and <a href="{@docRoot}design/patterns/navigation.html">Navigation</a>
+ * from the design guide.
+ * </div>
+ */
+public class TaskStackBuilder implements Iterable<Intent> {
+ private static final String TAG = "TaskStackBuilder";
+
+ private final ArrayList<Intent> mIntents = new ArrayList<Intent>();
+ private final Context mSourceContext;
+
+ private TaskStackBuilder(Context a) {
+ mSourceContext = a;
+ }
+
+ /**
+ * Return a new TaskStackBuilder for launching a fresh task stack consisting
+ * of a series of activities.
+ *
+ * @param context The context that will launch the new task stack or generate a PendingIntent
+ * @return A new TaskStackBuilder
+ */
+ public static TaskStackBuilder from(Context context) {
+ return new TaskStackBuilder(context);
+ }
+
+ /**
+ * Add a new Intent to the task stack. The most recently added Intent will invoke
+ * the Activity at the top of the final task stack.
+ *
+ * @param nextIntent Intent for the next Activity in the synthesized task stack
+ * @return This TaskStackBuilder for method chaining
+ */
+ public TaskStackBuilder addNextIntent(Intent nextIntent) {
+ mIntents.add(nextIntent);
+ return this;
+ }
+
+ /**
+ * Add the activity parent chain as specified by the
+ * {@link android.R.attr#parentActivityName parentActivityName} attribute of the activity
+ * (or activity-alias) element in the application's manifest to the task stack builder.
+ *
+ * @param sourceActivity All parents of this activity will be added
+ * @return This TaskStackBuilder for method chaining
+ */
+ public TaskStackBuilder addParentStack(Activity sourceActivity) {
+ final int insertAt = mIntents.size();
+ Intent parent = sourceActivity.getParentActivityIntent();
+ PackageManager pm = sourceActivity.getPackageManager();
+ while (parent != null) {
+ mIntents.add(insertAt, parent);
+ try {
+ ActivityInfo info = pm.getActivityInfo(parent.getComponent(), 0);
+ String parentActivity = info.parentActivityName;
+ if (parentActivity != null) {
+ parent = new Intent().setComponent(
+ new ComponentName(mSourceContext, parentActivity));
+ } else {
+ parent = null;
+ }
+ } catch (NameNotFoundException e) {
+ Log.e(TAG, "Bad ComponentName while traversing activity parent metadata");
+ throw new IllegalArgumentException(e);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Add the activity parent chain as specified by the
+ * {@link android.R.attr#parentActivityName parentActivityName} attribute of the activity
+ * (or activity-alias) element in the application's manifest to the task stack builder.
+ *
+ * @param sourceActivityClass All parents of this activity will be added
+ * @return This TaskStackBuilder for method chaining
+ */
+ public TaskStackBuilder addParentStack(Class<?> sourceActivityClass) {
+ final int insertAt = mIntents.size();
+ PackageManager pm = mSourceContext.getPackageManager();
+ try {
+ ActivityInfo info = pm.getActivityInfo(
+ new ComponentName(mSourceContext, sourceActivityClass), 0);
+ String parentActivity = info.parentActivityName;
+ Intent parent = new Intent().setComponent(
+ new ComponentName(mSourceContext, parentActivity));
+ while (parent != null) {
+ mIntents.add(insertAt, parent);
+ info = pm.getActivityInfo(parent.getComponent(), 0);
+ parentActivity = info.parentActivityName;
+ if (parentActivity != null) {
+ parent = new Intent().setComponent(
+ new ComponentName(mSourceContext, parentActivity));
+ } else {
+ parent = null;
+ }
+ }
+ } catch (NameNotFoundException e) {
+ Log.e(TAG, "Bad ComponentName while traversing activity parent metadata");
+ throw new IllegalArgumentException(e);
+ }
+ return this;
+ }
+
+ /**
+ * @return the number of intents added so far.
+ */
+ public int getIntentCount() {
+ return mIntents.size();
+ }
+
+ /**
+ * Get the intent at the specified index.
+ * Useful if you need to modify the flags or extras of an intent that was previously added,
+ * for example with {@link #addParentStack(Activity)}.
+ *
+ * @param index Index from 0-getIntentCount()
+ * @return the intent at position index
+ */
+ public Intent getIntent(int index) {
+ return mIntents.get(index);
+ }
+
+ public Iterator<Intent> iterator() {
+ return mIntents.iterator();
+ }
+
+ /**
+ * Start the task stack constructed by this builder.
+ */
+ public void startActivities() {
+ if (mIntents.isEmpty()) {
+ throw new IllegalStateException(
+ "No intents added to TaskStackBuilder; cannot startActivities");
+ }
+
+ Intent[] intents = mIntents.toArray(new Intent[mIntents.size()]);
+ intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
+ Intent.FLAG_ACTIVITY_CLEAR_TASK |
+ Intent.FLAG_ACTIVITY_TASK_ON_HOME);
+ mSourceContext.startActivities(intents);
+ }
+
+ /**
+ * Obtain a {@link PendingIntent} for launching the task constructed by this builder so far.
+ *
+ * @param requestCode Private request code for the sender
+ * @param flags May be {@link PendingIntent#FLAG_ONE_SHOT},
+ * {@link PendingIntent#FLAG_NO_CREATE}, {@link PendingIntent#FLAG_CANCEL_CURRENT},
+ * {@link PendingIntent#FLAG_UPDATE_CURRENT}, or any of the flags supported by
+ * {@link Intent#fillIn(Intent, int)} to control which unspecified parts of the
+ * intent that can be supplied when the actual send happens.
+ * @return The obtained PendingIntent
+ */
+ public PendingIntent getPendingIntent(int requestCode, int flags) {
+ if (mIntents.isEmpty()) {
+ throw new IllegalStateException(
+ "No intents added to TaskStackBuilder; cannot getPendingIntent");
+ }
+
+ Intent[] intents = mIntents.toArray(new Intent[mIntents.size()]);
+ intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
+ Intent.FLAG_ACTIVITY_CLEAR_TASK |
+ Intent.FLAG_ACTIVITY_TASK_ON_HOME);
+ return PendingIntent.getActivities(mSourceContext, requestCode, intents, flags);
+ }
+}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 98ed117..36638f9 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1919,6 +1919,15 @@
public static final String SERIAL_SERVICE = "serial";
/**
+ * Use with {@link #getSystemService} to retrieve a
+ * {@link android.hardware.input.InputManager} for interacting with input devices.
+ *
+ * @see #getSystemService
+ * @see android.hardware.input.InputManager
+ */
+ public static final String INPUT_SERVICE = "input";
+
+ /**
* Determine whether the given permission is allowed for a particular
* process and user ID running in the system.
*
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 2a9f1af..736dd24 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2034,6 +2034,38 @@
"android.intent.action.HDMI_AUDIO_PLUG";
/**
+ * Broadcast Action: A USB audio device was plugged in or unplugged.
+ *
+ * <p>The intent will have the following extra values:
+ * <ul>
+ * <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
+ * <li><em>card</em> - ALSA card number (integer) </li>
+ * <li><em>device</em> - ALSA device number (integer) </li>
+ * </ul>
+ * </ul>
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_USB_AUDIO_DEVICE_PLUG =
+ "android.intent.action.USB_AUDIO_DEVICE_PLUG";
+
+ /**
+ * Broadcast Action: A USB audio accessory was plugged in or unplugged.
+ *
+ * <p>The intent will have the following extra values:
+ * <ul>
+ * <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
+ * <li><em>card</em> - ALSA card number (integer) </li>
+ * <li><em>device</em> - ALSA device number (integer) </li>
+ * </ul>
+ * </ul>
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_USB_AUDIO_ACCESSORY_PLUG =
+ "android.intent.action.USB_AUDIO_ACCESSORY_PLUG";
+
+ /**
* <p>Broadcast Action: The user has switched on advanced settings in the settings app:</p>
* <ul>
* <li><em>state</em> - A boolean value indicating whether the settings is on or off.</li>
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 0e6694de..6b16e74 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -450,6 +450,11 @@
*/
public static final int UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW = 1;
+ /**
+ * If defined, the activity named here is the logical parent of this activity.
+ */
+ public String parentActivityName;
+
public ActivityInfo() {
}
@@ -465,6 +470,7 @@
configChanges = orig.configChanges;
softInputMode = orig.softInputMode;
uiOptions = orig.uiOptions;
+ parentActivityName = orig.parentActivityName;
}
/**
@@ -524,6 +530,7 @@
dest.writeInt(configChanges);
dest.writeInt(softInputMode);
dest.writeInt(uiOptions);
+ dest.writeString(parentActivityName);
}
public static final Parcelable.Creator<ActivityInfo> CREATOR
@@ -548,5 +555,6 @@
configChanges = source.readInt();
softInputMode = source.readInt();
uiOptions = source.readInt();
+ parentActivityName = source.readString();
}
}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index a79b86a..7ff9bfa 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -94,10 +94,12 @@
public static class SplitPermissionInfo {
public final String rootPerm;
public final String[] newPerms;
+ public final int targetSdk;
- public SplitPermissionInfo(String rootPerm, String[] newPerms) {
+ public SplitPermissionInfo(String rootPerm, String[] newPerms, int targetSdk) {
this.rootPerm = rootPerm;
this.newPerms = newPerms;
+ this.targetSdk = targetSdk;
}
}
@@ -126,7 +128,14 @@
public static final PackageParser.SplitPermissionInfo SPLIT_PERMISSIONS[] =
new PackageParser.SplitPermissionInfo[] {
new PackageParser.SplitPermissionInfo(android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
- new String[] { android.Manifest.permission.READ_EXTERNAL_STORAGE })
+ new String[] { android.Manifest.permission.READ_EXTERNAL_STORAGE },
+ android.os.Build.VERSION_CODES.CUR_DEVELOPMENT+1),
+ new PackageParser.SplitPermissionInfo(android.Manifest.permission.READ_CONTACTS,
+ new String[] { android.Manifest.permission.READ_CALL_LOG },
+ android.os.Build.VERSION_CODES.JELLY_BEAN),
+ new PackageParser.SplitPermissionInfo(android.Manifest.permission.WRITE_CONTACTS,
+ new String[] { android.Manifest.permission.WRITE_CALL_LOG },
+ android.os.Build.VERSION_CODES.JELLY_BEAN)
};
private String mArchiveSourcePath;
@@ -1293,7 +1302,8 @@
for (int is=0; is<NS; is++) {
final PackageParser.SplitPermissionInfo spi
= PackageParser.SPLIT_PERMISSIONS[is];
- if (!pkg.requestedPermissions.contains(spi.rootPerm)) {
+ if (pkg.applicationInfo.targetSdkVersion >= spi.targetSdk
+ || !pkg.requestedPermissions.contains(spi.rootPerm)) {
break;
}
for (int in=0; in<spi.newPerms.length; in++) {
@@ -2030,6 +2040,19 @@
com.android.internal.R.styleable.AndroidManifestActivity_uiOptions,
a.info.applicationInfo.uiOptions);
+ String parentName = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestActivity_parentActivityName, 0);
+ if (parentName != null) {
+ String parentClassName = buildClassName(a.info.packageName, parentName, outError);
+ if (outError[0] == null) {
+ a.info.parentActivityName = parentClassName;
+ } else {
+ Log.e(TAG, "Activity " + a.info.name + " specified invalid parentActivityName " +
+ parentName);
+ outError[0] = null;
+ }
+ }
+
String str;
str = sa.getNonConfigurationString(
com.android.internal.R.styleable.AndroidManifestActivity_permission, 0);
@@ -2274,6 +2297,7 @@
info.theme = target.info.theme;
info.softInputMode = target.info.softInputMode;
info.uiOptions = target.info.uiOptions;
+ info.parentActivityName = target.info.parentActivityName;
Activity a = new Activity(mParseActivityAliasArgs, info);
if (outError[0] != null) {
@@ -2295,6 +2319,20 @@
a.info.permission = str.length() > 0 ? str.toString().intern() : null;
}
+ String parentName = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestActivityAlias_parentActivityName,
+ 0);
+ if (parentName != null) {
+ String parentClassName = buildClassName(a.info.packageName, parentName, outError);
+ if (outError[0] == null) {
+ a.info.parentActivityName = parentClassName;
+ } else {
+ Log.e(TAG, "Activity alias " + a.info.name +
+ " specified invalid parentActivityName " + parentName);
+ outError[0] = null;
+ }
+ }
+
sa.recycle();
if (outError[0] != null) {
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
new file mode 100644
index 0000000..c2abce5
--- /dev/null
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -0,0 +1,37 @@
+/*
+ * 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.view.InputDevice;
+import android.view.InputEvent;
+
+/** @hide */
+interface IInputManager {
+ // Gets input device information.
+ InputDevice getInputDevice(int deviceId);
+ int[] getInputDeviceIds();
+
+ // Reports whether the hardware supports the given keys; returns true if successful
+ boolean hasKeys(int deviceId, int sourceMask, in int[] keyCodes, out boolean[] keyExists);
+
+ // Temporarily changes the pointer speed.
+ void tryPointerSpeed(int speed);
+
+ // 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);
+}
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
new file mode 100755
index 0000000..ba64035f
--- /dev/null
+++ b/core/java/android/hardware/input/InputManager.java
@@ -0,0 +1,654 @@
+/*
+ * 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 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.view.Display;
+import android.view.IWindowManager;
+import android.view.InputDevice;
+import android.view.InputEvent;
+import android.view.KeyCharacterMap;
+import android.view.WindowManagerPolicy;
+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.
+ * <p>
+ * Get an instance of this class by calling
+ * {@link android.content.Context#getSystemService(java.lang.String)
+ * Context.getSystemService()} with the argument
+ * {@link android.content.Context#INPUT_SERVICE}.
+ * </p>
+ */
+public final class InputManager {
+ private static final String TAG = "InputManager";
+
+ private static final IInputManager sIm;
+
+ private final Context mContext;
+
+ // Used to simulate a persistent data store.
+ // TODO: Replace with the real thing.
+ private static final HashMap<String, String> mFakeRegistry = new HashMap<String, String>();
+
+ /**
+ * Broadcast Action: Query available keyboard layouts.
+ * <p>
+ * The input manager service locates available keyboard layouts
+ * by querying broadcast receivers that are registered for this action.
+ * An application can offer additional keyboard layouts to the user
+ * by declaring a suitable broadcast receiver in its manifest.
+ * </p><p>
+ * Here is an example broadcast receiver declaration that an application
+ * might include in its AndroidManifest.xml to advertise keyboard layouts.
+ * The meta-data specifies a resource that contains a description of each keyboard
+ * layout that is provided by the application.
+ * <pre><code>
+ * <receiver android:name=".InputDeviceReceiver">
+ * <intent-filter>
+ * <action android:name="android.hardware.input.action.QUERY_KEYBOARD_LAYOUTS" />
+ * </intent-filter>
+ * <meta-data android:name="android.hardware.input.metadata.KEYBOARD_LAYOUTS"
+ * android:resource="@xml/keyboard_layouts" />
+ * </receiver>
+ * </code></pre>
+ * </p><p>
+ * In the above example, the <code>@xml/keyboard_layouts</code> resource refers to
+ * an XML resource whose root element is <code><keyboard-layouts></code> that
+ * contains zero or more <code><keyboard-layout></code> elements.
+ * Each <code><keyboard-layout></code> element specifies the name, label, and location
+ * of a key character map for a particular keyboard layout.
+ * <pre></code>
+ * <?xml version="1.0" encoding="utf-8"?>
+ * <keyboard-layouts xmlns:android="http://schemas.android.com/apk/res/android">
+ * <keyboard-layout android:name="keyboard_layout_english_us"
+ * android:label="@string/keyboard_layout_english_us_label"
+ * android:kcm="@raw/keyboard_layout_english_us" />
+ * </keyboard-layouts>
+ * </p><p>
+ * The <code>android:name</code> attribute specifies an identifier by which
+ * the keyboard layout will be known in the package.
+ * The <code>android:label</code> attributes specifies a human-readable descriptive
+ * label to describe the keyboard layout in the user interface, such as "English (US)".
+ * The <code>android:kcm</code> attribute refers to a
+ * <a href="http://source.android.com/tech/input/key-character-map-files.html">
+ * key character map</a> resource that defines the keyboard layout.
+ * </p>
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_QUERY_KEYBOARD_LAYOUTS =
+ "android.hardware.input.action.QUERY_KEYBOARD_LAYOUTS";
+
+ /**
+ * Metadata Key: Keyboard layout metadata associated with
+ * {@link #ACTION_QUERY_KEYBOARD_LAYOUTS}.
+ * <p>
+ * Specifies the resource id of a XML resource that describes the keyboard
+ * layouts that are provided by the application.
+ * </p>
+ */
+ public static final String META_DATA_KEYBOARD_LAYOUTS =
+ "android.hardware.input.metadata.KEYBOARD_LAYOUTS";
+
+ /**
+ * Pointer Speed: The minimum (slowest) pointer speed (-7).
+ * @hide
+ */
+ public static final int MIN_POINTER_SPEED = -7;
+
+ /**
+ * Pointer Speed: The maximum (fastest) pointer speed (7).
+ * @hide
+ */
+ public static final int MAX_POINTER_SPEED = 7;
+
+ /**
+ * Pointer Speed: The default pointer speed (0).
+ * @hide
+ */
+ public static final int DEFAULT_POINTER_SPEED = 0;
+
+ /**
+ * Input Event Injection Synchronization Mode: None.
+ * Never blocks. Injection is asynchronous and is assumed always to be successful.
+ * @hide
+ */
+ public static final int INJECT_INPUT_EVENT_MODE_ASYNC = 0; // see InputDispatcher.h
+
+ /**
+ * Input Event Injection Synchronization Mode: Wait for result.
+ * Waits for previous events to be dispatched so that the input dispatcher can
+ * determine whether input event injection will be permitted based on the current
+ * input focus. Does not wait for the input event to finish being handled
+ * by the application.
+ * @hide
+ */
+ public static final int INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT = 1; // see InputDispatcher.h
+
+ /**
+ * Input Event Injection Synchronization Mode: Wait for finish.
+ * Waits for the event to be delivered to the application and handled.
+ * @hide
+ */
+ 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);
+ }
+
+ /** @hide */
+ public InputManager(Context context) {
+ mContext = context;
+ }
+
+ /**
+ * Gets information about all supported keyboard layouts.
+ * <p>
+ * The input manager consults the built-in keyboard layouts as well
+ * as all keyboard layouts advertised by applications using a
+ * {@link #ACTION_QUERY_KEYBOARD_LAYOUTS} broadcast receiver.
+ * </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);
+ }
+ return list;
+ }
+
+ /**
+ * Gets the keyboard layout with the specified descriptor.
+ *
+ * @param keyboardLayoutDescriptor The keyboard layout descriptor, as returned by
+ * {@link KeyboardLayout#getDescriptor()}.
+ * @return The keyboard layout, or null if it could not be loaded.
+ *
+ * @hide
+ */
+ public KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor) {
+ if (keyboardLayoutDescriptor == null) {
+ 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 null;
+ }
+ }
+
+ /**
+ * Gets the keyboard layout descriptor for the specified input device.
+ *
+ * @param inputDeviceDescriptor The input device descriptor.
+ * @return The keyboard layout descriptor, or null if unknown or if the default
+ * keyboard layout will be used.
+ *
+ * @hide
+ */
+ public String getInputDeviceKeyboardLayoutDescriptor(String inputDeviceDescriptor) {
+ if (inputDeviceDescriptor == null) {
+ throw new IllegalArgumentException("inputDeviceDescriptor must not be null");
+ }
+
+ return mFakeRegistry.get(inputDeviceDescriptor);
+ }
+
+ /**
+ * Sets the keyboard layout descriptor for the specified input device.
+ * <p>
+ * This method may have the side-effect of causing the input device in question
+ * to be reconfigured.
+ * </p>
+ *
+ * @param inputDeviceDescriptor The input device descriptor.
+ * @param keyboardLayoutDescriptor The keyboard layout descriptor, or null to remove
+ * the mapping so that the default keyboard layout will be used for the input device.
+ *
+ * @hide
+ */
+ public void setInputDeviceKeyboardLayoutDescriptor(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.");
+ }
+ return null;
+ }
+
+ /**
+ * Gets the mouse pointer speed.
+ * <p>
+ * Only returns the permanent mouse pointer speed. Ignores any temporary pointer
+ * speed set by {@link #tryPointerSpeed}.
+ * </p>
+ *
+ * @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() {
+ int speed = DEFAULT_POINTER_SPEED;
+ try {
+ speed = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.POINTER_SPEED);
+ } catch (SettingNotFoundException snfe) {
+ }
+ return speed;
+ }
+
+ /**
+ * Sets the mouse pointer speed.
+ * <p>
+ * Requires {@link android.Manifest.permissions.WRITE_SETTINGS}.
+ * </p>
+ *
+ * @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) {
+ if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) {
+ throw new IllegalArgumentException("speed out of range");
+ }
+
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.POINTER_SPEED, speed);
+ }
+
+ /**
+ * Changes the mouse pointer speed temporarily, but does not save the setting.
+ * <p>
+ * Requires {@link android.Manifest.permission.SET_POINTER_SPEED}.
+ * </p>
+ *
+ * @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 tryPointerSpeed(int speed) {
+ if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) {
+ throw new IllegalArgumentException("speed out of range");
+ }
+
+ try {
+ sIm.tryPointerSpeed(speed);
+ } catch (RemoteException ex) {
+ Log.w(TAG, "Could not set temporary pointer speed.", ex);
+ }
+ }
+
+ /**
+ * Gets information about the input device with the specified id.
+ * @param id The device id.
+ * @return The input device or null if not found.
+ *
+ * @hide
+ */
+ public static InputDevice getInputDevice(int id) {
+ try {
+ return sIm.getInputDevice(id);
+ } catch (RemoteException ex) {
+ throw new RuntimeException("Could not get input device information.", ex);
+ }
+ }
+
+ /**
+ * Gets the ids of all input devices in the system.
+ * @return The input device ids.
+ *
+ * @hide
+ */
+ public static int[] getInputDeviceIds() {
+ try {
+ return sIm.getInputDeviceIds();
+ } catch (RemoteException ex) {
+ throw new RuntimeException("Could not get input device ids.", ex);
+ }
+ }
+
+ /**
+ * Queries the framework about whether any physical keys exist on the
+ * any keyboard attached to the device that are capable of producing the given
+ * array of key codes.
+ *
+ * @param keyCodes The array of key codes to query.
+ * @return A new array of the same size as the key codes array whose elements
+ * are set to true if at least one attached keyboard supports the corresponding key code
+ * at the same index in the key codes array.
+ *
+ * @hide
+ */
+ public static boolean[] deviceHasKeys(int[] keyCodes) {
+ boolean[] ret = new boolean[keyCodes.length];
+ try {
+ sIm.hasKeys(-1, InputDevice.SOURCE_ANY, keyCodes, ret);
+ } catch (RemoteException e) {
+ // no fallback; just return the empty array
+ }
+ return ret;
+ }
+
+ /**
+ * Injects an input event into the event system on behalf of an application.
+ * The synchronization mode determines whether the method blocks while waiting for
+ * input injection to proceed.
+ * <p>
+ * Requires {@link android.Manifest.permission.INJECT_EVENTS} to inject into
+ * windows that are owned by other applications.
+ * </p><p>
+ * Make sure you correctly set the event time and input source of the event
+ * before calling this method.
+ * </p>
+ *
+ * @param event The event to inject.
+ * @param mode The synchronization mode. One of:
+ * {@link #INJECT_INPUT_EVENT_MODE_ASYNC},
+ * {@link #INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT}, or
+ * {@link #INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH}.
+ * @return True if input event injection succeeded.
+ *
+ * @hide
+ */
+ public static boolean injectInputEvent(InputEvent event, int mode) {
+ if (event == null) {
+ throw new IllegalArgumentException("event must not be null");
+ }
+ if (mode != INJECT_INPUT_EVENT_MODE_ASYNC
+ && mode != INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH
+ && mode != INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT) {
+ throw new IllegalArgumentException("mode is invalid");
+ }
+
+ try {
+ return sIm.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/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 93f93c7..c40504a7 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -66,6 +66,8 @@
* PTP function is enabled
* <li> {@link #USB_FUNCTION_PTP} boolean extra indicating whether the
* accessory function is enabled
+ * <li> {@link #USB_FUNCTION_AUDIO_SOURCE} boolean extra indicating whether the
+ * audio source function is enabled
* </ul>
*
* {@hide}
@@ -178,6 +180,14 @@
public static final String USB_FUNCTION_PTP = "ptp";
/**
+ * Name of the audio source USB function.
+ * Used in extras for the {@link #ACTION_USB_STATE} broadcast
+ *
+ * {@hide}
+ */
+ public static final String USB_FUNCTION_AUDIO_SOURCE = "audio_source";
+
+ /**
* Name of the Accessory USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
*
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 2eef8f4..de16985 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -20,6 +20,7 @@
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.content.Context;
import android.os.Binder;
import android.os.Build.VERSION_CODES;
import android.os.RemoteException;
@@ -610,6 +611,11 @@
mService = checkNotNull(service, "missing IConnectivityManager");
}
+ /** {@hide} */
+ public static ConnectivityManager from(Context context) {
+ return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ }
+
/**
* {@hide}
*/
diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java
index ee12989..4ac5e76 100644
--- a/core/java/android/net/NetworkIdentity.java
+++ b/core/java/android/net/NetworkIdentity.java
@@ -16,9 +16,13 @@
package android.net;
+import static android.net.ConnectivityManager.TYPE_WIFI;
+import static android.net.ConnectivityManager.getNetworkTypeName;
import static android.net.ConnectivityManager.isNetworkTypeMobile;
import android.content.Context;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
import android.os.Build;
import android.telephony.TelephonyManager;
@@ -42,18 +46,21 @@
final int mType;
final int mSubType;
final String mSubscriberId;
+ final String mNetworkId;
final boolean mRoaming;
- public NetworkIdentity(int type, int subType, String subscriberId, boolean roaming) {
- this.mType = type;
- this.mSubType = COMBINE_SUBTYPE_ENABLED ? SUBTYPE_COMBINED : subType;
- this.mSubscriberId = subscriberId;
- this.mRoaming = roaming;
+ public NetworkIdentity(
+ int type, int subType, String subscriberId, String networkId, boolean roaming) {
+ mType = type;
+ mSubType = COMBINE_SUBTYPE_ENABLED ? SUBTYPE_COMBINED : subType;
+ mSubscriberId = subscriberId;
+ mNetworkId = networkId;
+ mRoaming = roaming;
}
@Override
public int hashCode() {
- return Objects.hashCode(mType, mSubType, mSubscriberId, mRoaming);
+ return Objects.hashCode(mType, mSubType, mSubscriberId, mNetworkId, mRoaming);
}
@Override
@@ -61,27 +68,34 @@
if (obj instanceof NetworkIdentity) {
final NetworkIdentity ident = (NetworkIdentity) obj;
return mType == ident.mType && mSubType == ident.mSubType && mRoaming == ident.mRoaming
- && Objects.equal(mSubscriberId, ident.mSubscriberId);
+ && Objects.equal(mSubscriberId, ident.mSubscriberId)
+ && Objects.equal(mNetworkId, ident.mNetworkId);
}
return false;
}
@Override
public String toString() {
- final String typeName = ConnectivityManager.getNetworkTypeName(mType);
- final String subTypeName;
+ final StringBuilder builder = new StringBuilder("[");
+ builder.append("type=").append(getNetworkTypeName(mType));
+ builder.append(", subType=");
if (COMBINE_SUBTYPE_ENABLED) {
- subTypeName = "COMBINED";
+ builder.append("COMBINED");
} else if (ConnectivityManager.isNetworkTypeMobile(mType)) {
- subTypeName = TelephonyManager.getNetworkTypeName(mSubType);
+ builder.append(TelephonyManager.getNetworkTypeName(mSubType));
} else {
- subTypeName = Integer.toString(mSubType);
+ builder.append(mSubType);
}
-
- final String scrubSubscriberId = scrubSubscriberId(mSubscriberId);
- final String roaming = mRoaming ? ", ROAMING" : "";
- return "[type=" + typeName + ", subType=" + subTypeName + ", subscriberId="
- + scrubSubscriberId + roaming + "]";
+ if (mSubscriberId != null) {
+ builder.append(", subscriberId=").append(scrubSubscriberId(mSubscriberId));
+ }
+ if (mNetworkId != null) {
+ builder.append(", networkId=").append(mNetworkId);
+ }
+ if (mRoaming) {
+ builder.append(", ROAMING");
+ }
+ return builder.append("]").toString();
}
public int getType() {
@@ -96,6 +110,10 @@
return mSubscriberId;
}
+ public String getNetworkId() {
+ return mNetworkId;
+ }
+
public boolean getRoaming() {
return mRoaming;
}
@@ -106,8 +124,11 @@
public static String scrubSubscriberId(String subscriberId) {
if ("eng".equals(Build.TYPE)) {
return subscriberId;
+ } else if (subscriberId != null) {
+ // TODO: parse this as MCC+MNC instead of hard-coding
+ return subscriberId.substring(0, Math.min(6, subscriberId.length())) + "...";
} else {
- return subscriberId != null ? "valid" : "null";
+ return "null";
}
}
@@ -122,8 +143,10 @@
// TODO: consider moving subscriberId over to LinkCapabilities, so it
// comes from an authoritative source.
- final String subscriberId;
- final boolean roaming;
+ String subscriberId = null;
+ String networkId = null;
+ boolean roaming = false;
+
if (isNetworkTypeMobile(type)) {
final TelephonyManager telephony = (TelephonyManager) context.getSystemService(
Context.TELEPHONY_SERVICE);
@@ -133,10 +156,13 @@
} else {
subscriberId = telephony.getSubscriberId();
}
- } else {
- subscriberId = null;
- roaming = false;
+
+ } else if (type == TYPE_WIFI) {
+ final WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+ final WifiInfo info = wifi.getConnectionInfo();
+ networkId = info != null ? info.getSSID() : null;
}
- return new NetworkIdentity(type, subType, subscriberId, roaming);
+
+ return new NetworkIdentity(type, subType, subscriberId, networkId, roaming);
}
}
diff --git a/core/java/android/net/NetworkPolicy.java b/core/java/android/net/NetworkPolicy.java
index c1f58a3..441db7a 100644
--- a/core/java/android/net/NetworkPolicy.java
+++ b/core/java/android/net/NetworkPolicy.java
@@ -30,6 +30,7 @@
* @hide
*/
public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
+ public static final int CYCLE_NONE = -1;
public static final long WARNING_DISABLED = -1;
public static final long LIMIT_DISABLED = -1;
public static final long SNOOZE_NEVER = -1;
@@ -123,6 +124,13 @@
lastLimitSnooze = SNOOZE_NEVER;
}
+ /**
+ * Test if this policy has a cycle defined, after which usage should reset.
+ */
+ public boolean hasCycle() {
+ return cycleDay != CYCLE_NONE;
+ }
+
@Override
public int compareTo(NetworkPolicy another) {
if (another == null || another.limitBytes == LIMIT_DISABLED) {
@@ -159,10 +167,17 @@
@Override
public String toString() {
- return "NetworkPolicy[" + template + "]: cycleDay=" + cycleDay + ", cycleTimezone="
- + cycleTimezone + ", warningBytes=" + warningBytes + ", limitBytes=" + limitBytes
- + ", lastWarningSnooze=" + lastWarningSnooze + ", lastLimitSnooze="
- + lastLimitSnooze + ", metered=" + metered + ", inferred=" + inferred;
+ final StringBuilder builder = new StringBuilder("NetworkPolicy");
+ builder.append("[").append(template).append("]:");
+ builder.append(" cycleDay=").append(cycleDay);
+ builder.append(", cycleTimezone=").append(cycleTimezone);
+ builder.append(", warningBytes=").append(warningBytes);
+ builder.append(", limitBytes=").append(limitBytes);
+ builder.append(", lastWarningSnooze=").append(lastWarningSnooze);
+ builder.append(", lastLimitSnooze=").append(lastLimitSnooze);
+ builder.append(", metered=").append(metered);
+ builder.append(", inferred=").append(inferred);
+ return builder.toString();
}
public static final Creator<NetworkPolicy> CREATOR = new Creator<NetworkPolicy>() {
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index c09c676..2b36131 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -17,6 +17,7 @@
package android.net;
import static android.content.pm.PackageManager.GET_SIGNATURES;
+import static android.net.NetworkPolicy.CYCLE_NONE;
import static android.text.format.Time.MONTH_DAY;
import android.content.Context;
@@ -66,27 +67,10 @@
mService = service;
}
- public static NetworkPolicyManager getSystemService(Context context) {
+ public static NetworkPolicyManager from(Context context) {
return (NetworkPolicyManager) context.getSystemService(Context.NETWORK_POLICY_SERVICE);
}
- /** {@hide} */
- public void setNetworkPolicies(NetworkPolicy[] policies) {
- try {
- mService.setNetworkPolicies(policies);
- } catch (RemoteException e) {
- }
- }
-
- /** {@hide} */
- public NetworkPolicy[] getNetworkPolicies() {
- try {
- return mService.getNetworkPolicies();
- } catch (RemoteException e) {
- return null;
- }
- }
-
/**
* Set policy flags for specific application.
*
@@ -122,6 +106,36 @@
}
}
+ public void setNetworkPolicies(NetworkPolicy[] policies) {
+ try {
+ mService.setNetworkPolicies(policies);
+ } catch (RemoteException e) {
+ }
+ }
+
+ public NetworkPolicy[] getNetworkPolicies() {
+ try {
+ return mService.getNetworkPolicies();
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ public void setRestrictBackground(boolean restrictBackground) {
+ try {
+ mService.setRestrictBackground(restrictBackground);
+ } catch (RemoteException e) {
+ }
+ }
+
+ public boolean getRestrictBackground() {
+ try {
+ return mService.getRestrictBackground();
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
/**
* Compute the last cycle boundary for the given {@link NetworkPolicy}. For
* example, if cycle day is 20th, and today is June 15th, it will return May
@@ -131,6 +145,10 @@
* @hide
*/
public static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) {
+ if (policy.cycleDay == CYCLE_NONE) {
+ throw new IllegalArgumentException("Unable to compute boundary without cycleDay");
+ }
+
final Time now = new Time(policy.cycleTimezone);
now.set(currentTime);
@@ -157,6 +175,10 @@
/** {@hide} */
public static long computeNextCycleBoundary(long currentTime, NetworkPolicy policy) {
+ if (policy.cycleDay == CYCLE_NONE) {
+ throw new IllegalArgumentException("Unable to compute boundary without cycleDay");
+ }
+
final Time now = new Time(policy.cycleTimezone);
now.set(currentTime);
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index e1fbdcc..50432a1 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -43,15 +43,10 @@
*/
public class NetworkTemplate implements Parcelable {
- /** {@hide} */
public static final int MATCH_MOBILE_ALL = 1;
- /** {@hide} */
public static final int MATCH_MOBILE_3G_LOWER = 2;
- /** {@hide} */
public static final int MATCH_MOBILE_4G = 3;
- /** {@hide} */
public static final int MATCH_WIFI = 4;
- /** {@hide} */
public static final int MATCH_ETHERNET = 5;
/**
@@ -65,37 +60,50 @@
}
/**
- * Template to combine all {@link ConnectivityManager#TYPE_MOBILE} style
- * networks together. Only uses statistics for requested IMSI.
+ * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
+ * the given IMSI.
*/
public static NetworkTemplate buildTemplateMobileAll(String subscriberId) {
- return new NetworkTemplate(MATCH_MOBILE_ALL, subscriberId);
+ return new NetworkTemplate(MATCH_MOBILE_ALL, subscriberId, null);
}
/**
- * Template to combine all {@link ConnectivityManager#TYPE_MOBILE} style
- * networks together that roughly meet a "3G" definition, or lower. Only
- * uses statistics for requested IMSI.
+ * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
+ * the given IMSI that roughly meet a "3G" definition, or lower.
*/
+ @Deprecated
public static NetworkTemplate buildTemplateMobile3gLower(String subscriberId) {
- return new NetworkTemplate(MATCH_MOBILE_3G_LOWER, subscriberId);
+ return new NetworkTemplate(MATCH_MOBILE_3G_LOWER, subscriberId, null);
}
/**
- * Template to combine all {@link ConnectivityManager#TYPE_MOBILE} style
- * networks together that meet a "4G" definition. Only uses statistics for
- * requested IMSI.
+ * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
+ * the given IMSI that roughly meet a "4G" definition.
*/
+ @Deprecated
public static NetworkTemplate buildTemplateMobile4g(String subscriberId) {
- return new NetworkTemplate(MATCH_MOBILE_4G, subscriberId);
+ return new NetworkTemplate(MATCH_MOBILE_4G, subscriberId, null);
}
/**
- * Template to combine all {@link ConnectivityManager#TYPE_WIFI} style
- * networks together.
+ * Template to match all {@link ConnectivityManager#TYPE_WIFI} networks,
+ * regardless of SSID.
*/
+ public static NetworkTemplate buildTemplateWifiWildcard() {
+ return new NetworkTemplate(MATCH_WIFI, null, null);
+ }
+
+ @Deprecated
public static NetworkTemplate buildTemplateWifi() {
- return new NetworkTemplate(MATCH_WIFI, null);
+ return buildTemplateWifiWildcard();
+ }
+
+ /**
+ * Template to match {@link ConnectivityManager#TYPE_WIFI} networks with the
+ * given SSID.
+ */
+ public static NetworkTemplate buildTemplateWifi(String networkId) {
+ return new NetworkTemplate(MATCH_WIFI, null, networkId);
}
/**
@@ -103,44 +111,53 @@
* networks together.
*/
public static NetworkTemplate buildTemplateEthernet() {
- return new NetworkTemplate(MATCH_ETHERNET, null);
+ return new NetworkTemplate(MATCH_ETHERNET, null, null);
}
private final int mMatchRule;
private final String mSubscriberId;
+ private final String mNetworkId;
- /** {@hide} */
- public NetworkTemplate(int matchRule, String subscriberId) {
- this.mMatchRule = matchRule;
- this.mSubscriberId = subscriberId;
+ public NetworkTemplate(int matchRule, String subscriberId, String networkId) {
+ mMatchRule = matchRule;
+ mSubscriberId = subscriberId;
+ mNetworkId = networkId;
}
private NetworkTemplate(Parcel in) {
mMatchRule = in.readInt();
mSubscriberId = in.readString();
+ mNetworkId = in.readString();
}
- /** {@inheritDoc} */
+ @Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mMatchRule);
dest.writeString(mSubscriberId);
+ dest.writeString(mNetworkId);
}
- /** {@inheritDoc} */
+ @Override
public int describeContents() {
return 0;
}
@Override
public String toString() {
- final String scrubSubscriberId = scrubSubscriberId(mSubscriberId);
- return "NetworkTemplate: matchRule=" + getMatchRuleName(mMatchRule) + ", subscriberId="
- + scrubSubscriberId;
+ final StringBuilder builder = new StringBuilder("NetworkTemplate: ");
+ builder.append("matchRule=").append(getMatchRuleName(mMatchRule));
+ if (mSubscriberId != null) {
+ builder.append(", subscriberId=").append(scrubSubscriberId(mSubscriberId));
+ }
+ if (mNetworkId != null) {
+ builder.append(", networkId=").append(mNetworkId);
+ }
+ return builder.toString();
}
@Override
public int hashCode() {
- return Objects.hashCode(mMatchRule, mSubscriberId);
+ return Objects.hashCode(mMatchRule, mSubscriberId, mNetworkId);
}
@Override
@@ -148,21 +165,24 @@
if (obj instanceof NetworkTemplate) {
final NetworkTemplate other = (NetworkTemplate) obj;
return mMatchRule == other.mMatchRule
- && Objects.equal(mSubscriberId, other.mSubscriberId);
+ && Objects.equal(mSubscriberId, other.mSubscriberId)
+ && Objects.equal(mNetworkId, other.mNetworkId);
}
return false;
}
- /** {@hide} */
public int getMatchRule() {
return mMatchRule;
}
- /** {@hide} */
public String getSubscriberId() {
return mSubscriberId;
}
+ public String getNetworkId() {
+ return mNetworkId;
+ }
+
/**
* Test if given {@link NetworkIdentity} matches this template.
*/
@@ -237,8 +257,13 @@
private boolean matchesWifi(NetworkIdentity ident) {
switch (ident.mType) {
case TYPE_WIFI:
+ if (mNetworkId == null) {
+ return true;
+ } else {
+ return Objects.equal(mNetworkId, ident.mNetworkId);
+ }
case TYPE_WIFI_P2P:
- return true;
+ return mNetworkId == null;
default:
return false;
}
@@ -279,10 +304,12 @@
}
public static final Creator<NetworkTemplate> CREATOR = new Creator<NetworkTemplate>() {
+ @Override
public NetworkTemplate createFromParcel(Parcel in) {
return new NetworkTemplate(in);
}
+ @Override
public NetworkTemplate[] newArray(int size) {
return new NetworkTemplate[size];
}
diff --git a/core/java/android/nfc/INdefPushCallback.aidl b/core/java/android/nfc/INdefPushCallback.aidl
index e60a5b0..4e79822 100644
--- a/core/java/android/nfc/INdefPushCallback.aidl
+++ b/core/java/android/nfc/INdefPushCallback.aidl
@@ -17,6 +17,7 @@
package android.nfc;
import android.nfc.NdefMessage;
+import android.net.Uri;
/**
* @hide
@@ -24,5 +25,7 @@
interface INdefPushCallback
{
NdefMessage createMessage();
+ Uri getUri();
+ String getMimeType();
void onNdefPushComplete();
}
diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java
index 2c73056..f80dae4 100644
--- a/core/java/android/nfc/NfcActivityManager.java
+++ b/core/java/android/nfc/NfcActivityManager.java
@@ -18,6 +18,7 @@
import android.app.Activity;
import android.app.Application;
+import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
@@ -107,10 +108,16 @@
NdefMessage ndefMessage = null; // static NDEF message
NfcAdapter.CreateNdefMessageCallback ndefMessageCallback = null;
NfcAdapter.OnNdefPushCompleteCallback onNdefPushCompleteCallback = null;
+ Uri uri = null;
+ String mimeType = null;
public NfcActivityState(Activity activity) {
if (activity.getWindow().isDestroyed()) {
throw new IllegalStateException("activity is already destroyed");
}
+ // Check if activity is resumed right now, as we will not
+ // immediately get a callback for that.
+ resumed = activity.isResumed();
+
this.activity = activity;
registerApplication(activity.getApplication());
}
@@ -121,12 +128,14 @@
ndefMessage = null;
ndefMessageCallback = null;
onNdefPushCompleteCallback = null;
+ uri = null;
+ mimeType = null;
}
@Override
public String toString() {
StringBuilder s = new StringBuilder("[").append(" ");
s.append(ndefMessage).append(" ").append(ndefMessageCallback).append(" ");
- s.append(onNdefPushCompleteCallback).append("]");
+ s.append(onNdefPushCompleteCallback).append(" ").append(uri).append("]");
return s.toString();
}
}
@@ -175,6 +184,19 @@
mDefaultEvent = new NfcEvent(mAdapter);
}
+ public void setNdefPushContentUri(Activity activity, String mimeType, Uri uri) {
+ boolean isResumed;
+ synchronized (NfcActivityManager.this) {
+ NfcActivityState state = getActivityState(activity);
+ state.uri = uri;
+ state.mimeType = mimeType;
+ isResumed = state.resumed;
+ }
+ if (isResumed) {
+ requestNfcServiceCallback(true);
+ }
+ }
+
public void setNdefPushMessage(Activity activity, NdefMessage message) {
boolean isResumed;
synchronized (NfcActivityManager.this) {
@@ -249,6 +271,26 @@
/** Callback from NFC service, usually on binder thread */
@Override
+ public Uri getUri() {
+ synchronized (NfcActivityManager.this) {
+ NfcActivityState state = findResumedActivityState();
+ if (state == null) return null;
+
+ return state.uri;
+ }
+ }
+ /** Callback from NFC service, usually on binder thread */
+ @Override
+ public String getMimeType() {
+ synchronized (NfcActivityManager.this) {
+ NfcActivityState state = findResumedActivityState();
+ if (state == null) return null;
+
+ return state.mimeType;
+ }
+ }
+ /** Callback from NFC service, usually on binder thread */
+ @Override
public void onNdefPushComplete() {
NfcAdapter.OnNdefPushCompleteCallback callback;
synchronized (NfcActivityManager.this) {
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index d78e06c..917751c 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -28,6 +28,7 @@
import android.content.IntentFilter;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
+import android.net.Uri;
import android.nfc.tech.MifareClassic;
import android.nfc.tech.Ndef;
import android.nfc.tech.NfcA;
@@ -555,6 +556,18 @@
}
}
+ //TODO: Consider a callback alternative
+ //TOOD: See if we get rid of mimeType
+ //TODO: make sure NFC service has permission for URI
+ //TODO: javadoc
+ /** @hide */
+ public void setBeamPushUri(String mimeType, Uri uri, Activity activity) {
+ if (activity == null) {
+ throw new NullPointerException("activity cannot be null");
+ }
+ mNfcActivityManager.setNdefPushContentUri(activity, mimeType, uri);
+ }
+
/**
* Set a static {@link NdefMessage} to send using Android Beam (TM).
*
diff --git a/core/java/android/nfc/tech/MifareClassic.java b/core/java/android/nfc/tech/MifareClassic.java
index 9d1e6a1..8c92288 100644
--- a/core/java/android/nfc/tech/MifareClassic.java
+++ b/core/java/android/nfc/tech/MifareClassic.java
@@ -150,6 +150,7 @@
mIsEmulated = false;
switch (a.getSak()) {
+ case 0x01:
case 0x08:
mType = TYPE_CLASSIC;
mSize = SIZE_1K;
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 830a85f..371e2a1 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -36,14 +36,19 @@
import android.net.wifi.WifiManager;
import android.os.BatteryManager;
import android.os.Bundle;
+import android.os.IBinder;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.SystemProperties;
+import android.os.UserId;
import android.speech.tts.TextToSpeech;
import android.text.TextUtils;
import android.util.AndroidException;
import android.util.Log;
import android.view.WindowOrientationListener;
+import com.android.internal.widget.ILockSettings;
+
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.HashSet;
@@ -2253,6 +2258,16 @@
// Populated lazily, guarded by class object:
private static NameValueCache sNameValueCache = null;
+ private static ILockSettings sLockSettings = null;
+
+ private static final HashSet<String> MOVED_TO_LOCK_SETTINGS;
+ static {
+ MOVED_TO_LOCK_SETTINGS = new HashSet<String>(3);
+ MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_PATTERN_ENABLED);
+ MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_PATTERN_VISIBLE);
+ MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED);
+ }
+
/**
* Look up a name in the database.
* @param resolver to access the database with
@@ -2264,6 +2279,19 @@
sNameValueCache = new NameValueCache(SYS_PROP_SETTING_VERSION, CONTENT_URI,
CALL_METHOD_GET_SECURE);
}
+
+ if (sLockSettings == null) {
+ sLockSettings = ILockSettings.Stub.asInterface(
+ (IBinder) ServiceManager.getService("lock_settings"));
+ }
+ if (sLockSettings != null && MOVED_TO_LOCK_SETTINGS.contains(name)) {
+ try {
+ return sLockSettings.getString(name, "0", UserId.getCallingUserId());
+ } catch (RemoteException re) {
+ // Fall through
+ }
+ }
+
return sNameValueCache.getString(resolver, name);
}
diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java
index f7a7eb8..bb4b282 100644
--- a/core/java/android/text/SpannableStringBuilder.java
+++ b/core/java/android/text/SpannableStringBuilder.java
@@ -50,6 +50,8 @@
public SpannableStringBuilder(CharSequence text, int start, int end) {
int srclen = end - start;
+ if (srclen < 0) throw new StringIndexOutOfBoundsException();
+
int len = ArrayUtils.idealCharArraySize(srclen + 1);
mText = new char[len];
mGapStart = srclen;
@@ -153,7 +155,7 @@
if (where == mGapStart)
return;
- boolean atend = (where == length());
+ boolean atEnd = (where == length());
if (where < mGapStart) {
int overlap = mGapStart - where;
@@ -179,7 +181,7 @@
else if (start == where) {
int flag = (mSpanFlags[i] & START_MASK) >> START_SHIFT;
- if (flag == POINT || (atend && flag == PARAGRAPH))
+ if (flag == POINT || (atEnd && flag == PARAGRAPH))
start += mGapLength;
}
@@ -190,7 +192,7 @@
else if (end == where) {
int flag = (mSpanFlags[i] & END_MASK);
- if (flag == POINT || (atend && flag == PARAGRAPH))
+ if (flag == POINT || (atEnd && flag == PARAGRAPH))
end += mGapLength;
}
@@ -397,7 +399,7 @@
// Documentation from interface
public SpannableStringBuilder replace(final int start, final int end,
- CharSequence tb, int tbstart, int tbend) {
+ CharSequence tb, int tbstart, int tbend) {
int filtercount = mFilters.length;
for (int i = 0; i < filtercount; i++) {
CharSequence repl = mFilters[i].filter(tb, tbstart, tbend, this, start, end);
@@ -419,53 +421,26 @@
TextWatcher[] textWatchers = getSpans(start, start + origLen, TextWatcher.class);
sendBeforeTextChanged(textWatchers, start, origLen, newLen);
- if (origLen == 0 || newLen == 0) {
- change(start, end, tb, tbstart, tbend);
- } else {
- int selstart = Selection.getSelectionStart(this);
- int selend = Selection.getSelectionEnd(this);
+ // Try to keep the cursor / selection at the same relative position during
+ // a text replacement. If replaced or replacement text length is zero, this
+ // is already taken care of.
+ boolean adjustSelection = origLen != 0 && newLen != 0;
+ int selstart = 0;
+ int selend = 0;
+ if (adjustSelection) {
+ selstart = Selection.getSelectionStart(this);
+ selend = Selection.getSelectionEnd(this);
+ }
- // XXX just make the span fixups in change() do the right thing
- // instead of this madness!
+ checkRange("replace", start, end);
- checkRange("replace", start, end);
- moveGapTo(end);
+ change(start, end, tb, tbstart, tbend);
- if (mGapLength < 2)
- resizeFor(length() + 1);
-
- for (int i = mSpanCount - 1; i >= 0; i--) {
- if (mSpanStarts[i] == mGapStart)
- mSpanStarts[i]++;
-
- if (mSpanEnds[i] == mGapStart)
- mSpanEnds[i]++;
- }
-
- mText[mGapStart] = ' ';
- mGapStart++;
- mGapLength--;
-
- if (mGapLength < 1) {
- new Exception("mGapLength < 1").printStackTrace();
- }
-
- change(start + 1, start + 1, tb, tbstart, tbend);
- change(start, start + 1, "", 0, 0);
- change(start + newLen, start + newLen + origLen, "", 0, 0);
-
- /*
- * Special case to keep the cursor in the same position
- * if it was somewhere in the middle of the replaced region.
- * If it was at the start or the end or crossing the whole
- * replacement, it should already be where it belongs.
- * TODO: Is there some more general mechanism that could
- * accomplish this?
- */
+ if (adjustSelection) {
if (selstart > start && selstart < end) {
long off = selstart - start;
- off = off * newLen / (end - start);
+ off = off * newLen / origLen;
selstart = (int) off + start;
setSpan(false, Selection.SELECTION_START, selstart, selstart,
@@ -474,7 +449,7 @@
if (selend > start && selend < end) {
long off = selend - start;
- off = off * newLen / (end - start);
+ off = off * newLen / origLen;
selend = (int) off + start;
setSpan(false, Selection.SELECTION_END, selend, selend, Spanned.SPAN_POINT_POINT);
diff --git a/core/java/android/view/GLES20TextureLayer.java b/core/java/android/view/GLES20TextureLayer.java
index cbb908b..16a13cf 100644
--- a/core/java/android/view/GLES20TextureLayer.java
+++ b/core/java/android/view/GLES20TextureLayer.java
@@ -42,6 +42,12 @@
}
}
+ GLES20TextureLayer(SurfaceTexture surface, boolean isOpaque) {
+ this(isOpaque);
+ mSurface = surface;
+ mSurface.attachToGLContext(mTexture);
+ }
+
@Override
boolean isValid() {
return mLayer != 0 && mTexture != 0;
@@ -72,6 +78,14 @@
return mSurface;
}
+ void setSurfaceTexture(SurfaceTexture surfaceTexture) {
+ if (mSurface != null) {
+ mSurface.release();
+ }
+ mSurface = surfaceTexture;
+ mSurface.attachToGLContext(mTexture);
+ }
+
@Override
void update(int width, int height, boolean isOpaque) {
super.update(width, height, isOpaque);
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index a1e7e7d..b0399fd 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -391,9 +391,9 @@
* @param isOpaque Whether the layer should be opaque or not
*
* @return A hardware layer
- */
+ */
abstract HardwareLayer createHardwareLayer(boolean isOpaque);
-
+
/**
* Creates a new hardware layer.
*
@@ -417,6 +417,15 @@
abstract SurfaceTexture createSurfaceTexture(HardwareLayer layer);
/**
+ * Sets the {@link android.graphics.SurfaceTexture} that will be used to
+ * render into the specified hardware layer.
+ *
+ * @param layer The layer to render into using a {@link android.graphics.SurfaceTexture}
+ * @param surfaceTexture The {@link android.graphics.SurfaceTexture} to use for the layer
+ */
+ abstract void setSurfaceTexture(HardwareLayer layer, SurfaceTexture surfaceTexture);
+
+ /**
* Initializes the hardware renderer for the specified surface and setup the
* renderer for drawing, if needed. This is invoked when the ViewAncestor has
* potentially lost the hardware renderer. The hardware renderer should be
@@ -1345,6 +1354,11 @@
}
@Override
+ void setSurfaceTexture(HardwareLayer layer, SurfaceTexture surfaceTexture) {
+ ((GLES20TextureLayer) layer).setSurfaceTexture(surfaceTexture);
+ }
+
+ @Override
void destroyLayers(View view) {
if (view != null && isEnabled() && checkCurrent() != SURFACE_STATE_ERROR) {
destroyHardwareLayer(view);
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 14cd48f..8fe8e40 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -62,18 +62,9 @@
void setForcedDisplaySize(int longDimen, int shortDimen);
void clearForcedDisplaySize();
- // Is device configured with a hideable status bar or a tablet system bar?
- boolean canStatusBarHide();
+ // Is the device configured to have a full system bar for larger screens?
+ boolean hasSystemNavBar();
- // These can only be called when injecting events to your own window,
- // or by holding the INJECT_EVENTS permission. These methods may block
- // until pending input events are finished being dispatched even when 'sync' is false.
- // Avoid calling these methods on your UI thread or use the 'NoWait' version instead.
- boolean injectKeyEvent(in KeyEvent ev, boolean sync);
- boolean injectPointerEvent(in MotionEvent ev, boolean sync);
- boolean injectTrackballEvent(in MotionEvent ev, boolean sync);
- boolean injectInputEventNoWait(in InputEvent ev);
-
// These can only be called when holding the MANAGE_APP_TOKENS permission.
void pauseKeyDispatching(IBinder token);
void resumeKeyDispatching(IBinder token);
@@ -128,26 +119,6 @@
void setAnimationScale(int which, float scale);
void setAnimationScales(in float[] scales);
- // These require the READ_INPUT_STATE permission.
- int getSwitchState(int sw);
- int getSwitchStateForDevice(int devid, int sw);
- int getScancodeState(int sw);
- int getScancodeStateForDevice(int devid, int sw);
- int getTrackballScancodeState(int sw);
- int getDPadScancodeState(int sw);
- int getKeycodeState(int sw);
- int getKeycodeStateForDevice(int devid, int sw);
- int getTrackballKeycodeState(int sw);
- int getDPadKeycodeState(int sw);
- InputChannel monitorInput(String inputChannelName);
-
- // Report whether the hardware supports the given keys; returns true if successful
- boolean hasKeys(in int[] keycodes, inout boolean[] keyExists);
-
- // Get input device information.
- InputDevice getInputDevice(int deviceId);
- int[] getInputDeviceIds();
-
// For testing
void setInTouchMode(boolean showFocus);
@@ -171,8 +142,10 @@
* @param alwaysSendConfiguration Flag to force a new configuration to
* be evaluated. This can be used when there are other parameters in
* configuration that are changing.
+ * @param forceRelayout If true, the window manager will always do a relayout
+ * of its windows even if the rotation hasn't changed.
*/
- void updateRotation(boolean alwaysSendConfiguration);
+ void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout);
/**
* Retrieve the current screen orientation, constants as per
@@ -218,11 +191,6 @@
void statusBarVisibilityChanged(int visibility);
/**
- * Called by the settings application to temporarily set the pointer speed.
- */
- void setPointerSpeed(int speed);
-
- /**
* Block until the given window has been drawn to the screen.
*/
void waitForWindowDrawn(IBinder token, in IRemoteCallback callback);
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 8115b36..93a0185 100755
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -16,9 +16,9 @@
package android.view;
+import android.hardware.input.InputManager;
import android.os.Parcel;
import android.os.Parcelable;
-import android.os.RemoteException;
import java.util.ArrayList;
import java.util.List;
@@ -26,7 +26,7 @@
/**
* Describes the capabilities of a particular input device.
* <p>
- * Each input device may support multiple classes of input. For example, a multifunction
+ * Each input device may support multiple classes of input. For example, a multi-function
* keyboard may compose the capabilities of a standard keyboard together with a track pad mouse
* or other pointing device.
* </p><p>
@@ -118,7 +118,11 @@
/**
* The input source is a keyboard.
- *
+ *
+ * This source indicates pretty much anything that has buttons. Use
+ * {@link #getKeyboardType()} to determine whether the keyboard has alphabetic keys
+ * and can be used to enter text.
+ *
* @see #SOURCE_CLASS_BUTTON
*/
public static final int SOURCE_KEYBOARD = 0x00000100 | SOURCE_CLASS_BUTTON;
@@ -297,13 +301,7 @@
* @return The input device or null if not found.
*/
public static InputDevice getDevice(int id) {
- IWindowManager wm = Display.getWindowManager();
- try {
- return wm.getInputDevice(id);
- } catch (RemoteException ex) {
- throw new RuntimeException(
- "Could not get input device information from Window Manager.", ex);
- }
+ return InputManager.getInputDevice(id);
}
/**
@@ -311,23 +309,39 @@
* @return The input device ids.
*/
public static int[] getDeviceIds() {
- IWindowManager wm = Display.getWindowManager();
- try {
- return wm.getInputDeviceIds();
- } catch (RemoteException ex) {
- throw new RuntimeException(
- "Could not get input device ids from Window Manager.", ex);
- }
+ return InputManager.getInputDeviceIds();
}
-
+
/**
* Gets the input device id.
+ * <p>
+ * Each input device receives a unique id when it is first configured
+ * by the system. The input device id may change when the system is restarted or if the
+ * input device is disconnected, reconnected or reconfigured at any time.
+ * If you require a stable identifier for a device that persists across
+ * boots and reconfigurations, use {@link #getDescriptor()}.
+ * </p>
+ *
* @return The input device id.
*/
public int getId() {
return mId;
}
-
+
+ /**
+ * Gets the input device descriptor, which is a stable identifier for an input device.
+ * <p>
+ * An input device descriptor uniquely identifies an input device. Its value
+ * is intended to be persistent across system restarts, and should not change even
+ * if the input device is disconnected, reconnected or reconfigured at any time.
+ * </p>
+ *
+ * @return The input device descriptor.
+ */
+ public String getDescriptor() {
+ return "PLACEHOLDER"; // TODO: implement for real
+ }
+
/**
* Gets the name of this input device.
* @return The input device name.
diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java
index 575af3b..b03f086 100644
--- a/core/java/android/view/KeyCharacterMap.java
+++ b/core/java/android/view/KeyCharacterMap.java
@@ -19,7 +19,7 @@
import android.text.method.MetaKeyKeyListener;
import android.util.AndroidRuntimeException;
import android.util.SparseIntArray;
-import android.os.RemoteException;
+import android.hardware.input.InputManager;
import android.util.SparseArray;
import java.lang.Character;
@@ -196,6 +196,14 @@
}
/**
+ * TODO implement this
+ * @hide
+ */
+ public static KeyCharacterMap load(CharSequence contents) {
+ return null;
+ }
+
+ /**
* Gets the Unicode character generated by the specified key and meta
* key state combination.
* <p>
@@ -456,7 +464,8 @@
/**
* Gets the keyboard type.
- * Returns {@link #NUMERIC}, {@link #PREDICTIVE}, {@link #ALPHA} or {@link #FULL}.
+ * Returns {@link #NUMERIC}, {@link #PREDICTIVE}, {@link #ALPHA}, {@link #FULL}
+ * or {@link #SPECIAL_FUNCTION}.
* <p>
* Different keyboard types have different semantics. Refer to the documentation
* associated with the keyboard type constants for details.
@@ -518,10 +527,7 @@
* @return True if at least one attached keyboard supports the specified key code.
*/
public static boolean deviceHasKey(int keyCode) {
- int[] codeArray = new int[1];
- codeArray[0] = keyCode;
- boolean[] ret = deviceHasKeys(codeArray);
- return ret[0];
+ return InputManager.deviceHasKeys(new int[] { keyCode })[0];
}
/**
@@ -535,14 +541,7 @@
* at the same index in the key codes array.
*/
public static boolean[] deviceHasKeys(int[] keyCodes) {
- boolean[] ret = new boolean[keyCodes.length];
- IWindowManager wm = Display.getWindowManager();
- try {
- wm.hasKeys(keyCodes, ret);
- } catch (RemoteException e) {
- // no fallback; just return the empty array
- }
- return ret;
+ return InputManager.deviceHasKeys(keyCodes);
}
/**
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index 83999a1..3cd8b71 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -115,6 +115,7 @@
private final Object[] mLock = new Object[0];
private boolean mUpdateLayer;
+ private boolean mUpdateSurface;
private SurfaceTexture.OnFrameAvailableListener mUpdateListener;
@@ -208,6 +209,8 @@
private void destroySurface() {
if (mLayer != null) {
+ mSurface.detachFromGLContext();
+
boolean shouldRelease = true;
if (mListener != null) {
shouldRelease = mListener.onSurfaceTextureDestroyed(mSurface);
@@ -322,9 +325,13 @@
}
mLayer = mAttachInfo.mHardwareRenderer.createHardwareLayer(mOpaque);
- mSurface = mAttachInfo.mHardwareRenderer.createSurfaceTexture(mLayer);
+ if (!mUpdateSurface) {
+ // We already have a SurfaceTexture to use, and we will pass it
+ // to mLayer below.
+ mSurface = mAttachInfo.mHardwareRenderer.createSurfaceTexture(mLayer);
+ }
nSetDefaultBufferSize(mSurface, getWidth(), getHeight());
- nCreateNativeWindow(mSurface);
+ nCreateNativeWindow(mSurface);
mUpdateListener = new SurfaceTexture.OnFrameAvailableListener() {
@Override
@@ -344,6 +351,15 @@
}
}
+ if (mUpdateSurface) {
+ // Someone has requested that we use a specific SurfaceTexture, so
+ // tell mLayer about it and set the SurfaceTexture to use the
+ // current view size.
+ mUpdateSurface = false;
+ mAttachInfo.mHardwareRenderer.setSurfaceTexture(mLayer, mSurface);
+ nSetDefaultBufferSize(mSurface, getWidth(), getHeight());
+ }
+
applyUpdate();
applyTransformMatrix();
@@ -371,7 +387,7 @@
mUpdateLayer = true;
invalidate();
}
-
+
private void applyUpdate() {
if (mLayer == null) {
return;
@@ -636,6 +652,32 @@
}
/**
+ * Set the {@link SurfaceTexture} for this view to use. If a {@link
+ * SurfaceTexture} is already being used by this view, it is immediately
+ * released and not be usable any more. The {@link
+ * SurfaceTextureListener#onSurfaceTextureDestroyed} callback is <b>not</b>
+ * called.
+ *
+ * The {@link SurfaceTexture} object must be detached from all OpenGL ES
+ * contexts prior to calling this method.
+ *
+ * @param surfaceTexture The {@link SurfaceTexture} that the view should use.
+ * @see SurfaceTexture#detachFromGLContext()
+ * @hide
+ */
+ public void setSurfaceTexture(SurfaceTexture surfaceTexture) {
+ if (surfaceTexture == null) {
+ throw new NullPointerException("surfaceTexture must not be null");
+ }
+ if (mSurface != null) {
+ mSurface.release();
+ }
+ mSurface = surfaceTexture;
+ mUpdateSurface = true;
+ invalidateParentIfNeeded();
+ }
+
+ /**
* Returns the {@link SurfaceTextureListener} currently associated with this
* texture view.
*
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 4b35c72..d62e32f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4032,8 +4032,9 @@
* <p>
* <strong>Note:</strong> When a View clears focus the framework is trying
* to give focus to the first focusable View from the top. Hence, if this
- * View is the first from the top that can take focus, then its focus will
- * not be cleared nor will the focus change callback be invoked.
+ * View is the first from the top that can take focus, then all callbacks
+ * related to clearing focus will be invoked after wich the framework will
+ * give focus to this view.
* </p>
*/
public void clearFocus() {
@@ -4050,25 +4051,15 @@
onFocusChanged(false, 0, null);
refreshDrawableState();
+
+ ensureInputFocusOnFirstFocusable();
}
}
- /**
- * Called to clear the focus of a view that is about to be removed.
- * Doesn't call clearChildFocus, which prevents this view from taking
- * focus again before it has been removed from the parent
- */
- void clearFocusForRemoval() {
- if ((mPrivateFlags & FOCUSED) != 0) {
- mPrivateFlags &= ~FOCUSED;
-
- onFocusChanged(false, 0, null);
- refreshDrawableState();
-
- // The view cleared focus and invoked the callbacks, so now is the
- // time to give focus to the the first focusable from the top to
- // ensure that the gain focus is announced after clear focus.
- getRootView().requestFocus(FOCUS_FORWARD);
+ void ensureInputFocusOnFirstFocusable() {
+ View root = getRootView();
+ if (root != null) {
+ root.requestFocus(FOCUS_FORWARD);
}
}
@@ -14423,9 +14414,48 @@
}
/**
- * Request that the visibility of the status bar be changed.
- * @param visibility Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE} or
- * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.
+ * Request that the visibility of the status bar or other screen/window
+ * decorations be changed.
+ *
+ * <p>This method is used to put the over device UI into temporary modes
+ * where the user's attention is focused more on the application content,
+ * by dimming or hiding surrounding system affordances. This is typically
+ * used in conjunction with {@link Window#FEATURE_ACTION_BAR_OVERLAY
+ * Window.FEATURE_ACTION_BAR_OVERLAY}, allowing the applications content
+ * to be placed behind the action bar (and with these flags other system
+ * affordances) so that smooth transitions between hiding and showing them
+ * can be done.
+ *
+ * <p>Two representative examples of the use of system UI visibility is
+ * implementing a content browsing application (like a magazine reader)
+ * and a video playing application.
+ *
+ * <p>The first code shows a typical implementation of a View in a content
+ * browsing application. In this implementation, the application goes
+ * into a content-oriented mode by hiding the status bar and action bar,
+ * and putting the navigation elements into lights out mode. The user can
+ * then interact with content while in this mode. Such an application should
+ * provide an easy way for the user to toggle out of the mode (such as to
+ * check information in the status bar or access notifications). In the
+ * implementation here, this is done simply by tapping on the content.
+ *
+ * {@sample development/samples/ApiDemos/src/com/example/android/apis/view/ContentBrowserActivity.java
+ * content}
+ *
+ * <p>This second code sample shows a typical implementation of a View
+ * in a video playing application. In this situation, while the video is
+ * playing the application would like to go into a complete full-screen mode,
+ * to use as much of the display as possible for the video. When in this state
+ * the user can not interact with the application; the system intercepts
+ * touching on the screen to pop the UI out of full screen mode.
+ *
+ * {@sample development/samples/ApiDemos/src/com/example/android/apis/view/VideoPlayerActivity.java
+ * content}
+ *
+ * @param visibility Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
+ * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, {@link #SYSTEM_UI_FLAG_FULLSCREEN},
+ * {@link #SYSTEM_UI_FLAG_LAYOUT_STABLE}, {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION},
+ * and {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}.
*/
public void setSystemUiVisibility(int visibility) {
if (visibility != mSystemUiVisibility) {
@@ -14437,9 +14467,11 @@
}
/**
- * Returns the status bar visibility that this view has requested.
- * @return Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE} or
- * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.
+ * Returns the last {@link #setSystemUiVisibility(int) that this view has requested.
+ * @return Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
+ * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, {@link #SYSTEM_UI_FLAG_FULLSCREEN},
+ * {@link #SYSTEM_UI_FLAG_LAYOUT_STABLE}, {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION},
+ * and {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}.
*/
public int getSystemUiVisibility() {
return mSystemUiVisibility;
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index b9924c7..9d06145 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -315,7 +315,7 @@
if (!sHasPermanentMenuKeySet) {
IWindowManager wm = Display.getWindowManager();
try {
- sHasPermanentMenuKey = wm.canStatusBarHide() && !wm.hasNavigationBar();
+ sHasPermanentMenuKey = !wm.hasSystemNavBar() && !wm.hasNavigationBar();
sHasPermanentMenuKeySet = true;
} catch (RemoteException ex) {
sHasPermanentMenuKey = false;
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index ae5debe..121b544 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3375,7 +3375,7 @@
boolean clearChildFocus = false;
if (view == mFocused) {
- view.clearFocusForRemoval();
+ view.unFocus();
clearChildFocus = true;
}
@@ -3398,6 +3398,7 @@
if (clearChildFocus) {
clearChildFocus(view);
+ ensureInputFocusOnFirstFocusable();
}
}
@@ -3450,7 +3451,7 @@
}
if (view == focused) {
- view.clearFocusForRemoval();
+ view.unFocus();
clearChildFocus = view;
}
@@ -3474,6 +3475,7 @@
if (clearChildFocus != null) {
clearChildFocus(clearChildFocus);
+ ensureInputFocusOnFirstFocusable();
}
}
@@ -3519,7 +3521,7 @@
}
if (view == focused) {
- view.clearFocusForRemoval();
+ view.unFocus();
clearChildFocus = view;
}
@@ -3542,6 +3544,7 @@
if (clearChildFocus != null) {
clearChildFocus(clearChildFocus);
+ ensureInputFocusOnFirstFocusable();
}
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index d72f3b7..899fb32 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2039,9 +2039,10 @@
scrollToRectOrFocus(null, false);
- if (mAttachInfo.mViewScrollChanged) {
- mAttachInfo.mViewScrollChanged = false;
- mAttachInfo.mTreeObserver.dispatchOnScrollChanged();
+ final AttachInfo attachInfo = mAttachInfo;
+ if (attachInfo.mViewScrollChanged) {
+ attachInfo.mViewScrollChanged = false;
+ attachInfo.mTreeObserver.dispatchOnScrollChanged();
}
int yoff;
@@ -2056,8 +2057,8 @@
fullRedrawNeeded = true;
}
- final float appScale = mAttachInfo.mApplicationScale;
- final boolean scalingRequired = mAttachInfo.mScalingRequired;
+ final float appScale = attachInfo.mApplicationScale;
+ final boolean scalingRequired = attachInfo.mScalingRequired;
int resizeAlpha = 0;
if (mResizeBuffer != null) {
@@ -2086,7 +2087,7 @@
}
if (fullRedrawNeeded) {
- mAttachInfo.mIgnoreDirtyState = true;
+ attachInfo.mIgnoreDirtyState = true;
dirty.set(0, 0, (int) (mWidth * appScale + 0.5f), (int) (mHeight * appScale + 0.5f));
}
@@ -2099,8 +2100,10 @@
appScale + ", width=" + mWidth + ", height=" + mHeight);
}
+ attachInfo.mTreeObserver.dispatchOnDraw();
+
if (!dirty.isEmpty() || mIsAnimating) {
- if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {
+ if (attachInfo.mHardwareRenderer != null && attachInfo.mHardwareRenderer.isEnabled()) {
// Draw with hardware renderer.
mIsAnimating = false;
mHardwareYOffset = yoff;
@@ -2111,147 +2114,12 @@
mPreviousDirty.set(dirty);
dirty.setEmpty();
- if (mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this,
+ if (attachInfo.mHardwareRenderer.draw(mView, attachInfo, this,
animating ? null : mCurrentDirty)) {
mPreviousDirty.set(0, 0, mWidth, mHeight);
}
- } else {
- // Draw with software renderer.
- Canvas canvas;
- try {
- int left = dirty.left;
- int top = dirty.top;
- int right = dirty.right;
- int bottom = dirty.bottom;
-
- final long lockCanvasStartTime;
- if (ViewDebug.DEBUG_LATENCY) {
- lockCanvasStartTime = System.nanoTime();
- }
-
- canvas = mSurface.lockCanvas(dirty);
-
- if (ViewDebug.DEBUG_LATENCY) {
- long now = System.nanoTime();
- Log.d(ViewDebug.DEBUG_LATENCY_TAG, "- lockCanvas() took "
- + ((now - lockCanvasStartTime) * 0.000001f) + "ms");
- }
-
- if (left != dirty.left || top != dirty.top || right != dirty.right ||
- bottom != dirty.bottom) {
- mAttachInfo.mIgnoreDirtyState = true;
- }
-
- // TODO: Do this in native
- canvas.setDensity(mDensity);
- } catch (Surface.OutOfResourcesException e) {
- Log.e(TAG, "OutOfResourcesException locking surface", e);
- try {
- if (!sWindowSession.outOfMemory(mWindow)) {
- Slog.w(TAG, "No processes killed for memory; killing self");
- Process.killProcess(Process.myPid());
- }
- } catch (RemoteException ex) {
- }
- mLayoutRequested = true; // ask wm for a new surface next time.
- return;
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "IllegalArgumentException locking surface", e);
- // Don't assume this is due to out of memory, it could be
- // something else, and if it is something else then we could
- // kill stuff (or ourself) for no reason.
- mLayoutRequested = true; // ask wm for a new surface next time.
- return;
- }
-
- try {
- if (DEBUG_ORIENTATION || DEBUG_DRAW) {
- Log.v(TAG, "Surface " + surface + " drawing to bitmap w="
- + canvas.getWidth() + ", h=" + canvas.getHeight());
- //canvas.drawARGB(255, 255, 0, 0);
- }
-
- long startTime = 0L;
- if (ViewDebug.DEBUG_PROFILE_DRAWING) {
- startTime = SystemClock.elapsedRealtime();
- }
-
- // If this bitmap's format includes an alpha channel, we
- // need to clear it before drawing so that the child will
- // properly re-composite its drawing on a transparent
- // background. This automatically respects the clip/dirty region
- // or
- // If we are applying an offset, we need to clear the area
- // where the offset doesn't appear to avoid having garbage
- // left in the blank areas.
- if (!canvas.isOpaque() || yoff != 0) {
- canvas.drawColor(0, PorterDuff.Mode.CLEAR);
- }
-
- dirty.setEmpty();
- mIsAnimating = false;
- mAttachInfo.mDrawingTime = SystemClock.uptimeMillis();
- mView.mPrivateFlags |= View.DRAWN;
-
- if (DEBUG_DRAW) {
- Context cxt = mView.getContext();
- Log.i(TAG, "Drawing: package:" + cxt.getPackageName() +
- ", metrics=" + cxt.getResources().getDisplayMetrics() +
- ", compatibilityInfo=" + cxt.getResources().getCompatibilityInfo());
- }
- try {
- canvas.translate(0, -yoff);
- if (mTranslator != null) {
- mTranslator.translateCanvas(canvas);
- }
- canvas.setScreenDensity(scalingRequired
- ? DisplayMetrics.DENSITY_DEVICE : 0);
- mAttachInfo.mSetIgnoreDirtyState = false;
-
- final long drawStartTime;
- if (ViewDebug.DEBUG_LATENCY) {
- drawStartTime = System.nanoTime();
- }
-
- mView.draw(canvas);
-
- if (ViewDebug.DEBUG_LATENCY) {
- long now = System.nanoTime();
- Log.d(ViewDebug.DEBUG_LATENCY_TAG, "- draw() took "
- + ((now - drawStartTime) * 0.000001f) + "ms");
- }
- } finally {
- if (!mAttachInfo.mSetIgnoreDirtyState) {
- // Only clear the flag if it was not set during the mView.draw() call
- mAttachInfo.mIgnoreDirtyState = false;
- }
- }
-
- if (false && ViewDebug.consistencyCheckEnabled) {
- mView.dispatchConsistencyCheck(ViewDebug.CONSISTENCY_DRAWING);
- }
-
- if (ViewDebug.DEBUG_PROFILE_DRAWING) {
- EventLog.writeEvent(60000, SystemClock.elapsedRealtime() - startTime);
- }
- } finally {
- final long unlockCanvasAndPostStartTime;
- if (ViewDebug.DEBUG_LATENCY) {
- unlockCanvasAndPostStartTime = System.nanoTime();
- }
-
- surface.unlockCanvasAndPost(canvas);
-
- if (ViewDebug.DEBUG_LATENCY) {
- long now = System.nanoTime();
- Log.d(ViewDebug.DEBUG_LATENCY_TAG, "- unlockCanvasAndPost() took "
- + ((now - unlockCanvasAndPostStartTime) * 0.000001f) + "ms");
- }
-
- if (LOCAL_LOGV) {
- Log.v(TAG, "Surface " + surface + " unlockCanvasAndPost");
- }
- }
+ } else if (!drawSoftware(surface, attachInfo, yoff, scalingRequired, dirty)) {
+ return;
}
}
@@ -2261,6 +2129,151 @@
}
}
+ /**
+ * @return true if drawing was succesfull, false if an error occurred
+ */
+ private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int yoff,
+ boolean scalingRequired, Rect dirty) {
+
+ // Draw with software renderer.
+ Canvas canvas;
+ try {
+ int left = dirty.left;
+ int top = dirty.top;
+ int right = dirty.right;
+ int bottom = dirty.bottom;
+
+ final long lockCanvasStartTime;
+ if (ViewDebug.DEBUG_LATENCY) {
+ lockCanvasStartTime = System.nanoTime();
+ }
+
+ canvas = mSurface.lockCanvas(dirty);
+
+ if (ViewDebug.DEBUG_LATENCY) {
+ long now = System.nanoTime();
+ Log.d(ViewDebug.DEBUG_LATENCY_TAG, "- lockCanvas() took "
+ + ((now - lockCanvasStartTime) * 0.000001f) + "ms");
+ }
+
+ if (left != dirty.left || top != dirty.top || right != dirty.right ||
+ bottom != dirty.bottom) {
+ attachInfo.mIgnoreDirtyState = true;
+ }
+
+ // TODO: Do this in native
+ canvas.setDensity(mDensity);
+ } catch (Surface.OutOfResourcesException e) {
+ Log.e(TAG, "OutOfResourcesException locking surface", e);
+ try {
+ if (!sWindowSession.outOfMemory(mWindow)) {
+ Slog.w(TAG, "No processes killed for memory; killing self");
+ Process.killProcess(Process.myPid());
+ }
+ } catch (RemoteException ex) {
+ }
+ mLayoutRequested = true; // ask wm for a new surface next time.
+ return false;
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "IllegalArgumentException locking surface", e);
+ // Don't assume this is due to out of memory, it could be
+ // something else, and if it is something else then we could
+ // kill stuff (or ourself) for no reason.
+ mLayoutRequested = true; // ask wm for a new surface next time.
+ return false;
+ }
+
+ try {
+ if (DEBUG_ORIENTATION || DEBUG_DRAW) {
+ Log.v(TAG, "Surface " + surface + " drawing to bitmap w="
+ + canvas.getWidth() + ", h=" + canvas.getHeight());
+ //canvas.drawARGB(255, 255, 0, 0);
+ }
+
+ long startTime = 0L;
+ if (ViewDebug.DEBUG_PROFILE_DRAWING) {
+ startTime = SystemClock.elapsedRealtime();
+ }
+
+ // If this bitmap's format includes an alpha channel, we
+ // need to clear it before drawing so that the child will
+ // properly re-composite its drawing on a transparent
+ // background. This automatically respects the clip/dirty region
+ // or
+ // If we are applying an offset, we need to clear the area
+ // where the offset doesn't appear to avoid having garbage
+ // left in the blank areas.
+ if (!canvas.isOpaque() || yoff != 0) {
+ canvas.drawColor(0, PorterDuff.Mode.CLEAR);
+ }
+
+ dirty.setEmpty();
+ mIsAnimating = false;
+ attachInfo.mDrawingTime = SystemClock.uptimeMillis();
+ mView.mPrivateFlags |= View.DRAWN;
+
+ if (DEBUG_DRAW) {
+ Context cxt = mView.getContext();
+ Log.i(TAG, "Drawing: package:" + cxt.getPackageName() +
+ ", metrics=" + cxt.getResources().getDisplayMetrics() +
+ ", compatibilityInfo=" + cxt.getResources().getCompatibilityInfo());
+ }
+ try {
+ canvas.translate(0, -yoff);
+ if (mTranslator != null) {
+ mTranslator.translateCanvas(canvas);
+ }
+ canvas.setScreenDensity(scalingRequired
+ ? DisplayMetrics.DENSITY_DEVICE : 0);
+ attachInfo.mSetIgnoreDirtyState = false;
+
+ final long drawStartTime;
+ if (ViewDebug.DEBUG_LATENCY) {
+ drawStartTime = System.nanoTime();
+ }
+
+ mView.draw(canvas);
+
+ if (ViewDebug.DEBUG_LATENCY) {
+ long now = System.nanoTime();
+ Log.d(ViewDebug.DEBUG_LATENCY_TAG, "- draw() took "
+ + ((now - drawStartTime) * 0.000001f) + "ms");
+ }
+ } finally {
+ if (!attachInfo.mSetIgnoreDirtyState) {
+ // Only clear the flag if it was not set during the mView.draw() call
+ attachInfo.mIgnoreDirtyState = false;
+ }
+ }
+
+ if (false && ViewDebug.consistencyCheckEnabled) {
+ mView.dispatchConsistencyCheck(ViewDebug.CONSISTENCY_DRAWING);
+ }
+
+ if (ViewDebug.DEBUG_PROFILE_DRAWING) {
+ EventLog.writeEvent(60000, SystemClock.elapsedRealtime() - startTime);
+ }
+ } finally {
+ final long unlockCanvasAndPostStartTime;
+ if (ViewDebug.DEBUG_LATENCY) {
+ unlockCanvasAndPostStartTime = System.nanoTime();
+ }
+
+ surface.unlockCanvasAndPost(canvas);
+
+ if (ViewDebug.DEBUG_LATENCY) {
+ long now = System.nanoTime();
+ Log.d(ViewDebug.DEBUG_LATENCY_TAG, "- unlockCanvasAndPost() took "
+ + ((now - unlockCanvasAndPostStartTime) * 0.000001f) + "ms");
+ }
+
+ if (LOCAL_LOGV) {
+ Log.v(TAG, "Surface " + surface + " unlockCanvasAndPost");
+ }
+ }
+ return true;
+ }
+
void invalidateDisplayLists() {
final ArrayList<DisplayList> displayLists = mDisplayLists;
final int count = displayLists.size();
@@ -3830,30 +3843,33 @@
if (LOCAL_LOGV) Log.v(TAG, "DIE in " + this + " of " + mSurface);
synchronized (this) {
if (mAdded) {
- mAdded = false;
dispatchDetachedFromWindow();
}
if (mAdded && !mFirst) {
destroyHardwareRenderer();
- int viewVisibility = mView.getVisibility();
- boolean viewVisibilityChanged = mViewVisibility != viewVisibility;
- if (mWindowAttributesChanged || viewVisibilityChanged) {
- // If layout params have been changed, first give them
- // to the window manager to make sure it has the correct
- // animation info.
- try {
- if ((relayoutWindow(mWindowAttributes, viewVisibility, false)
- & WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0) {
- sWindowSession.finishDrawing(mWindow);
+ if (mView != null) {
+ int viewVisibility = mView.getVisibility();
+ boolean viewVisibilityChanged = mViewVisibility != viewVisibility;
+ if (mWindowAttributesChanged || viewVisibilityChanged) {
+ // If layout params have been changed, first give them
+ // to the window manager to make sure it has the correct
+ // animation info.
+ try {
+ if ((relayoutWindow(mWindowAttributes, viewVisibility, false)
+ & WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0) {
+ sWindowSession.finishDrawing(mWindow);
+ }
+ } catch (RemoteException e) {
}
- } catch (RemoteException e) {
}
+
+ mSurface.release();
}
-
- mSurface.release();
}
+
+ mAdded = false;
}
}
diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java
index 7fd3389..1c5d436 100644
--- a/core/java/android/view/ViewTreeObserver.java
+++ b/core/java/android/view/ViewTreeObserver.java
@@ -38,6 +38,7 @@
private CopyOnWriteArrayList<OnComputeInternalInsetsListener> mOnComputeInternalInsetsListeners;
private CopyOnWriteArrayList<OnScrollChangedListener> mOnScrollChangedListeners;
private ArrayList<OnPreDrawListener> mOnPreDrawListeners;
+ private ArrayList<OnDrawListener> mOnDrawListeners;
private boolean mAlive = true;
@@ -90,6 +91,27 @@
}
/**
+ * Interface definition for a callback to be invoked when the view tree is about to be drawn.
+ */
+ public interface OnDrawListener {
+ /**
+ * <p>Callback method to be invoked when the view tree is about to be drawn. At this point,
+ * views cannot be modified in any way.</p>
+ *
+ * <p>Unlike with {@link OnPreDrawListener}, this method cannot be used to cancel the
+ * current drawing pass.</p>
+ *
+ * <p>An {@link OnDrawListener} listener <strong>cannot be added or removed</strong>
+ * from this method.</p>
+ *
+ * @see android.view.View#onMeasure
+ * @see android.view.View#onLayout
+ * @see android.view.View#onDraw
+ */
+ public void onDraw();
+ }
+
+ /**
* Interface definition for a callback to be invoked when the touch mode changes.
*/
public interface OnTouchModeChangeListener {
@@ -171,11 +193,7 @@
public void setTouchableInsets(int val) {
mTouchableInsets = val;
}
-
- public int getTouchableInsets() {
- return mTouchableInsets;
- }
-
+
int mTouchableInsets;
void reset() {
@@ -184,29 +202,28 @@
touchableRegion.setEmpty();
mTouchableInsets = TOUCHABLE_INSETS_FRAME;
}
-
+
+ @Override
+ public int hashCode() {
+ int result = contentInsets != null ? contentInsets.hashCode() : 0;
+ result = 31 * result + (visibleInsets != null ? visibleInsets.hashCode() : 0);
+ result = 31 * result + (touchableRegion != null ? touchableRegion.hashCode() : 0);
+ result = 31 * result + mTouchableInsets;
+ return result;
+ }
+
@Override
public boolean equals(Object o) {
- try {
- if (o == null) {
- return false;
- }
- InternalInsetsInfo other = (InternalInsetsInfo)o;
- if (mTouchableInsets != other.mTouchableInsets) {
- return false;
- }
- if (!contentInsets.equals(other.contentInsets)) {
- return false;
- }
- if (!visibleInsets.equals(other.visibleInsets)) {
- return false;
- }
- return touchableRegion.equals(other.touchableRegion);
- } catch (ClassCastException e) {
- return false;
- }
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ InternalInsetsInfo other = (InternalInsetsInfo)o;
+ return mTouchableInsets == other.mTouchableInsets &&
+ contentInsets.equals(other.contentInsets) &&
+ visibleInsets.equals(other.visibleInsets) &&
+ touchableRegion.equals(other.touchableRegion);
}
-
+
void set(InternalInsetsInfo other) {
contentInsets.set(other.contentInsets);
visibleInsets.set(other.visibleInsets);
@@ -420,6 +437,44 @@
}
/**
+ * <p>Register a callback to be invoked when the view tree is about to be drawn.</p>
+ * <p><strong>Note:</strong> this method <strong>cannot</strong> be invoked from
+ * {@link android.view.ViewTreeObserver.OnDrawListener#onDraw()}.</p>
+ *
+ * @param listener The callback to add
+ *
+ * @throws IllegalStateException If {@link #isAlive()} returns false
+ */
+ public void addOnDrawListener(OnDrawListener listener) {
+ checkIsAlive();
+
+ if (mOnDrawListeners == null) {
+ mOnDrawListeners = new ArrayList<OnDrawListener>();
+ }
+
+ mOnDrawListeners.add(listener);
+ }
+
+ /**
+ * <p>Remove a previously installed pre-draw callback.</p>
+ * <p><strong>Note:</strong> this method <strong>cannot</strong> be invoked from
+ * {@link android.view.ViewTreeObserver.OnDrawListener#onDraw()}.</p>
+ *
+ * @param victim The callback to remove
+ *
+ * @throws IllegalStateException If {@link #isAlive()} returns false
+ *
+ * @see #addOnDrawListener(OnDrawListener)
+ */
+ public void removeOnDrawListener(OnDrawListener victim) {
+ checkIsAlive();
+ if (mOnDrawListeners == null) {
+ return;
+ }
+ mOnDrawListeners.remove(victim);
+ }
+
+ /**
* Register a callback to be invoked when a view has been scrolled.
*
* @param listener The callback to add
@@ -601,6 +656,7 @@
*
* @return True if the current draw should be canceled and resceduled, false otherwise.
*/
+ @SuppressWarnings("unchecked")
public final boolean dispatchOnPreDraw() {
// NOTE: we *must* clone the listener list to perform the dispatching.
// The clone is a safe guard against listeners that
@@ -619,6 +675,19 @@
}
/**
+ * Notifies registered listeners that the drawing pass is about to start.
+ */
+ public final void dispatchOnDraw() {
+ if (mOnDrawListeners != null) {
+ final ArrayList<OnDrawListener> listeners = mOnDrawListeners;
+ int numListeners = listeners.size();
+ for (int i = 0; i < numListeners; ++i) {
+ listeners.get(i).onDraw();
+ }
+ }
+ }
+
+ /**
* Notifies registered listeners that the touch mode has changed.
*
* @param inTouchMode True if the touch mode is now enabled, false otherwise.
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 75267bb..491cd67 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -326,6 +326,11 @@
* Returns true if {@link #hideLw} was last called for the window.
*/
public boolean showLw(boolean doAnimation);
+
+ /**
+ * Check whether the process hosting this window is currently alive.
+ */
+ public boolean isAlive();
}
/**
@@ -344,6 +349,10 @@
* between it and the policy.
*/
public interface WindowManagerFuncs {
+ public static final int LID_ABSENT = -1;
+ public static final int LID_CLOSED = 0;
+ public static final int LID_OPEN = 1;
+
/**
* Ask the window manager to re-evaluate the system UI flags.
*/
@@ -357,6 +366,16 @@
InputEventReceiver.Factory inputEventReceiverFactory,
String name, int windowType, int layoutParamsFlags, boolean canReceiveKeys,
boolean hasFocus, boolean touchFullscreen);
+
+ /**
+ * Returns a code that describes the current state of the lid switch.
+ */
+ public int getLidState();
+
+ /**
+ * Creates an input channel that will receive all input from the input dispatcher.
+ */
+ public InputChannel monitorInput(String name);
}
/**
@@ -447,7 +466,7 @@
* Called by window manager once it has the initial, default native
* display dimensions.
*/
- public void setInitialDisplaySize(int width, int height);
+ public void setInitialDisplaySize(Display display, int width, int height);
/**
* Check permissions when adding a window.
@@ -514,10 +533,10 @@
public int getMaxWallpaperLayer();
/**
- * Return true if the policy allows the status bar to hide. Otherwise,
- * it is a tablet-style system bar.
+ * Return true if the policy desires a full unified system nav bar. Otherwise,
+ * it is a phone-style status bar with optional nav bar.
*/
- public boolean canStatusBarHide();
+ public boolean hasSystemNavBar();
/**
* Return the display width available after excluding any screen
@@ -938,10 +957,10 @@
public void setRotationLw(int rotation);
/**
- * Called when the system is mostly done booting to determine whether
+ * Called when the system is mostly done booting to set whether
* the system should go into safe mode.
*/
- public boolean detectSafeMode();
+ public void setSafeMode(boolean safeMode);
/**
* Called when the system is mostly done booting.
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 17dbde8..067be39 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -405,7 +405,9 @@
}
// Check focus again in case that "onWindowFocus" is called before
// handling this message.
- checkFocus(mHasBeenInactive);
+ if (mServedView != null && mServedView.hasWindowFocus()) {
+ checkFocus(mHasBeenInactive);
+ }
}
}
return;
@@ -1202,7 +1204,9 @@
}
if (DEBUG) Log.v(TAG, "checkFocus: view=" + mServedView
+ " next=" + mNextServedView
- + " forceNewFocus=" + forceNewFocus);
+ + " forceNewFocus=" + forceNewFocus
+ + " package="
+ + (mServedView != null ? mServedView.getContext().getPackageName() : "<none>"));
if (mNextServedView == null) {
finishInputLocked();
diff --git a/core/java/android/view/textservice/SpellCheckerInfo.java b/core/java/android/view/textservice/SpellCheckerInfo.java
index 137743a..d05c1af 100644
--- a/core/java/android/view/textservice/SpellCheckerInfo.java
+++ b/core/java/android/view/textservice/SpellCheckerInfo.java
@@ -45,6 +45,7 @@
private final ResolveInfo mService;
private final String mId;
private final int mLabel;
+ private final boolean mSupportsSentenceSpellCheck;
/**
* The spell checker setting activity's name, used by the system settings to
@@ -97,6 +98,9 @@
label = sa.getResourceId(com.android.internal.R.styleable.SpellChecker_label, 0);
settingsActivityComponent = sa.getString(
com.android.internal.R.styleable.SpellChecker_settingsActivity);
+ mSupportsSentenceSpellCheck = sa.getBoolean(
+ com.android.internal.R.styleable.SpellChecker_supportsSentenceSpellCheck,
+ false);
sa.recycle();
final int depth = parser.getDepth();
@@ -138,6 +142,7 @@
*/
public SpellCheckerInfo(Parcel source) {
mLabel = source.readInt();
+ mSupportsSentenceSpellCheck = source.readInt() != 0;
mId = source.readString();
mSettingsActivityName = source.readString();
mService = ResolveInfo.CREATOR.createFromParcel(source);
@@ -152,6 +157,12 @@
return mId;
}
+ /**
+ * @hide
+ */
+ public boolean isSentenceSpellCheckSupported() {
+ return mSupportsSentenceSpellCheck;
+ }
/**
* Return the component of the service that implements.
@@ -177,6 +188,7 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mLabel);
+ dest.writeInt(mSupportsSentenceSpellCheck ? 1 : 0);
dest.writeString(mId);
dest.writeString(mSettingsActivityName);
mService.writeToParcel(dest, flags);
diff --git a/core/java/android/view/textservice/SpellCheckerSession.java b/core/java/android/view/textservice/SpellCheckerSession.java
index 35940ba..9dc05e4 100644
--- a/core/java/android/view/textservice/SpellCheckerSession.java
+++ b/core/java/android/view/textservice/SpellCheckerSession.java
@@ -436,15 +436,15 @@
*/
public interface SpellCheckerSessionListener {
/**
- * Callback for {@link SpellCheckerSession#getSuggestions(TextInfo[], int, boolean)}
+ * Callback for {@link SpellCheckerSession#getSuggestions(TextInfo, int)}
+ * and {@link SpellCheckerSession#getSuggestions(TextInfo[], int, boolean)}
* @param results an array of {@link SuggestionsInfo}s.
* These results are suggestions for {@link TextInfo}s queried by
- * {@link SpellCheckerSession#getSuggestions(TextInfo[], int, boolean)}.
+ * {@link SpellCheckerSession#getSuggestions(TextInfo, int)} or
+ * {@link SpellCheckerSession#getSuggestions(TextInfo[], int, boolean)}
*/
public void onGetSuggestions(SuggestionsInfo[] results);
- // TODO: Remove @hide as soon as the sample spell checker client gets fixed.
/**
- * @hide
* Callback for {@link SpellCheckerSession#getSentenceSuggestions(TextInfo[], int)}
* @param results an array of {@link SentenceSuggestionsInfo}s.
* These results are suggestions for {@link TextInfo}s
@@ -494,7 +494,7 @@
}
/**
- * @hide
+ * @return true if the spell checker supports sentence level spell checking APIs
*/
public boolean isSentenceSpellCheckSupported() {
return mSubtype.containsExtraValueKey(SUPPORT_SENTENCE_SPELL_CHECK);
diff --git a/core/java/android/webkit/WebSettingsClassic.java b/core/java/android/webkit/WebSettingsClassic.java
index 94b46fc..aa3d8d3 100644
--- a/core/java/android/webkit/WebSettingsClassic.java
+++ b/core/java/android/webkit/WebSettingsClassic.java
@@ -33,7 +33,7 @@
*/
public class WebSettingsClassic extends WebSettings {
// TODO: Keep this up to date
- private static final String PREVIOUS_VERSION = "4.0.3";
+ private static final String PREVIOUS_VERSION = "4.0.4";
// WebView associated with this WebSettings.
private WebViewClassic mWebView;
diff --git a/core/java/android/widget/Chronometer.java b/core/java/android/widget/Chronometer.java
index 0370049..9c9eb4b 100644
--- a/core/java/android/widget/Chronometer.java
+++ b/core/java/android/widget/Chronometer.java
@@ -25,6 +25,7 @@
import android.text.format.DateUtils;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.Slog;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.RemoteViews.RemoteView;
@@ -247,6 +248,7 @@
}
}
setText(text);
+ Slog.v("Chronometer", "updateText: sec=" + seconds + " mFormat=" + mFormat + " text=" + text);
}
private void updateRunning() {
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 3115eff..f1dffa1 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -85,6 +85,8 @@
private TabImpl mSelectedTab;
private int mSavedTabPosition = INVALID_POSITION;
+ private boolean mDisplayHomeAsUpSet;
+
ActionModeImpl mActionMode;
ActionMode mDeferredDestroyActionMode;
ActionMode.Callback mDeferredModeDestroyCallback;
@@ -375,11 +377,17 @@
}
public void setDisplayOptions(int options) {
+ if ((options & DISPLAY_HOME_AS_UP) != 0) {
+ mDisplayHomeAsUpSet = true;
+ }
mActionView.setDisplayOptions(options);
}
public void setDisplayOptions(int options, int mask) {
final int current = mActionView.getDisplayOptions();
+ if ((mask & DISPLAY_HOME_AS_UP) != 0) {
+ mDisplayHomeAsUpSet = true;
+ }
mActionView.setDisplayOptions((options & mask) | (current & ~mask));
}
@@ -1072,4 +1080,10 @@
public void setLogo(Drawable logo) {
mActionView.setLogo(logo);
}
+
+ public void setDefaultDisplayHomeAsUpEnabled(boolean enable) {
+ if (!mDisplayHomeAsUpSet) {
+ setDisplayHomeAsUpEnabled(enable);
+ }
+ }
}
diff --git a/core/java/com/android/internal/net/NetworkStatsFactory.java b/core/java/com/android/internal/net/NetworkStatsFactory.java
index ccd2763..d59585f 100644
--- a/core/java/com/android/internal/net/NetworkStatsFactory.java
+++ b/core/java/com/android/internal/net/NetworkStatsFactory.java
@@ -16,7 +16,7 @@
package com.android.internal.net;
-import static android.net.NetworkStats.SET_DEFAULT;
+import static android.net.NetworkStats.SET_ALL;
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
import static com.android.server.NetworkManagementSocketTagger.kernelToTag;
@@ -101,7 +101,7 @@
while (reader.hasMoreData()) {
entry.iface = reader.nextString();
entry.uid = UID_ALL;
- entry.set = SET_DEFAULT;
+ entry.set = SET_ALL;
entry.tag = TAG_NONE;
final boolean active = reader.nextInt() != 0;
@@ -165,7 +165,7 @@
entry.iface = iface;
entry.uid = UID_ALL;
- entry.set = SET_DEFAULT;
+ entry.set = SET_ALL;
entry.tag = TAG_NONE;
entry.rxBytes = readSingleLongFromFile(new File(ifacePath, "rx_bytes"));
entry.rxPackets = readSingleLongFromFile(new File(ifacePath, "rx_packets"));
@@ -193,7 +193,7 @@
try {
entry.iface = values.get(0);
entry.uid = UID_ALL;
- entry.set = SET_DEFAULT;
+ entry.set = SET_ALL;
entry.tag = TAG_NONE;
entry.rxBytes = Long.parseLong(values.get(1));
entry.rxPackets = Long.parseLong(values.get(2));
diff --git a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
index 8521481..d1652df 100644
--- a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
+++ b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
@@ -18,14 +18,11 @@
import com.android.internal.app.ActionBarImpl;
-import android.animation.LayoutTransition;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.View;
-import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
/**
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
new file mode 100644
index 0000000..c72c770
--- /dev/null
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+/** {@hide} */
+interface ILockSettings {
+ void setBoolean(in String key, in boolean value, in int userId);
+ void setLong(in String key, in long value, in int userId);
+ void setString(in String key, in String value, in int userId);
+ boolean getBoolean(in String key, in boolean defaultValue, in int userId);
+ long getLong(in String key, in long defaultValue, in int userId);
+ String getString(in String key, in String defaultValue, in int userId);
+ void setLockPattern(in byte[] hash, int userId);
+ boolean checkPattern(in byte[] hash, int userId);
+ void setLockPassword(in byte[] hash, int userId);
+ boolean checkPassword(in byte[] hash, int userId);
+ boolean havePattern(int userId);
+ boolean havePassword(int userId);
+ void removeUser(int userId);
+}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 93f90f6..4d308dd 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -21,15 +21,20 @@
import com.google.android.collect.Lists;
import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.PackageManager;
+import android.os.Binder;
import android.os.FileObserver;
import android.os.IBinder;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
+import android.os.UserId;
import android.os.storage.IMountService;
import android.provider.Settings;
import android.security.KeyStore;
@@ -59,10 +64,6 @@
private static final String TAG = "LockPatternUtils";
- private static final String SYSTEM_DIRECTORY = "/system/";
- private static final String LOCK_PATTERN_FILE = "gesture.key";
- private static final String LOCK_PASSWORD_FILE = "password.key";
-
/**
* The maximum number of incorrect attempts before the user is prevented
* from trying again for {@link #FAILED_ATTEMPT_TIMEOUT_MS}.
@@ -111,14 +112,14 @@
*/
public static final int FLAG_BIOMETRIC_WEAK_LIVELINESS = 0x1;
- private final static String LOCKOUT_PERMANENT_KEY = "lockscreen.lockedoutpermanently";
- private final static String LOCKOUT_ATTEMPT_DEADLINE = "lockscreen.lockoutattemptdeadline";
- private final static String PATTERN_EVER_CHOSEN_KEY = "lockscreen.patterneverchosen";
+ protected final static String LOCKOUT_PERMANENT_KEY = "lockscreen.lockedoutpermanently";
+ protected final static String LOCKOUT_ATTEMPT_DEADLINE = "lockscreen.lockoutattemptdeadline";
+ protected final static String PATTERN_EVER_CHOSEN_KEY = "lockscreen.patterneverchosen";
public final static String PASSWORD_TYPE_KEY = "lockscreen.password_type";
public static final String PASSWORD_TYPE_ALTERNATE_KEY = "lockscreen.password_type_alternate";
- private final static String LOCK_PASSWORD_SALT_KEY = "lockscreen.password_salt";
- private final static String DISABLE_LOCKSCREEN_KEY = "lockscreen.disabled";
- private final static String LOCKSCREEN_OPTIONS = "lockscreen.options";
+ protected final static String LOCK_PASSWORD_SALT_KEY = "lockscreen.password_salt";
+ protected final static String DISABLE_LOCKSCREEN_KEY = "lockscreen.disabled";
+ protected final static String LOCKSCREEN_OPTIONS = "lockscreen.options";
public final static String LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK
= "lockscreen.biometric_weak_fallback";
public final static String BIOMETRIC_WEAK_EVER_CHOSEN_KEY
@@ -126,35 +127,13 @@
public final static String LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS
= "lockscreen.power_button_instantly_locks";
- private final static String PASSWORD_HISTORY_KEY = "lockscreen.passwordhistory";
+ protected final static String PASSWORD_HISTORY_KEY = "lockscreen.passwordhistory";
private final Context mContext;
private final ContentResolver mContentResolver;
private DevicePolicyManager mDevicePolicyManager;
- private static String sLockPatternFilename;
- private static String sLockPasswordFilename;
-
- private static final AtomicBoolean sHaveNonZeroPatternFile = new AtomicBoolean(false);
- private static final AtomicBoolean sHaveNonZeroPasswordFile = new AtomicBoolean(false);
-
- private static FileObserver sPasswordObserver;
-
- private static class PasswordFileObserver extends FileObserver {
- public PasswordFileObserver(String path, int mask) {
- super(path, mask);
- }
-
- @Override
- public void onEvent(int event, String path) {
- if (LOCK_PATTERN_FILE.equals(path)) {
- Log.d(TAG, "lock pattern file changed");
- sHaveNonZeroPatternFile.set(new File(sLockPatternFilename).length() > 0);
- } else if (LOCK_PASSWORD_FILE.equals(path)) {
- Log.d(TAG, "lock password file changed");
- sHaveNonZeroPasswordFile.set(new File(sLockPasswordFilename).length() > 0);
- }
- }
- }
+ private ILockSettings mLockSettingsService;
+ private int mCurrentUserId = 0;
public DevicePolicyManager getDevicePolicyManager() {
if (mDevicePolicyManager == null) {
@@ -167,34 +146,27 @@
}
return mDevicePolicyManager;
}
+
/**
* @param contentResolver Used to look up and save settings.
*/
public LockPatternUtils(Context context) {
mContext = context;
mContentResolver = context.getContentResolver();
+ }
- // Initialize the location of gesture & PIN lock files
- if (sLockPatternFilename == null) {
- String dataSystemDirectory =
- android.os.Environment.getDataDirectory().getAbsolutePath() +
- SYSTEM_DIRECTORY;
- sLockPatternFilename = dataSystemDirectory + LOCK_PATTERN_FILE;
- sLockPasswordFilename = dataSystemDirectory + LOCK_PASSWORD_FILE;
- sHaveNonZeroPatternFile.set(new File(sLockPatternFilename).length() > 0);
- sHaveNonZeroPasswordFile.set(new File(sLockPasswordFilename).length() > 0);
- int fileObserverMask = FileObserver.CLOSE_WRITE | FileObserver.DELETE |
- FileObserver.MOVED_TO | FileObserver.CREATE;
- sPasswordObserver = new PasswordFileObserver(dataSystemDirectory, fileObserverMask);
- sPasswordObserver.startWatching();
+ private ILockSettings getLockSettings() {
+ if (mLockSettingsService == null) {
+ mLockSettingsService = ILockSettings.Stub.asInterface(
+ (IBinder) ServiceManager.getService("lock_settings"));
}
+ return mLockSettingsService;
}
public int getRequestedMinimumPasswordLength() {
return getDevicePolicyManager().getPasswordMinimumLength(null);
}
-
/**
* Gets the device policy password mode. If the mode is non-specific, returns
* MODE_PATTERN which allows the user to choose anything.
@@ -243,6 +215,33 @@
getDevicePolicyManager().reportSuccessfulPasswordAttempt();
}
+ public void setCurrentUser(int userId) {
+ if (Process.myUid() == Process.SYSTEM_UID) {
+ mCurrentUserId = userId;
+ } else {
+ throw new SecurityException("Only the system process can set the current user");
+ }
+ }
+
+ public void removeUser(int userId) {
+ if (Process.myUid() == Process.SYSTEM_UID) {
+ try {
+ getLockSettings().removeUser(userId);
+ } catch (RemoteException re) {
+ Log.e(TAG, "Couldn't remove lock settings for user " + userId);
+ }
+ }
+ }
+
+ private int getCurrentOrCallingUserId() {
+ int callingUid = Binder.getCallingUid();
+ if (callingUid == android.os.Process.SYSTEM_UID) {
+ return mCurrentUserId;
+ } else {
+ return UserId.getUserId(callingUid);
+ }
+ }
+
/**
* Check to see if a pattern matches the saved pattern. If no pattern exists,
* always returns true.
@@ -250,20 +249,10 @@
* @return Whether the pattern matches the stored one.
*/
public boolean checkPattern(List<LockPatternView.Cell> pattern) {
+ int userId = getCurrentOrCallingUserId();
try {
- // Read all the bytes from the file
- RandomAccessFile raf = new RandomAccessFile(sLockPatternFilename, "r");
- final byte[] stored = new byte[(int) raf.length()];
- int got = raf.read(stored, 0, stored.length);
- raf.close();
- if (got <= 0) {
- return true;
- }
- // Compare the hash from the file with the entered pattern's hash
- return Arrays.equals(stored, LockPatternUtils.patternToHash(pattern));
- } catch (FileNotFoundException fnfe) {
- return true;
- } catch (IOException ioe) {
+ return getLockSettings().checkPattern(patternToHash(pattern), userId);
+ } catch (RemoteException re) {
return true;
}
}
@@ -275,20 +264,10 @@
* @return Whether the password matches the stored one.
*/
public boolean checkPassword(String password) {
+ int userId = getCurrentOrCallingUserId();
try {
- // Read all the bytes from the file
- RandomAccessFile raf = new RandomAccessFile(sLockPasswordFilename, "r");
- final byte[] stored = new byte[(int) raf.length()];
- int got = raf.read(stored, 0, stored.length);
- raf.close();
- if (got <= 0) {
- return true;
- }
- // Compare the hash from the file with the entered password's hash
- return Arrays.equals(stored, passwordToHash(password));
- } catch (FileNotFoundException fnfe) {
- return true;
- } catch (IOException ioe) {
+ return getLockSettings().checkPassword(passwordToHash(password), userId);
+ } catch (RemoteException re) {
return true;
}
}
@@ -325,7 +304,11 @@
* @return Whether a saved pattern exists.
*/
public boolean savedPatternExists() {
- return sHaveNonZeroPatternFile.get();
+ try {
+ return getLockSettings().havePattern(getCurrentOrCallingUserId());
+ } catch (RemoteException re) {
+ return false;
+ }
}
/**
@@ -333,7 +316,11 @@
* @return Whether a saved pattern exists.
*/
public boolean savedPasswordExists() {
- return sHaveNonZeroPasswordFile.get();
+ try {
+ return getLockSettings().havePassword(getCurrentOrCallingUserId());
+ } catch (RemoteException re) {
+ return false;
+ }
}
/**
@@ -471,15 +458,7 @@
// Compute the hash
final byte[] hash = LockPatternUtils.patternToHash(pattern);
try {
- // Write the hash to file
- RandomAccessFile raf = new RandomAccessFile(sLockPatternFilename, "rw");
- // Truncate the file if pattern is null, to clear the lock
- if (pattern == null) {
- raf.setLength(0);
- } else {
- raf.write(hash, 0, hash.length);
- }
- raf.close();
+ getLockSettings().setLockPattern(hash, getCurrentOrCallingUserId());
DevicePolicyManager dpm = getDevicePolicyManager();
KeyStore keyStore = KeyStore.getInstance();
if (pattern != null) {
@@ -505,13 +484,8 @@
dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0,
0, 0, 0, 0, 0);
}
- } catch (FileNotFoundException fnfe) {
- // Cant do much, unless we want to fail over to using the settings
- // provider
- Log.e(TAG, "Unable to save lock pattern to " + sLockPatternFilename);
- } catch (IOException ioe) {
- // Cant do much
- Log.e(TAG, "Unable to save lock pattern to " + sLockPatternFilename);
+ } catch (RemoteException re) {
+ Log.e(TAG, "Couldn't save lock pattern " + re);
}
}
@@ -586,15 +560,7 @@
// Compute the hash
final byte[] hash = passwordToHash(password);
try {
- // Write the hash to file
- RandomAccessFile raf = new RandomAccessFile(sLockPasswordFilename, "rw");
- // Truncate the file if pattern is null, to clear the lock
- if (password == null) {
- raf.setLength(0);
- } else {
- raf.write(hash, 0, hash.length);
- }
- raf.close();
+ getLockSettings().setLockPassword(hash, getCurrentOrCallingUserId());
DevicePolicyManager dpm = getDevicePolicyManager();
KeyStore keyStore = KeyStore.getInstance();
if (password != null) {
@@ -676,12 +642,9 @@
dpm.setActivePasswordState(
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0, 0, 0, 0, 0, 0);
}
- } catch (FileNotFoundException fnfe) {
- // Cant do much, unless we want to fail over to using the settings provider
- Log.e(TAG, "Unable to save lock pattern to " + sLockPasswordFilename);
- } catch (IOException ioe) {
+ } catch (RemoteException re) {
// Cant do much
- Log.e(TAG, "Unable to save lock pattern to " + sLockPasswordFilename);
+ Log.e(TAG, "Unable to save lock password " + re);
}
}
@@ -1013,30 +976,57 @@
}
private boolean getBoolean(String secureSettingKey, boolean defaultValue) {
- return 1 ==
- android.provider.Settings.Secure.getInt(mContentResolver, secureSettingKey,
- defaultValue ? 1 : 0);
+ try {
+ return getLockSettings().getBoolean(secureSettingKey, defaultValue,
+ getCurrentOrCallingUserId());
+ } catch (RemoteException re) {
+ return defaultValue;
+ }
}
private void setBoolean(String secureSettingKey, boolean enabled) {
- android.provider.Settings.Secure.putInt(mContentResolver, secureSettingKey,
- enabled ? 1 : 0);
+ try {
+ getLockSettings().setBoolean(secureSettingKey, enabled, getCurrentOrCallingUserId());
+ } catch (RemoteException re) {
+ // What can we do?
+ Log.e(TAG, "Couldn't write boolean " + secureSettingKey + re);
+ }
}
- private long getLong(String secureSettingKey, long def) {
- return android.provider.Settings.Secure.getLong(mContentResolver, secureSettingKey, def);
+ private long getLong(String secureSettingKey, long defaultValue) {
+ try {
+ return getLockSettings().getLong(secureSettingKey, defaultValue,
+ getCurrentOrCallingUserId());
+ } catch (RemoteException re) {
+ return defaultValue;
+ }
}
private void setLong(String secureSettingKey, long value) {
- android.provider.Settings.Secure.putLong(mContentResolver, secureSettingKey, value);
+ try {
+ getLockSettings().setLong(secureSettingKey, value, getCurrentOrCallingUserId());
+ } catch (RemoteException re) {
+ // What can we do?
+ Log.e(TAG, "Couldn't write long " + secureSettingKey + re);
+ }
}
private String getString(String secureSettingKey) {
- return android.provider.Settings.Secure.getString(mContentResolver, secureSettingKey);
+ try {
+ return getLockSettings().getString(secureSettingKey, null,
+ getCurrentOrCallingUserId());
+ } catch (RemoteException re) {
+ return null;
+ }
}
private void setString(String secureSettingKey, String value) {
- android.provider.Settings.Secure.putString(mContentResolver, secureSettingKey, value);
+ try {
+ getLockSettings().setString(secureSettingKey, value, getCurrentOrCallingUserId());
+ } catch (RemoteException re) {
+ // What can we do?
+ Log.e(TAG, "Couldn't write string " + secureSettingKey + re);
+ }
}
public boolean isSecure() {
diff --git a/core/java/com/android/internal/widget/LockSettingsService.java b/core/java/com/android/internal/widget/LockSettingsService.java
new file mode 100644
index 0000000..24c7161
--- /dev/null
+++ b/core/java/com/android/internal/widget/LockSettingsService.java
@@ -0,0 +1,388 @@
+/*
+ * 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.internal.widget;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.os.UserId;
+import android.provider.Settings;
+import android.provider.Settings.Secure;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Arrays;
+
+/**
+ * Keeps the lock pattern/password data and related settings for each user.
+ * Used by LockPatternUtils. Needs to be a service because Settings app also needs
+ * to be able to save lockscreen information for secondary users.
+ * @hide
+ */
+public class LockSettingsService extends ILockSettings.Stub {
+
+ private final DatabaseHelper mOpenHelper;
+ private static final String TAG = "LockSettingsService";
+
+ private static final String TABLE = "locksettings";
+ private static final String COLUMN_KEY = "name";
+ private static final String COLUMN_USERID = "user";
+ private static final String COLUMN_VALUE = "value";
+
+ private static final String[] COLUMNS_FOR_QUERY = {
+ COLUMN_VALUE
+ };
+
+ private static final String SYSTEM_DIRECTORY = "/system/";
+ private static final String LOCK_PATTERN_FILE = "gesture.key";
+ private static final String LOCK_PASSWORD_FILE = "password.key";
+
+ private final Context mContext;
+
+ public LockSettingsService(Context context) {
+ mContext = context;
+ // Open the database
+ mOpenHelper = new DatabaseHelper(mContext);
+ }
+
+ public void systemReady() {
+ migrateOldData();
+ }
+
+ private void migrateOldData() {
+ try {
+ if (getString("migrated", null, 0) != null) {
+ // Already migrated
+ return;
+ }
+
+ final ContentResolver cr = mContext.getContentResolver();
+ for (String validSetting : VALID_SETTINGS) {
+ String value = Settings.Secure.getString(cr, validSetting);
+ if (value != null) {
+ setString(validSetting, value, 0);
+ }
+ }
+ // No need to move the password / pattern files. They're already in the right place.
+ setString("migrated", "true", 0);
+ Slog.i(TAG, "Migrated lock settings to new location");
+ } catch (RemoteException re) {
+ Slog.e(TAG, "Unable to migrate old data");
+ }
+ }
+
+ private static final void checkWritePermission(int userId) {
+ final int callingUid = Binder.getCallingUid();
+ if (UserId.getAppId(callingUid) != android.os.Process.SYSTEM_UID) {
+ throw new SecurityException("uid=" + callingUid
+ + " not authorized to write lock settings");
+ }
+ }
+
+ private static final void checkPasswordReadPermission(int userId) {
+ final int callingUid = Binder.getCallingUid();
+ if (UserId.getAppId(callingUid) != android.os.Process.SYSTEM_UID) {
+ throw new SecurityException("uid=" + callingUid
+ + " not authorized to read lock password");
+ }
+ }
+
+ private static final void checkReadPermission(int userId) {
+ final int callingUid = Binder.getCallingUid();
+ if (UserId.getAppId(callingUid) != android.os.Process.SYSTEM_UID
+ && UserId.getUserId(callingUid) != userId) {
+ throw new SecurityException("uid=" + callingUid
+ + " not authorized to read settings of user " + userId);
+ }
+ }
+
+ @Override
+ public void setBoolean(String key, boolean value, int userId) throws RemoteException {
+ checkWritePermission(userId);
+
+ writeToDb(key, value ? "1" : "0", userId);
+ }
+
+ @Override
+ public void setLong(String key, long value, int userId) throws RemoteException {
+ checkWritePermission(userId);
+
+ writeToDb(key, Long.toString(value), userId);
+ }
+
+ @Override
+ public void setString(String key, String value, int userId) throws RemoteException {
+ checkWritePermission(userId);
+
+ writeToDb(key, value, userId);
+ }
+
+ @Override
+ public boolean getBoolean(String key, boolean defaultValue, int userId) throws RemoteException {
+ //checkReadPermission(userId);
+
+ String value = readFromDb(key, null, userId);
+ return TextUtils.isEmpty(value) ?
+ defaultValue : (value.equals("1") || value.equals("true"));
+ }
+
+ @Override
+ public long getLong(String key, long defaultValue, int userId) throws RemoteException {
+ //checkReadPermission(userId);
+
+ String value = readFromDb(key, null, userId);
+ return TextUtils.isEmpty(value) ? defaultValue : Long.parseLong(value);
+ }
+
+ @Override
+ public String getString(String key, String defaultValue, int userId) throws RemoteException {
+ //checkReadPermission(userId);
+
+ return readFromDb(key, defaultValue, userId);
+ }
+
+ private String getLockPatternFilename(int userId) {
+ String dataSystemDirectory =
+ android.os.Environment.getDataDirectory().getAbsolutePath() +
+ SYSTEM_DIRECTORY;
+ if (userId == 0) {
+ // Leave it in the same place for user 0
+ return dataSystemDirectory + LOCK_PATTERN_FILE;
+ } else {
+ return dataSystemDirectory + "users/" + userId + "/" + LOCK_PATTERN_FILE;
+ }
+ }
+
+ private String getLockPasswordFilename(int userId) {
+ String dataSystemDirectory =
+ android.os.Environment.getDataDirectory().getAbsolutePath() +
+ SYSTEM_DIRECTORY;
+ if (userId == 0) {
+ // Leave it in the same place for user 0
+ return dataSystemDirectory + LOCK_PASSWORD_FILE;
+ } else {
+ return dataSystemDirectory + "users/" + userId + "/" + LOCK_PASSWORD_FILE;
+ }
+ }
+
+ @Override
+ public boolean havePassword(int userId) throws RemoteException {
+ // Do we need a permissions check here?
+
+ return new File(getLockPasswordFilename(userId)).length() > 0;
+ }
+
+ @Override
+ public boolean havePattern(int userId) throws RemoteException {
+ // Do we need a permissions check here?
+
+ return new File(getLockPatternFilename(userId)).length() > 0;
+ }
+
+ @Override
+ public void setLockPattern(byte[] hash, int userId) throws RemoteException {
+ checkWritePermission(userId);
+
+ writeFile(getLockPatternFilename(userId), hash);
+ }
+
+ @Override
+ public boolean checkPattern(byte[] hash, int userId) throws RemoteException {
+ checkPasswordReadPermission(userId);
+ try {
+ // Read all the bytes from the file
+ RandomAccessFile raf = new RandomAccessFile(getLockPatternFilename(userId), "r");
+ final byte[] stored = new byte[(int) raf.length()];
+ int got = raf.read(stored, 0, stored.length);
+ raf.close();
+ if (got <= 0) {
+ return true;
+ }
+ // Compare the hash from the file with the entered pattern's hash
+ return Arrays.equals(stored, hash);
+ } catch (FileNotFoundException fnfe) {
+ Slog.e(TAG, "Cannot read file " + fnfe);
+ return true;
+ } catch (IOException ioe) {
+ Slog.e(TAG, "Cannot read file " + ioe);
+ return true;
+ }
+ }
+
+ @Override
+ public void setLockPassword(byte[] hash, int userId) throws RemoteException {
+ checkWritePermission(userId);
+
+ writeFile(getLockPasswordFilename(userId), hash);
+ }
+
+ @Override
+ public boolean checkPassword(byte[] hash, int userId) throws RemoteException {
+ checkPasswordReadPermission(userId);
+
+ try {
+ // Read all the bytes from the file
+ RandomAccessFile raf = new RandomAccessFile(getLockPasswordFilename(userId), "r");
+ final byte[] stored = new byte[(int) raf.length()];
+ int got = raf.read(stored, 0, stored.length);
+ raf.close();
+ if (got <= 0) {
+ return true;
+ }
+ // Compare the hash from the file with the entered password's hash
+ return Arrays.equals(stored, hash);
+ } catch (FileNotFoundException fnfe) {
+ Slog.e(TAG, "Cannot read file " + fnfe);
+ return true;
+ } catch (IOException ioe) {
+ Slog.e(TAG, "Cannot read file " + ioe);
+ return true;
+ }
+ }
+
+ @Override
+ public void removeUser(int userId) {
+ checkWritePermission(userId);
+
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ try {
+ File file = new File(getLockPasswordFilename(userId));
+ if (file.exists()) {
+ file.delete();
+ }
+ file = new File(getLockPatternFilename(userId));
+ if (file.exists()) {
+ file.delete();
+ }
+
+ db.beginTransaction();
+ db.delete(TABLE, COLUMN_USERID + "='" + userId + "'", null);
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
+ }
+
+ private void writeFile(String name, byte[] hash) {
+ try {
+ // Write the hash to file
+ RandomAccessFile raf = new RandomAccessFile(name, "rw");
+ // Truncate the file if pattern is null, to clear the lock
+ if (hash == null || hash.length == 0) {
+ raf.setLength(0);
+ } else {
+ raf.write(hash, 0, hash.length);
+ }
+ raf.close();
+ } catch (IOException ioe) {
+ Slog.e(TAG, "Error writing to file " + ioe);
+ }
+ }
+
+ private void writeToDb(String key, String value, int userId) {
+ ContentValues cv = new ContentValues();
+ cv.put(COLUMN_KEY, key);
+ cv.put(COLUMN_USERID, userId);
+ cv.put(COLUMN_VALUE, value);
+
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ db.beginTransaction();
+ try {
+ db.delete(TABLE, COLUMN_KEY + "=? AND " + COLUMN_USERID + "=?",
+ new String[] {key, Integer.toString(userId)});
+ db.insert(TABLE, null, cv);
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
+ }
+
+ private String readFromDb(String key, String defaultValue, int userId) {
+ Cursor cursor;
+ String result = defaultValue;
+ SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+ if ((cursor = db.query(TABLE, COLUMNS_FOR_QUERY,
+ COLUMN_USERID + "=? AND " + COLUMN_KEY + "=?",
+ new String[] { Integer.toString(userId), key },
+ null, null, null)) != null) {
+ if (cursor.moveToFirst()) {
+ result = cursor.getString(0);
+ }
+ cursor.close();
+ }
+ return result;
+ }
+
+ class DatabaseHelper extends SQLiteOpenHelper {
+ private static final String TAG = "LockSettingsDB";
+ private static final String DATABASE_NAME = "locksettings.db";
+
+ private static final int DATABASE_VERSION = 1;
+
+ public DatabaseHelper(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ setWriteAheadLoggingEnabled(true);
+ }
+
+ private void createTable(SQLiteDatabase db) {
+ db.execSQL("CREATE TABLE " + TABLE + " (" +
+ "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
+ COLUMN_KEY + " TEXT," +
+ COLUMN_USERID + " INTEGER," +
+ COLUMN_VALUE + " TEXT" +
+ ");");
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ createTable(db);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
+ // Nothing yet
+ }
+ }
+
+ private static final String[] VALID_SETTINGS = new String[] {
+ LockPatternUtils.LOCKOUT_PERMANENT_KEY,
+ LockPatternUtils.LOCKOUT_ATTEMPT_DEADLINE,
+ LockPatternUtils.PATTERN_EVER_CHOSEN_KEY,
+ LockPatternUtils.PASSWORD_TYPE_KEY,
+ LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
+ LockPatternUtils.LOCK_PASSWORD_SALT_KEY,
+ LockPatternUtils.DISABLE_LOCKSCREEN_KEY,
+ LockPatternUtils.LOCKSCREEN_OPTIONS,
+ LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK,
+ LockPatternUtils.BIOMETRIC_WEAK_EVER_CHOSEN_KEY,
+ LockPatternUtils.LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS,
+ LockPatternUtils.PASSWORD_HISTORY_KEY,
+ Secure.LOCK_PATTERN_ENABLED,
+ Secure.LOCK_BIOMETRIC_WEAK_FLAGS,
+ Secure.LOCK_PATTERN_VISIBLE,
+ Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED
+ };
+}
diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp
index 3d350ed..244b166 100644
--- a/core/jni/android/graphics/SurfaceTexture.cpp
+++ b/core/jni/android/graphics/SurfaceTexture.cpp
@@ -218,6 +218,18 @@
return surfaceTexture->updateTexImage();
}
+static jint SurfaceTexture_detachFromGLContext(JNIEnv* env, jobject thiz)
+{
+ sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
+ return surfaceTexture->detachFromContext();
+}
+
+static jint SurfaceTexture_attachToGLContext(JNIEnv* env, jobject thiz, jint tex)
+{
+ sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
+ return surfaceTexture->attachToContext((GLuint)tex);
+}
+
static void SurfaceTexture_getTransformMatrix(JNIEnv* env, jobject thiz,
jfloatArray jmtx)
{
@@ -242,14 +254,16 @@
// ----------------------------------------------------------------------------
static JNINativeMethod gSurfaceTextureMethods[] = {
- {"nativeClassInit", "()V", (void*)SurfaceTexture_classInit },
- {"nativeInit", "(ILjava/lang/Object;Z)V", (void*)SurfaceTexture_init },
- {"nativeFinalize", "()V", (void*)SurfaceTexture_finalize },
+ {"nativeClassInit", "()V", (void*)SurfaceTexture_classInit },
+ {"nativeInit", "(ILjava/lang/Object;Z)V", (void*)SurfaceTexture_init },
+ {"nativeFinalize", "()V", (void*)SurfaceTexture_finalize },
{"nativeSetDefaultBufferSize", "(II)V", (void*)SurfaceTexture_setDefaultBufferSize },
- {"nativeUpdateTexImage", "()I", (void*)SurfaceTexture_updateTexImage },
- {"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix },
- {"nativeGetTimestamp", "()J", (void*)SurfaceTexture_getTimestamp },
- {"nativeRelease", "()V", (void*)SurfaceTexture_release },
+ {"nativeUpdateTexImage", "()I", (void*)SurfaceTexture_updateTexImage },
+ {"nativeDetachFromGLContext", "()I", (void*)SurfaceTexture_detachFromGLContext },
+ {"nativeAttachToGLContext", "(I)I", (void*)SurfaceTexture_attachToGLContext },
+ {"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix },
+ {"nativeGetTimestamp", "()J", (void*)SurfaceTexture_getTimestamp },
+ {"nativeRelease", "()V", (void*)SurfaceTexture_release },
};
int register_android_graphics_SurfaceTexture(JNIEnv* env)
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 5ae12b6..00faa41 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1200,7 +1200,8 @@
android:protectionLevel="signature|system" />
<!-- Allows an application to retrieve the current state of keys and
- switches. This is only for use by the system.-->
+ switches. This is only for use by the system.
+ @deprecated The API that used this permission has been removed. -->
<permission android:name="android.permission.READ_INPUT_STATE"
android:label="@string/permlab_readInputState"
android:description="@string/permdesc_readInputState"
diff --git a/packages/SystemUI/res/anim/status_bar_enter.xml b/core/res/res/anim/dock_bottom_enter.xml
similarity index 77%
copy from packages/SystemUI/res/anim/status_bar_enter.xml
copy to core/res/res/anim/dock_bottom_enter.xml
index f1c1301..7a2e94b 100644
--- a/packages/SystemUI/res/anim/status_bar_enter.xml
+++ b/core/res/res/anim/dock_bottom_enter.xml
@@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
-/* //device/apps/common/res/anim/options_panel_enter.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* 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.
@@ -18,10 +16,11 @@
*/
-->
+<!-- Animation for when a dock window at the bottom of the screen is entering. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/decelerate_quad">
- <translate android:fromYDelta="-75%" android:toYDelta="0"
+ <translate android:fromYDelta="75%" android:toYDelta="0"
android:duration="@android:integer/config_mediumAnimTime"/>
- <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+ <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_mediumAnimTime" />
</set>
diff --git a/packages/SystemUI/res/anim/status_bar_exit.xml b/core/res/res/anim/dock_bottom_exit.xml
similarity index 78%
copy from packages/SystemUI/res/anim/status_bar_exit.xml
copy to core/res/res/anim/dock_bottom_exit.xml
index 46462e2..c2fd15c 100644
--- a/packages/SystemUI/res/anim/status_bar_exit.xml
+++ b/core/res/res/anim/dock_bottom_exit.xml
@@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
-/* //device/apps/common/res/anim/options_panel_exit.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* 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.
@@ -18,10 +16,11 @@
*/
-->
+<!-- Animation for when a dock window at the bottom of the screen is exiting. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/accelerate_quad">
- <translate android:fromYDelta="0" android:toYDelta="-75%"
+ <translate android:fromYDelta="0" android:toYDelta="75%"
android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/>
- <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+ <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime" />
</set>
diff --git a/packages/SystemUI/res/anim/status_bar_enter.xml b/core/res/res/anim/dock_left_enter.xml
similarity index 77%
copy from packages/SystemUI/res/anim/status_bar_enter.xml
copy to core/res/res/anim/dock_left_enter.xml
index f1c1301..b057f67 100644
--- a/packages/SystemUI/res/anim/status_bar_enter.xml
+++ b/core/res/res/anim/dock_left_enter.xml
@@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
-/* //device/apps/common/res/anim/options_panel_enter.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* 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.
@@ -18,10 +16,11 @@
*/
-->
+<!-- Animation for when a dock window at the left of the screen is entering. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/decelerate_quad">
- <translate android:fromYDelta="-75%" android:toYDelta="0"
+ <translate android:fromXDelta="-75%" android:toXDelta="0"
android:duration="@android:integer/config_mediumAnimTime"/>
- <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+ <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_mediumAnimTime" />
</set>
diff --git a/packages/SystemUI/res/anim/status_bar_exit.xml b/core/res/res/anim/dock_left_exit.xml
similarity index 78%
copy from packages/SystemUI/res/anim/status_bar_exit.xml
copy to core/res/res/anim/dock_left_exit.xml
index 46462e2..576b1aa 100644
--- a/packages/SystemUI/res/anim/status_bar_exit.xml
+++ b/core/res/res/anim/dock_left_exit.xml
@@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
-/* //device/apps/common/res/anim/options_panel_exit.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* 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.
@@ -18,10 +16,11 @@
*/
-->
+<!-- Animation for when a dock window at the right of the screen is exiting. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/accelerate_quad">
- <translate android:fromYDelta="0" android:toYDelta="-75%"
+ <translate android:fromXDelta="0" android:toXDelta="-75%"
android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/>
- <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+ <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime" />
</set>
diff --git a/packages/SystemUI/res/anim/status_bar_enter.xml b/core/res/res/anim/dock_right_enter.xml
similarity index 77%
copy from packages/SystemUI/res/anim/status_bar_enter.xml
copy to core/res/res/anim/dock_right_enter.xml
index f1c1301..e1bd190 100644
--- a/packages/SystemUI/res/anim/status_bar_enter.xml
+++ b/core/res/res/anim/dock_right_enter.xml
@@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
-/* //device/apps/common/res/anim/options_panel_enter.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* 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.
@@ -18,10 +16,11 @@
*/
-->
+<!-- Animation for when a dock window at the right of the screen is entering. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/decelerate_quad">
- <translate android:fromYDelta="-75%" android:toYDelta="0"
+ <translate android:fromXDelta="75%" android:toXDelta="0"
android:duration="@android:integer/config_mediumAnimTime"/>
- <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+ <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_mediumAnimTime" />
</set>
diff --git a/packages/SystemUI/res/anim/status_bar_exit.xml b/core/res/res/anim/dock_right_exit.xml
similarity index 78%
copy from packages/SystemUI/res/anim/status_bar_exit.xml
copy to core/res/res/anim/dock_right_exit.xml
index 46462e2..6d778fa 100644
--- a/packages/SystemUI/res/anim/status_bar_exit.xml
+++ b/core/res/res/anim/dock_right_exit.xml
@@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
-/* //device/apps/common/res/anim/options_panel_exit.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* 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.
@@ -18,10 +16,11 @@
*/
-->
+<!-- Animation for when a dock window at the right of the screen is exiting. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/accelerate_quad">
- <translate android:fromYDelta="0" android:toYDelta="-75%"
+ <translate android:fromXDelta="0" android:toXDelta="75%"
android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/>
- <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+ <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime" />
</set>
diff --git a/packages/SystemUI/res/anim/status_bar_enter.xml b/core/res/res/anim/dock_top_enter.xml
similarity index 77%
rename from packages/SystemUI/res/anim/status_bar_enter.xml
rename to core/res/res/anim/dock_top_enter.xml
index f1c1301..f2e4cae 100644
--- a/packages/SystemUI/res/anim/status_bar_enter.xml
+++ b/core/res/res/anim/dock_top_enter.xml
@@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
-/* //device/apps/common/res/anim/options_panel_enter.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -18,10 +16,11 @@
*/
-->
+<!-- Animation for when a dock window at the top of the screen is entering. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/decelerate_quad">
- <translate android:fromYDelta="-75%" android:toYDelta="0"
+ <translate android:fromYDelta="-75%" android:toYDelta="0"
android:duration="@android:integer/config_mediumAnimTime"/>
- <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+ <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_mediumAnimTime" />
</set>
diff --git a/packages/SystemUI/res/anim/status_bar_exit.xml b/core/res/res/anim/dock_top_exit.xml
similarity index 78%
rename from packages/SystemUI/res/anim/status_bar_exit.xml
rename to core/res/res/anim/dock_top_exit.xml
index 46462e2..7373695 100644
--- a/packages/SystemUI/res/anim/status_bar_exit.xml
+++ b/core/res/res/anim/dock_top_exit.xml
@@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
-/* //device/apps/common/res/anim/options_panel_exit.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -18,10 +16,11 @@
*/
-->
+<!-- Animation for when a dock window at the top of the screen is exiting. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/accelerate_quad">
- <translate android:fromYDelta="0" android:toYDelta="-75%"
+ <translate android:fromYDelta="0" android:toYDelta="-75%"
android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/>
- <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+ <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime" />
</set>
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_search_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_search_activated.png
new file mode 100644
index 0000000..0d2e2ef
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_search_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_search_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_search_normal.png
new file mode 100644
index 0000000..66d14ae
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_search_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_search_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_search_activated.png
new file mode 100644
index 0000000..73c6be6
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_search_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_search_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_search_normal.png
new file mode 100644
index 0000000..73c6be6
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_search_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_search_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_search_activated.png
new file mode 100644
index 0000000..c625a36
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_search_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_search_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_search_normal.png
new file mode 100644
index 0000000..c625a36
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_search_normal.png
Binary files differ
diff --git a/core/res/res/drawable/ic_lockscreen_search.xml b/core/res/res/drawable/ic_lockscreen_search.xml
new file mode 100644
index 0000000..b103922
--- /dev/null
+++ b/core/res/res/drawable/ic_lockscreen_search.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item
+ android:state_enabled="true"
+ android:state_active="false"
+ android:state_focused="false"
+ android:drawable="@drawable/ic_lockscreen_search_normal" />
+
+ <item
+ android:state_enabled="true"
+ android:state_active="true"
+ android:state_focused="false"
+ android:drawable="@drawable/ic_lockscreen_search_activated" />
+
+</selector>
diff --git a/core/res/res/layout/keyguard_screen_unlock_portrait.xml b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
index 9a2e024..35b8665 100644
--- a/core/res/res/layout/keyguard_screen_unlock_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
@@ -173,13 +173,13 @@
<RelativeLayout
android:id="@+id/faceLockAreaView"
android:visibility="invisible"
- android:layout_row="4"
+ android:layout_row="3"
android:layout_column="0"
- android:layout_rowSpan="1"
+ android:layout_rowSpan="2"
android:layout_columnSpan="1"
android:layout_gravity="fill"
- android:layout_marginTop="8dip"
- android:layout_marginBottom="8dip"
+ android:layout_marginTop="4dip"
+ android:layout_marginBottom="4dip"
android:layout_width="0dip"
android:layout_height="0dip"
android:background="@drawable/intro_bg">
diff --git a/core/res/res/layout/notification_template_base.xml b/core/res/res/layout/notification_template_base.xml
index 93843fd..b9710d6 100644
--- a/core/res/res/layout/notification_template_base.xml
+++ b/core/res/res/layout/notification_template_base.xml
@@ -53,15 +53,21 @@
android:fadingEdge="horizontal"
android:layout_weight="1"
/>
- <DateTimeView android:id="@+id/time"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Time"
+ <ViewStub android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="0"
- android:singleLine="true"
- android:gravity="center"
- android:paddingLeft="8dp"
+ android:visibility="gone"
+ android:layout="@layout/notification_template_part_time"
+ />
+ <ViewStub android:id="@+id/chronometer"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:visibility="gone"
+ android:layout="@layout/notification_template_part_chronometer"
/>
</LinearLayout>
<TextView android:id="@+id/text2"
diff --git a/core/res/res/layout/notification_template_part_chronometer.xml b/core/res/res/layout/notification_template_part_chronometer.xml
new file mode 100644
index 0000000..382b0e4
--- /dev/null
+++ b/core/res/res/layout/notification_template_part_chronometer.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<Chronometer android:id="@+id/chronometer" xmlns:android="http://schemas.android.com/apk/res/android"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Time"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:singleLine="true"
+ android:gravity="center"
+ android:paddingLeft="8dp"
+ />
diff --git a/core/res/res/layout/notification_template_part_time.xml b/core/res/res/layout/notification_template_part_time.xml
new file mode 100644
index 0000000..410fcaf
--- /dev/null
+++ b/core/res/res/layout/notification_template_part_time.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<DateTimeView android:id="@+id/time" xmlns:android="http://schemas.android.com/apk/res/android"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Time"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:singleLine="true"
+ android:gravity="center"
+ android:paddingLeft="8dp"
+ />
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 203c335..d6073e3 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Voer \'n PUK van 8 syfers of langer in."</string>
<string name="needPuk" msgid="919668385956251611">"Jou SIM-kaart is PUK-gesluit. Voer die PUK-kode in om dit te ontsluit."</string>
<string name="needPuk2" msgid="4526033371987193070">"Sleutel PUK2 in om SIM-kaart oop te sluit."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Inkomender beller-ID"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Uitgaande beller-ID"</string>
<string name="CfMmi" msgid="5123218989141573515">"Oproepaanstuur"</string>
@@ -1021,6 +1019,8 @@
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Stel tyd"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Stel datum"</string>
<string name="date_time_set" msgid="5777075614321087758">"Stel"</string>
+ <!-- no translation found for date_time_done (2507683751759308828) -->
+ <skip />
<string name="default_permission_group" msgid="2690160991405646128">"Verstek"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NUUT: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Geen toestemmings benodig nie"</string>
@@ -1170,22 +1170,35 @@
<string name="add_account_label" msgid="2935267344849993553">"Voeg \'n rekening by"</string>
<string name="choose_account_text" msgid="6303348737197849675">"Watter rekening wil jy gebruik?"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"Voeg rekening by"</string>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Verhoging"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Verminder"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> raak en hou."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Skuif op om by te tel en af om af te trek."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Tel \'n minuut by"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Trek \'n minuut af"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Tel \'n uur by."</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Trek \'n uur af"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Stel NM."</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Stel VM."</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Tel \'n maand by"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Trek \'n maand af"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Tel \'n dag by"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Trek \'n dag af."</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Tel \'n jaar by"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Trek \'n jaar af"</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="checkbox_checked" msgid="7222044992652711167">"gekontroleer"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"nie gekontroleer nie"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"gekies"</string>
@@ -1205,10 +1218,14 @@
<string name="shareactionprovider_share_with" msgid="806688056141131819">"Deel met"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Deel met <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"Skyfievatsel. Raak en hou."</string>
- <string name="description_direction_up" msgid="1983114130441878529">"Op na <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Af vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Links vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Regs vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Ontsluit"</string>
<string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Stil"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index ab937c5..2b98607 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"8 ወይም ከዛ በላይ የሆኑ ቁጥሮችንPUK ተይብ።"</string>
<string name="needPuk" msgid="919668385956251611">"SIM ካርድዎ PUK-የተቆለፈ ነው።የPUK ኮዱን በመተየብ ይክፈቱት።"</string>
<string name="needPuk2" msgid="4526033371987193070">" SIM ለመክፈት PUK2 ተይብ።"</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"የገቢ ደዋይID"</string>
<string name="ClirMmi" msgid="7784673673446833091">"የወጪ ጥሪID"</string>
<string name="CfMmi" msgid="5123218989141573515">"ጥሪ ማስተላለፍ"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"ጨምር"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"ቀንስ"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> ንካ እና ያዝ።"</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"ለመጨመር ወደላይ ለመቀነስ ወደታች አንሸራት"</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"ደቂቃዎች ጨምር"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"ደቂቃ ቀንስ"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"ሰዓት ጨምር።"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"ሰዓት ቀንስ"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"PM አዘጋጅ"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"AM አዘጋጅ"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"ወር ጨምር"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"ወር ቀንስ"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"ቀን ጨምር"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"ቀን ቀንስ"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"አመት ጨምር"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"አመት ቀንስ"</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="checkbox_checked" msgid="7222044992652711167">"ታይቷል"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"አልተፈተሸም"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"የተመረጠ"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደላይ።"</string>
- <string name="description_direction_down" msgid="4294993639091088240">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደታች።"</string>
- <string name="description_direction_left" msgid="6814008463839915747">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደግራ።"</string>
- <string name="description_direction_right" msgid="4296057241963012862">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደቀኝ።"</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_target_unlock" msgid="2228524900439801453">"ክፈት"</string>
<string name="description_target_camera" msgid="969071997552486814">"ካሜራ"</string>
<string name="description_target_silent" msgid="893551287746522182">"ፀጥታ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index aca8f47..9c3ef5e 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"اكتب رمز PUK مكونًا من 8 أرقام أو أكثر."</string>
<string name="needPuk" msgid="919668385956251611">"بطاقة SIM مؤمّنة بكود PUK. اكتب كود PUK لإلغاء تأمينها."</string>
<string name="needPuk2" msgid="4526033371987193070">"اكتب PUK2 لإلغاء تأمين بطاقة SIM."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"معرف المتصل الوارد"</string>
<string name="ClirMmi" msgid="7784673673446833091">"معرف المتصل الصادر"</string>
<string name="CfMmi" msgid="5123218989141573515">"إعادة توجيه الاتصال"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"زيادة"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"تناقص"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> المس مع الاستمرار."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"مرر لأعلى للزيادة ولأسفل للإنقاص."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"زيادة دقيقة"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"إنقاص دقيقة"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"زيادة ساعة"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"إنقاص ساعة"</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="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="6324978841467899081">"زيادة شهر"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"إنقاص شهر"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"زيادة يوم"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"إنقاص يوم"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"زيادة عام"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"إنقاص عام"</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="checkbox_checked" msgid="7222044992652711167">"تم التحديد"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"لم يتم التحديد"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"محدد"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"أعلى إلى <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"أسفل إلى <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"يسارًا إلى <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"يمينًا إلى <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"إلغاء تأمين"</string>
<string name="description_target_camera" msgid="969071997552486814">"الكاميرا"</string>
<string name="description_target_silent" msgid="893551287746522182">"صامت"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 4d304f1..dcb8f05 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Увядзіце PUK з 8 лічбаў ці больш."</string>
<string name="needPuk" msgid="919668385956251611">"Ваша SIM-карта заблакавана PUK-кодам. Увядзіце PUK, каб разблакаваць карту."</string>
<string name="needPuk2" msgid="4526033371987193070">"Увядзіце PUK2 для разблакавання SIM-карты."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Ідэнтыфікатар АВН"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Ідэнтыфікатар АВН"</string>
<string name="CfMmi" msgid="5123218989141573515">"Пераадрасацыя выкліку"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Інкрэмент"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Дэкрэмент"</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_scroll_mode" msgid="3073101067441638428">"Націсніце і ўтрымлівайце <xliff:g id="VALUE">%s</xliff:g>."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Перасуньце палец уверх, каб павялiчыць адрэзак, або ўніз, каб паменшыць."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"На хвiлiну больш"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"На хвiлiну менш"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"На гадзiну больш"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"На гадзiну менш"</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="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="6324978841467899081">"На месяц больш"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"На месяц менш"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"На дзень больш"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"На дзень менш."</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"На год больш"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"На год менш"</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="checkbox_checked" msgid="7222044992652711167">"пастаўлены"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"не пастаўлены"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"абрана"</string>
@@ -1205,10 +1218,14 @@
<string name="shareactionprovider_share_with" msgid="806688056141131819">"Апублікаваць з дапамогай"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Адправiць з дапамогай прыкладання <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"Ручка для перасоўвання. Націсніце і ўтрымлівайце."</string>
- <string name="description_direction_up" msgid="1983114130441878529">"Уверх да <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Уніз да <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Улева да <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Управа да <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Разблакаваць"</string>
<string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
<string name="description_target_silent" msgid="893551287746522182">"Ціхі рэжым"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index b057cef..cee54b4 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Въведете PUK код с поне осем цифри."</string>
<string name="needPuk" msgid="919668385956251611">"SIM картата ви е заключена с PUK. Въведете PUK кода, за да я отключите."</string>
<string name="needPuk2" msgid="4526033371987193070">"Въведете PUK2, за да отблокирате SIM картата."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Идентификация на вх. обаждания"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Идентификация на изходящите повиквания"</string>
<string name="CfMmi" msgid="5123218989141573515">"Пренасочване на повиквания"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Увеличаване"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Намаляване"</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_scroll_mode" msgid="3073101067441638428">"Докоснете <xliff:g id="VALUE">%s</xliff:g> път/и и задръжте."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Плъзнете нагоре за увеличаване и надолу за намаляване."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Увеличаване на минутите"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Намаляване на минутите"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Увеличаване на часа"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Намаляване на часа"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Задаване на PM"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Задаване на AM"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Увеличаване на месеца"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Намаляване на месеца"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Увеличаване на деня"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Намаляване на деня"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Увеличаване на годината"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Намаляване на годината"</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="checkbox_checked" msgid="7222044992652711167">"отметнато"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"не е отметнато"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"избрано"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"Нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Надолу за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Наляво за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Надясно за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Отключване"</string>
<string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
<string name="description_target_silent" msgid="893551287746522182">"Тих режим"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 61c3cf0..e360af1 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Introdueix un PUK compost com a mínim de 8 nombres."</string>
<string name="needPuk" msgid="919668385956251611">"La targeta SIM està bloquejada pel PUK. Escriviu el codi PUK per desbloquejar-la."</string>
<string name="needPuk2" msgid="4526033371987193070">"Escriviu el PUK2 per desbloquejar la targeta SIM."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Identificació de trucada entrant"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Identificació de trucada de sortida"</string>
<string name="CfMmi" msgid="5123218989141573515">"Desviació de trucades"</string>
@@ -1021,6 +1019,8 @@
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Estableix l\'hora"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Establiment de data"</string>
<string name="date_time_set" msgid="5777075614321087758">"Defineix"</string>
+ <!-- no translation found for date_time_done (2507683751759308828) -->
+ <skip />
<string name="default_permission_group" msgid="2690160991405646128">"Predeterminat"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOU: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"No cal cap permís"</string>
@@ -1170,22 +1170,35 @@
<string name="add_account_label" msgid="2935267344849993553">"Addició d\'un compte"</string>
<string name="choose_account_text" msgid="6303348737197849675">"Quin compte vols utilitzar?"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"Afegeix un compte"</string>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Incrementa"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Disminueix"</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_scroll_mode" msgid="3073101067441638428">"Mantén premut <xliff:g id="VALUE">%s</xliff:g>."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Fes lliscar el dit cap amunt per incrementar i cap avall per disminuir."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Incrementa els minuts"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Disminueix els minuts"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Incrementa les hores"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Disminueix les hores"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Estableix com a p. m."</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Estableix com a a. m."</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Incrementa el mes"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Disminueix el mes"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Incrementa els dies"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Disminueix els dies"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Incrementa l\'any"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Disminueix l\'any"</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="checkbox_checked" msgid="7222044992652711167">"marcat"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"no marcat"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"seleccionat"</string>
@@ -1205,10 +1218,14 @@
<string name="shareactionprovider_share_with" msgid="806688056141131819">"Comparteix amb"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Comparteix amb <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"Llisca el dit. Mantén premut."</string>
- <string name="description_direction_up" msgid="1983114130441878529">"Cap amunt per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Cap avall per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Cap a l\'esquerra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Cap a la dreta per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Desbloqueja"</string>
<string name="description_target_camera" msgid="969071997552486814">"Càmera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Silenci"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index ec640f7..ea206b0 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Zadejte osmimístný nebo delší kód PUK."</string>
<string name="needPuk" msgid="919668385956251611">"Karta SIM je blokována pomocí kódu PUK. Odblokujete ji zadáním kódu PUK."</string>
<string name="needPuk2" msgid="4526033371987193070">"Chcete-li odblokovat kartu SIM, zadejte kód PUK2."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Příchozí identifikace volajícího"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Odchozí identifikace volajícího"</string>
<string name="CfMmi" msgid="5123218989141573515">"Přesměrování hovorů"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Zvýšení"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Snížení"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> dotkněte se a podržte."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Chcete-li přičítat, přejeďte prstem nahoru, chcete-li odečítat, přejeďte prstem dolů."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Přičíst minutu"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Odečíst minutu"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Přičíst hodinu"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Odečíst hodinu"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Nastavit odp."</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Nastavit dop."</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Přičíst měsíc"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Odečíst měsíc"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Přičíst den"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Odečíst den"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Přičíst rok"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Odečíst rok"</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="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>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> – nahoru."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> – dolů."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> – vlevo."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> – vpravo."</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_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>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index d72364b..94c2999 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Angiv en PUK-kode på 8 eller flere cifre."</string>
<string name="needPuk" msgid="919668385956251611">"Dit SIM-kort er låst med PUK-koden. Indtast PUK-koden for at låse den op."</string>
<string name="needPuk2" msgid="4526033371987193070">"Indtast PUK2-koden for at låse op for SIM-kortet."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI-nummer"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Indgående opkalds-id"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Udgående opkalds-id"</string>
<string name="CfMmi" msgid="5123218989141573515">"Viderestilling af opkald"</string>
@@ -1021,6 +1019,8 @@
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Angiv tidspunkt"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Angiv dato"</string>
<string name="date_time_set" msgid="5777075614321087758">"Angiv"</string>
+ <!-- no translation found for date_time_done (2507683751759308828) -->
+ <skip />
<string name="default_permission_group" msgid="2690160991405646128">"Standard"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NYHED! "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Der kræves ingen tilladelser"</string>
@@ -1170,22 +1170,35 @@
<string name="add_account_label" msgid="2935267344849993553">"Tilføj en konto"</string>
<string name="choose_account_text" msgid="6303348737197849675">"Hvilken konto vil du bruge?"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"Tilføj konto"</string>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Optælling"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Nedtælling"</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_scroll_mode" msgid="3073101067441638428">"Tryk <xliff:g id="VALUE">%s</xliff:g> gange, og hold inde."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Glid op for at tilføje, og glid ned for at fjerne."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Tilføj minut"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Fjern minut"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Tilføj time"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Fjern time"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Indstil PM"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Indstil AM"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Tilføj måned"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Fjern måned"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Tilføj dag"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Fjern dag"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Tilføj år"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Fjern år"</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="checkbox_checked" msgid="7222044992652711167">"markeret"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"ikke markeret"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"udvalgt"</string>
@@ -1205,10 +1218,14 @@
<string name="shareactionprovider_share_with" msgid="806688056141131819">"Del med"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Del med <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"Glidende håndtag. Tryk og hold nede."</string>
- <string name="description_direction_up" msgid="1983114130441878529">"Op for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Ned for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Til venstre for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Til højre for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Lås op"</string>
<string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Lydløs"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index defd850..82a60d2 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Geben Sie eine mindestens achtstellige PUK ein."</string>
<string name="needPuk" msgid="919668385956251611">"Ihre SIM-Karte ist mit einem PUK gesperrt. Geben Sie zum Entsperren den PUK-Code ein."</string>
<string name="needPuk2" msgid="4526033371987193070">"Geben Sie zum Entsperren der SIM-Karte den PUK2 ein."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Anrufer-ID für eingehenden Anruf"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Anrufer-ID für ausgehenden Anruf"</string>
<string name="CfMmi" msgid="5123218989141573515">"Rufweiterleitung"</string>
@@ -1021,6 +1019,8 @@
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Uhrzeit festlegen"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Datum festlegen"</string>
<string name="date_time_set" msgid="5777075614321087758">"Speichern"</string>
+ <!-- no translation found for date_time_done (2507683751759308828) -->
+ <skip />
<string name="default_permission_group" msgid="2690160991405646128">"Standard"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"Neu: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Keine Berechtigungen erforderlich"</string>
@@ -1170,22 +1170,35 @@
<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="4830170763103463443">"Erhöhen"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Verringern"</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_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="4628981789985093179">"Zum Vorstellen nach oben und zum Zurückstellen nach unten ziehen"</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Minute vorstellen"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Minute zurückstellen"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Stunde vorstellen"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Stunde zurückstellen"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Zeit festlegen"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Zeit festlegen"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Monat vorstellen"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Monat zurückstellen"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Tag vorstellen"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Tag zurückstellen"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Jahr vorstellen"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Jahr zurückstellen"</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="checkbox_checked" msgid="7222044992652711167">"Aktiviert"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"Nicht aktiviert"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"Ausgewählt"</string>
@@ -1205,10 +1218,14 @@
<string name="shareactionprovider_share_with" msgid="806688056141131819">"Teilen mit"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Mit <xliff:g id="APPLICATION_NAME">%s</xliff:g> teilen"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"Schieberegler: Berühren und halten"</string>
- <string name="description_direction_up" msgid="1983114130441878529">"Für <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach oben"</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Für <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach unten"</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Für <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach links"</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Für <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach rechts"</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_target_unlock" msgid="2228524900439801453">"Entsperren"</string>
<string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Lautlos"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 71547ce..b9710e5 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Πληκτρολογήστε έναν κωδικό PUK με 8 αριθμούς ή περισσότερους."</string>
<string name="needPuk" msgid="919668385956251611">"Η κάρτα SIM έχει κλειδωθεί με κωδικό PUK. Πληκτρολογήστε τον κωδικό PUK για να την ξεκλειδώσετε."</string>
<string name="needPuk2" msgid="4526033371987193070">"Πληκτρολογήστε τον κωδικό PUK2 για την κατάργηση αποκλεισμού της κάρτας SIM."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Εισερχόμενη αναγνώριση κλήσης"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Εξερχόμενη αναγνώριση κλήσης"</string>
<string name="CfMmi" msgid="5123218989141573515">"Προώθηση κλήσεων"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Αύξηση"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Μείωση"</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_scroll_mode" msgid="3073101067441638428">"Πατήστε παρατεταμένα το <xliff:g id="VALUE">%s</xliff:g>."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Πραγματοποιήστε κύλιση προς τα πάνω για αύξηση και προς τα κάτω για μείωση."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Αύξηση λεπτού"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Μείωση λεπτού"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Αύξηση ώρας"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Μείωση ώρας"</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="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="6324978841467899081">"Επόμενος μήνας"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Προηγούμενος μήνας"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Επόμενη ημέρα"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Προηγούμενη μέρα"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Αύξηση έτους"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Προηγούμενο έτος"</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="checkbox_checked" msgid="7222044992652711167">"ελέγχθηκε"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"δεν επιλέχθηκε"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"επιλεγμένο"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"Κύλιση πάνω <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Κύλιση κάτω για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Κύλιση αριστερά για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Κύλιση δεξιά <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Ξεκλείδωμα"</string>
<string name="description_target_camera" msgid="969071997552486814">"Φωτογραφική μηχανή"</string>
<string name="description_target_silent" msgid="893551287746522182">"Αθόρυβο"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index b070e02..c41f2be 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Type a PUK that is 8 numbers or longer."</string>
<string name="needPuk" msgid="919668385956251611">"Your SIM card is PUK-locked. Type the PUK code to unlock it."</string>
<string name="needPuk2" msgid="4526033371987193070">"Type PUK2 to unblock SIM card."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Incoming Caller ID"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Outgoing Caller ID"</string>
<string name="CfMmi" msgid="5123218989141573515">"Call forwarding"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Increment"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Decrement"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> touch and hold."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Slide up to increment and down to decrease."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Increment minute"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Decrement minute"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Increment hour"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Decrement hour"</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="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>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Increment month"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Decrement month"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Increment day"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Decrement day"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Increment year"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Decrement year"</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="checkbox_checked" msgid="7222044992652711167">"ticked"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"not ticked"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"selected"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"Up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Down for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Left for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Right for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Unlock"</string>
<string name="description_target_camera" msgid="969071997552486814">"Camera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Silent"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 8de6b8c0..19e8e25 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Ingresa un código PUK de ocho números o más."</string>
<string name="needPuk" msgid="919668385956251611">"Tu tarjeta SIM está bloqueada con PUK. Escribe el código PUK para desbloquearla."</string>
<string name="needPuk2" msgid="4526033371987193070">"Escribir PUK2 para desbloquear la tarjeta SIM."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Identificador de llamadas entrantes"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Identificador de llamadas salientes"</string>
<string name="CfMmi" msgid="5123218989141573515">"Desvío de llamadas"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Incremento"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Decremento"</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_scroll_mode" msgid="3073101067441638428">"Mantén presionado <xliff:g id="VALUE">%s</xliff:g>."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Deslízate hacia arriba para aumentar y hacia abajo para disminuir."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Aumentar minutos"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Disminuir minutos"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Aumentar horas"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Disminuir horas"</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="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>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Aumentar mes"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Disminuir mes"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Aumentar día"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Disminuir día"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Aumentar año"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Disminuir año"</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="checkbox_checked" msgid="7222044992652711167">"marcado"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"no marcado"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"seleccionado"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"Hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Hacia abajo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Hacia la izquierda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Hacia la derecha para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</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_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>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index b76053f..c732ab9 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Escribe un código PUK de ocho caracteres o más."</string>
<string name="needPuk" msgid="919668385956251611">"La tarjeta SIM está bloqueada con el código PUK. Introduce el código PUK para desbloquearla."</string>
<string name="needPuk2" msgid="4526033371987193070">"Introduce el código PUK2 para desbloquear la tarjeta SIM."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"ID de emisor de llamada entrante"</string>
<string name="ClirMmi" msgid="7784673673446833091">"ID de emisor de llamada saliente"</string>
<string name="CfMmi" msgid="5123218989141573515">"Desvío de llamada"</string>
@@ -1021,6 +1019,8 @@
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Establecer hora"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Establecer fecha"</string>
<string name="date_time_set" msgid="5777075614321087758">"Establecer"</string>
+ <!-- no translation found for date_time_done (2507683751759308828) -->
+ <skip />
<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 es necesario ningún permiso"</string>
@@ -1170,22 +1170,35 @@
<string name="add_account_label" msgid="2935267344849993553">"Añadir una cuenta"</string>
<string name="choose_account_text" msgid="6303348737197849675">"¿Qué cuenta quieres usar?"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"Añadir cuenta"</string>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Aumentar"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Disminuir"</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_scroll_mode" msgid="3073101067441638428">"Mantén pulsado <xliff:g id="VALUE">%s</xliff:g>."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Desliza el dedo hacia arriba para aumentar y hacia abajo para disminuir."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Aumentar minuto"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Disminuir minuto"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Aumentar hora"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Disminuir hora"</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="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>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Aumentar mes"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Disminuir mes"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Aumentar día"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Disminuir día"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Aumentar año"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Disminuir año"</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="checkbox_checked" msgid="7222044992652711167">"seleccionado"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"no seleccionado"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"seleccionado"</string>
@@ -1205,10 +1218,14 @@
<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 pulsado el icono de desbloqueo y deslízalo."</string>
- <string name="description_direction_up" msgid="1983114130441878529">"Hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Hacia abajo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Hacia la izquierda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Hacia la derecha para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</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_target_unlock" msgid="2228524900439801453">"Desbloquear"</string>
<string name="description_target_camera" msgid="969071997552486814">"Cámara"</string>
<string name="description_target_silent" msgid="893551287746522182">"Silencio"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 38c9251..890dd7b 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Sisestage 8- või enamanumbriline PUK-kood."</string>
<string name="needPuk" msgid="919668385956251611">"SIM-kaart on PUK-lukustatud. Avamiseks sisestage PUK-kood."</string>
<string name="needPuk2" msgid="4526033371987193070">"Sisestage SIM-kaardi blokeeringu tühistamiseks PUK2-kood."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Sissetuleva kõne helistaja ID"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Väljuva kõne helistaja ID"</string>
<string name="CfMmi" msgid="5123218989141573515">"Kõnede suunamine"</string>
@@ -1021,6 +1019,8 @@
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Kellaaja määramine"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Kuupäeva määramine"</string>
<string name="date_time_set" msgid="5777075614321087758">"Määra"</string>
+ <!-- no translation found for date_time_done (2507683751759308828) -->
+ <skip />
<string name="default_permission_group" msgid="2690160991405646128">"Vaikimisi"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"UUS: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Lube pole vaja"</string>
@@ -1170,22 +1170,35 @@
<string name="add_account_label" msgid="2935267344849993553">"Konto lisamine"</string>
<string name="choose_account_text" msgid="6303348737197849675">"Millist kontot soovite kasutada?"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"Lisa konto"</string>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Suurenda"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Vähenda"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> puudutage ja hoidke."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Suurendamiseks lohistage üles, vähendamiseks alla."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Minutite arvu suurendamine"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Minutite arvu vähendamine"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Tundide arvu suurendamine"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Tundide arvu vähendamine"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"PM-i seadmine"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"AM-i seadmine"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Järgmine kuu"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Eelmine kuu"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Järgmine päev"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Eelmine päev"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Aastaarvu suurendamine"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Aastaarvu vähendamine"</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="checkbox_checked" msgid="7222044992652711167">"märgitud"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"pole märgitud"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"valitud"</string>
@@ -1205,10 +1218,14 @@
<string name="shareactionprovider_share_with" msgid="806688056141131819">"Jaga:"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Jaga rakendusega <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"Libistamispide. Puudutage ja hoidke all."</string>
- <string name="description_direction_up" msgid="1983114130441878529">"Üles – <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Alla – <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Vasakule – <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Paremale – <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Luku avamine"</string>
<string name="description_target_camera" msgid="969071997552486814">"Kaamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Hääletu"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 5a50a8f..ce26f1e 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"یک PUK با 8 رقم یا بیشتر تایپ کنید."</string>
<string name="needPuk" msgid="919668385956251611">"سیم کارت شما با PUK قفل شده است. کد PUK را برای بازگشایی آن بنویسید."</string>
<string name="needPuk2" msgid="4526033371987193070">"PUK2 را برای بازگشایی قفل سیم کارت بنویسید."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"شناسه تماس گیرنده ورودی"</string>
<string name="ClirMmi" msgid="7784673673446833091">"شناسه تماس گیرنده خروجی"</string>
<string name="CfMmi" msgid="5123218989141573515">"هدایت تماس"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"افزایش"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"کاهش"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> لمس کرده و نگه دارید."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"برای افزایش به بالا و برای کاهش به پایین بلغزانید."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">" افزایش دقیقه"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"کاهش دقیقه"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"افزایش ساعت"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"کاهش ساعت"</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="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="6324978841467899081">"ماه افزایشی"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"کاهش ماه"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"افزایش روز"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"کاهش روز"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"افزایش سال"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"کاهش سال"</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="checkbox_checked" msgid="7222044992652711167">"علامت زده"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"بدون علامت"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"انتخاب شد"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"بالا برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"پایین برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"چپ برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"راست برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"بازکردن قفل"</string>
<string name="description_target_camera" msgid="969071997552486814">"دوربین"</string>
<string name="description_target_silent" msgid="893551287746522182">"ساکت"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 6d849dd..54e1a1b 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Kirjoita vähintään 8 numeron pituinen PUK-koodi."</string>
<string name="needPuk" msgid="919668385956251611">"SIM-korttisi on PUK-lukittu. Poista lukitus antamalla PUK-koodi."</string>
<string name="needPuk2" msgid="4526033371987193070">"Pura SIM-kortin esto antamalla PUK2-koodi."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI-koodi"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Soittajan tunnus"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Soittajan tunnus"</string>
<string name="CfMmi" msgid="5123218989141573515">"Soitonsiirto"</string>
@@ -1021,6 +1019,8 @@
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Aseta aika"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Aseta päivämäärä"</string>
<string name="date_time_set" msgid="5777075614321087758">"Aseta"</string>
+ <!-- no translation found for date_time_done (2507683751759308828) -->
+ <skip />
<string name="default_permission_group" msgid="2690160991405646128">"Oletus"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"UUTTA: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Lupia ei tarvita"</string>
@@ -1170,22 +1170,35 @@
<string name="add_account_label" msgid="2935267344849993553">"Lisää tili"</string>
<string name="choose_account_text" msgid="6303348737197849675">"Mitä tiliä haluat käyttää?"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"Lisää tili"</string>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Lisää"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Vähennä"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> kosketa pitkään."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Kasvata tai pienennä arvoa liu\'uttamalla ylös tai alas."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Kasvata minuuttia"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Pienennä minuuttia"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Kasvata tuntia"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Pienennä tuntia"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Aseta ip"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Aseta ap"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Kasvata kuukautta"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Vähennä kuukautta"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Kasvata päivää"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Pienennä päivää"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Kasvata vuotta"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Pienennä vuotta"</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="checkbox_checked" msgid="7222044992652711167">"valittu"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"ei valittu"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"valittu"</string>
@@ -1205,10 +1218,14 @@
<string name="shareactionprovider_share_with" msgid="806688056141131819">"Jaa seuraavien kanssa:"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Jaa sovelluksessa <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"Liukuva valitsin. Kosketa pitkään."</string>
- <string name="description_direction_up" msgid="1983114130441878529">"Ylös: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Alas: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Vasemmalle: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Oikealle: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Poista lukitus"</string>
<string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Äänetön"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 548d66b..d4a6f5b 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Saisissez un code PUK comportant au moins huit chiffres."</string>
<string name="needPuk" msgid="919668385956251611">"Votre carte SIM est verrouillée par clé PUK. Saisissez la clé PUK pour la déverrouiller."</string>
<string name="needPuk2" msgid="4526033371987193070">"Saisissez la clé PUK2 pour débloquer la carte SIM."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"Code IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"Code MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Numéro de l\'appelant (entrant)"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Numéro de l\'appelant (sortant)"</string>
<string name="CfMmi" msgid="5123218989141573515">"Transfert d\'appel"</string>
@@ -1021,6 +1019,8 @@
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Définir l\'heure"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Définir la date"</string>
<string name="date_time_set" msgid="5777075614321087758">"Définir"</string>
+ <!-- no translation found for date_time_done (2507683751759308828) -->
+ <skip />
<string name="default_permission_group" msgid="2690160991405646128">"Par défaut"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOUVEAU"</font>" :"</string>
<string name="no_permissions" msgid="7283357728219338112">"Aucune autorisation requise"</string>
@@ -1170,22 +1170,35 @@
<string name="add_account_label" msgid="2935267344849993553">"Ajouter un compte"</string>
<string name="choose_account_text" msgid="6303348737197849675">"Quel compte souhaitez-vous utiliser ?"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"Ajouter un compte"</string>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Augmenter"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Diminuer"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> appuyez de manière prolongée."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Faire glisser vers le haut pour augmenter et vers le bas pour diminuer"</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Minute suivante"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Minute précédente"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Heure suivante"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Heure précédente"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Définir la valeur PM"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Définir la valeur AM"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Mois suivant"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Mois précédent"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Jour suivant"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Jour précédent"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Année suivante"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Année précédente"</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="checkbox_checked" msgid="7222044992652711167">"coché"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"non coché"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"sélectionné"</string>
@@ -1205,10 +1218,14 @@
<string name="shareactionprovider_share_with" msgid="806688056141131819">"Partager avec"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Partager avec <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"Poignée coulissante. Appuyez de manière prolongée."</string>
- <string name="description_direction_up" msgid="1983114130441878529">"Vers le haut pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Vers le bas pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Vers la gauche pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Vers la droite pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</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_target_unlock" msgid="2228524900439801453">"Déverrouiller"</string>
<string name="description_target_camera" msgid="969071997552486814">"Appareil photo"</string>
<string name="description_target_silent" msgid="893551287746522182">"Mode silencieux"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index be85378..d84915e 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"ऐसा PUK लिखें जो 8 अंकों या अधिक का हो."</string>
<string name="needPuk" msgid="919668385956251611">"आपका सिम कार्ड PUK लॉक किया गया है. इसे अनलॉक करने के लिए PUK कोड लिखें."</string>
<string name="needPuk2" msgid="4526033371987193070">"सिम कार्ड अनब्लॉक करने के लिए PUK2 लिखें."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"इनकमिंग कॉलर ID"</string>
<string name="ClirMmi" msgid="7784673673446833091">"आउटगोइंग कॉलर ID"</string>
<string name="CfMmi" msgid="5123218989141573515">"कॉल अग्रेषण"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"वृद्धि"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"कमी"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> को स्पर्श करके रखें."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"बढ़ते क्रम के लिए ऊपर और घटते क्रम के लिए नीचे की ओर स्लाइड करें."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"बढ़ते क्रम में मिनट"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"घटते क्रम में मिनट"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"बढ़ते क्रम में घंटा"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"घटते क्रम में घंटा"</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="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="6324978841467899081">"बढ़ते क्रम में माह"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"घटते क्रम में माह"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"बढ़ते क्रम में दिन"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"घटते क्रम में दिन"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"बढ़ते क्रम में वर्ष"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"घटते क्रम में वर्ष"</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="checkbox_checked" msgid="7222044992652711167">"चेक किया गया"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"चेक नहीं किया गया"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"चयनित"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए ऊपर."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए नीचे."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए बाएं."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए दाएं."</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_target_unlock" msgid="2228524900439801453">"अनलॉक करें"</string>
<string name="description_target_camera" msgid="969071997552486814">"कैमरा"</string>
<string name="description_target_silent" msgid="893551287746522182">"मौन"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index a30a5e0..b0ebc8a 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Upišite PUK koji se sastoji od barem 8 brojeva."</string>
<string name="needPuk" msgid="919668385956251611">"Vaša je SIM kartica zaključana PUK-om. Unesite PUK kôd da biste je otključali."</string>
<string name="needPuk2" msgid="4526033371987193070">"Unesite PUK2 da biste odblokirali SIM karticu."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"ID dolaznog pozivatelja"</string>
<string name="ClirMmi" msgid="7784673673446833091">"ID izlaznog pozivatelja"</string>
<string name="CfMmi" msgid="5123218989141573515">"Preusmjeravanje poziva"</string>
@@ -1021,6 +1019,8 @@
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Postavljanje vremena"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Postavi datum"</string>
<string name="date_time_set" msgid="5777075614321087758">"Postavi"</string>
+ <!-- no translation found for date_time_done (2507683751759308828) -->
+ <skip />
<string name="default_permission_group" msgid="2690160991405646128">"Zadano"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVO: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Nije potrebno dopuštenje"</string>
@@ -1170,22 +1170,35 @@
<string name="add_account_label" msgid="2935267344849993553">"Dodajte račun"</string>
<string name="choose_account_text" msgid="6303348737197849675">"Koji račun želite upotrijebiti?"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"Dodaj račun"</string>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Povećaj"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Smanji"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> pritisnite i držite."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Klizite prema gore za pomak unaprijed, a prema dolje za pomak unatrag."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Pomak unaprijed za jednu minutu"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Pomak unatrag za jednu minutu"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Pomak unaprijed za jedan sat"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Pomak unatrag za jedan sat"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Postavi PM"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Postavi AM"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Pomak unaprijed za jedan mjesec"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Pomak unatrag za jedan mjesec"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Pomak unaprijed za jedan dan"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Pomak unatrag za jedan dan"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Pomak unaprijed za jednu godinu"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Pomak unatrag za jednu godinu"</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="checkbox_checked" msgid="7222044992652711167">"označeno"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"nije označeno"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"odabran"</string>
@@ -1205,10 +1218,14 @@
<string name="shareactionprovider_share_with" msgid="806688056141131819">"Dijeljenje sa"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Dijeli s aplikacijom <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"Klizna ručka. Dodirnite i držite."</string>
- <string name="description_direction_up" msgid="1983114130441878529">"Gore za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Dolje za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Lijevo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Desno za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Otključaj"</string>
<string name="description_target_camera" msgid="969071997552486814">"Fotoaparat"</string>
<string name="description_target_silent" msgid="893551287746522182">"Bešumno"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index f6fd651..5e3464d 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"8 számjegyű vagy hosszabb PUK kódot írjon be."</string>
<string name="needPuk" msgid="919668385956251611">"A SIM-kártya le van zárva a PUK-kóddal. A feloldáshoz adja meg a PUK-kódot."</string>
<string name="needPuk2" msgid="4526033371987193070">"A SIM-kártya feloldásához adja meg a PUK2-kódot."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Beérkező hívóazonosító"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Kimenő hívóazonosító"</string>
<string name="CfMmi" msgid="5123218989141573515">"Hívásátirányítás"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Növelés"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Csökkentés"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> érintse meg és tartsa lenyomva."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Csúsztassa fel a növeléshez és le a csökkentéshez."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Percek növelése"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Percek csökkentése"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Órák növelése"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Órák csökkentése"</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="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>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Hónapok növelése"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Hónapok csökkentése"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Napok növelése"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Napok csökkentése"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Évek növelése"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Évek csökkentése"</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="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>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"Fel: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Le: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Balra: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Jobbra: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</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_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>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 4a142083..4fb25c1 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Ketik PUK yang terdiri dari 8 angka atau lebih."</string>
<string name="needPuk" msgid="919668385956251611">"Kartu SIM Anda dikunci PUK. Ketikkan kode PUK untuk membukanya."</string>
<string name="needPuk2" msgid="4526033371987193070">"Ketikkan PUK2 untuk membuka kartu SIM"</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Nomor Penelepon Masuk"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Nomor Penelepon Keluar"</string>
<string name="CfMmi" msgid="5123218989141573515">"Penerusan panggilan"</string>
@@ -1021,6 +1019,8 @@
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Setel waktu"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Setel tanggal"</string>
<string name="date_time_set" msgid="5777075614321087758">"Setel"</string>
+ <!-- no translation found for date_time_done (2507683751759308828) -->
+ <skip />
<string name="default_permission_group" msgid="2690160991405646128">"Default"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"BARU: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Tidak perlu izin"</string>
@@ -1170,22 +1170,35 @@
<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="4830170763103463443">"Penambahan"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Pengurangan"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> sentuh dan tahan."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Geser ke atas untuk menambah dan ke bawah untuk mengurangi."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Menit penambahan"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Menit pengurangan"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Jam penambahan"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Jam pengurangan"</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="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="6324978841467899081">"Bulan penambahan"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Bulan pengurangan"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Hari penambahan"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Hari pengurangan"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Tahun penambahan"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Tahun pengurangan"</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="checkbox_checked" msgid="7222044992652711167">"dicentang"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"tidak diperiksa"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"dipilih"</string>
@@ -1205,10 +1218,14 @@
<string name="shareactionprovider_share_with" msgid="806688056141131819">"Berbagi dengan"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Berbagi dengan <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"Gagang geser. Sentuh & tahan."</string>
- <string name="description_direction_up" msgid="1983114130441878529">"Ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Ke bawah untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Ke kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Ke kanan untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Membuka gembok"</string>
<string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Senyap"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index c682a85..7f399be 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Digita un PUK formato da almeno 8 numeri."</string>
<string name="needPuk" msgid="919668385956251611">"La SIM è bloccata tramite PUK. Digita il codice PUK per sbloccarla."</string>
<string name="needPuk2" msgid="4526033371987193070">"Digita il PUK2 per sbloccare la SIM."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"ID chiamante in entrata"</string>
<string name="ClirMmi" msgid="7784673673446833091">"ID chiamante in uscita"</string>
<string name="CfMmi" msgid="5123218989141573515">"Deviazione chiamate"</string>
@@ -1021,6 +1019,8 @@
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Imposta ora"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Imposta data"</string>
<string name="date_time_set" msgid="5777075614321087758">"Imposta"</string>
+ <!-- no translation found for date_time_done (2507683751759308828) -->
+ <skip />
<string name="default_permission_group" msgid="2690160991405646128">"Predefinito"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NUOVA: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Nessuna autorizzazione richiesta"</string>
@@ -1170,22 +1170,35 @@
<string name="add_account_label" msgid="2935267344849993553">"Aggiungi un account"</string>
<string name="choose_account_text" msgid="6303348737197849675">"Quale account vuoi usare?"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"Aggiungi account"</string>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Aumenta"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Diminuisci"</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_scroll_mode" msgid="3073101067441638428">"Tocca e tieni premuto il numero <xliff:g id="VALUE">%s</xliff:g>."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Scorri verso l\'alto per aumentare il valore e verso il basso per diminuirlo."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Aumenta minuto"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Diminuisci minuto"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Aumenta ora"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Diminuisci ora"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Imposta PM"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Imposta AM"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Aumenta mese"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Diminuisci mese"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Aumenta giorno"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Diminuisci giorno"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Aumenta anno"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Diminuisci anno"</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="checkbox_checked" msgid="7222044992652711167">"selezionata"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"non selezionato"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"selezionato"</string>
@@ -1205,10 +1218,14 @@
<string name="shareactionprovider_share_with" msgid="806688056141131819">"Condividi con"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Condividi con <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"Maniglia scorrevole. Tocca e tieni premuto."</string>
- <string name="description_direction_up" msgid="1983114130441878529">"Su per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Giù per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"A sinistra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"A destra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Sblocca"</string>
<string name="description_target_camera" msgid="969071997552486814">"Fotocamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Silenzioso"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 9ebc58d..b03207d 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"הקלד PUK באורך 8 מספרים או יותר."</string>
<string name="needPuk" msgid="919668385956251611">"כרטיס ה-SIM נעול באמצעות PUK. הקלד את קוד PUK כדי לבטל את נעילתו."</string>
<string name="needPuk2" msgid="4526033371987193070">"הקלד PUK2 כדי לבטל את חסימת כרטיס ה-SIM."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"זיהוי מתקשר של שיחה נכנסת"</string>
<string name="ClirMmi" msgid="7784673673446833091">"זיהוי מתקשר בשיחה יוצאת"</string>
<string name="CfMmi" msgid="5123218989141573515">"העברת שיחות"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"הגדל"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"הפחת"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> גע והחזק."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"הסט מעלה כדי להוסיף ומטה כדי להפחית."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"הוסף דקה"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"הפחת דקה"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"הוסף שעה"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"הפחת שעה"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"הגדר PM"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"הגדר AM"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"הוסף חודש"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"הפחת חודש"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"הוסף יום"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"הפחת יום."</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"הוסף שנה"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"הפחת שנה"</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="checkbox_checked" msgid="7222044992652711167">"מסומן"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"לא מסומן"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"נבחר"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"\'למעלה\' עבור <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"\'למטה\' עבור <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"\'שמאל\' עבור <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"\'ימין\' עבור <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"בטל נעילה"</string>
<string name="description_target_camera" msgid="969071997552486814">"מצלמה"</string>
<string name="description_target_silent" msgid="893551287746522182">"שקט"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 9f70bb3..526535f 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"PUKは8桁以上で入力してください。"</string>
<string name="needPuk" msgid="919668385956251611">"SIMカードはPUKでロックされています。ロックを解除するにはPUKコードを入力してください。"</string>
<string name="needPuk2" msgid="4526033371987193070">"SIMカードのロック解除のためPUK2を入力します。"</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"着信時の発信者番号"</string>
<string name="ClirMmi" msgid="7784673673446833091">"発信者番号"</string>
<string name="CfMmi" msgid="5123218989141573515">"着信転送"</string>
@@ -1021,6 +1019,8 @@
<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="default_permission_group" msgid="2690160991405646128">"端末既定"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NEW: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"権限の許可は必要ありません"</string>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"増やす"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"減らす"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g>回タップして押し続けます。"</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"上にスライドで大きく、下にスライドで小さくなります。"</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"1分進める"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"1分戻す"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"1時間進める"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"1時間戻す"</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="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="6324978841467899081">"1か月進める"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"1か月戻す"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"1日進める"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"1日戻す"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"1年進める"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"1年戻す"</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="checkbox_checked" msgid="7222044992652711167">"ON"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"OFF"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"ON"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"上は<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>です。"</string>
- <string name="description_direction_down" msgid="4294993639091088240">"下は<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>です。"</string>
- <string name="description_direction_left" msgid="6814008463839915747">"左は<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>です。"</string>
- <string name="description_direction_right" msgid="4296057241963012862">"右は<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>です。"</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_target_unlock" msgid="2228524900439801453">"ロックを解除"</string>
<string name="description_target_camera" msgid="969071997552486814">"カメラ"</string>
<string name="description_target_silent" msgid="893551287746522182">"マナーモード"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 0057a5b..b38b988 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"8자리 이상의 숫자 PUK를 입력합니다."</string>
<string name="needPuk" msgid="919668385956251611">"SIM 카드의 PUK가 잠겨 있습니다. 잠금해제하려면 PUK 코드를 입력하세요."</string>
<string name="needPuk2" msgid="4526033371987193070">"SIM 카드 잠금을 해제하려면 PUK2를 입력하세요."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"발신자 번호"</string>
<string name="ClirMmi" msgid="7784673673446833091">"내 발신 번호"</string>
<string name="CfMmi" msgid="5123218989141573515">"착신전환"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"올리기"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"줄이기"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> 길게 터치하세요."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"올리려면 위로 슬라이드하고 줄이려면 아래로 슬라이드합니다."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"\'분\'을 올립니다."</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"\'분\'을 줄입니다."</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"\'시\'를 올립니다."</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"\'시\'를 줄입니다."</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"PM 설정"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"AM 설정"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"\'월\'을 올립니다."</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"\'월\'을 줄입니다."</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"\'날짜\'를 올립니다."</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"\'날짜\'를 줄입니다."</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"\'연도\'를 올립니다."</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"\'연도\'를 줄입니다."</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="checkbox_checked" msgid="7222044992652711167">"확인"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"선택 안함"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"선택됨"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 위로 슬라이드"</string>
- <string name="description_direction_down" msgid="4294993639091088240">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 아래로 슬라이드"</string>
- <string name="description_direction_left" msgid="6814008463839915747">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 왼쪽으로 슬라이드"</string>
- <string name="description_direction_right" msgid="4296057241963012862">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 오른쪽으로 슬라이드"</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_target_unlock" msgid="2228524900439801453">"잠금 해제"</string>
<string name="description_target_camera" msgid="969071997552486814">"카메라"</string>
<string name="description_target_silent" msgid="893551287746522182">"무음"</string>
diff --git a/core/res/res/values-land/arrays.xml b/core/res/res/values-land/arrays.xml
index 68e5cfd..537d27c 100644
--- a/core/res/res/values-land/arrays.xml
+++ b/core/res/res/values-land/arrays.xml
@@ -23,49 +23,49 @@
<array name="lockscreen_targets_when_silent">
<item>@null</item>"
<item>@drawable/ic_lockscreen_unlock</item>
- <item>@null</item>
+ <item>@drawable/ic_lockscreen_search</item>
<item>@drawable/ic_lockscreen_soundon</item>
</array>
<array name="lockscreen_target_descriptions_when_silent">
<item>@null</item>
<item>@string/description_target_unlock</item>
- <item>@null</item>
+ <item>@string/description_target_search</item>
<item>@string/description_target_soundon</item>
</array>
<array name="lockscreen_direction_descriptions">
<item>@null</item>
<item>@string/description_direction_up</item>
- <item>@null</item>
+ <item>@string/description_direction_left</item>
<item>@string/description_direction_down</item>
</array>
<array name="lockscreen_targets_when_soundon">
<item>@null</item>
<item>@drawable/ic_lockscreen_unlock</item>
- <item>@null</item>
+ <item>@drawable/ic_lockscreen_search</item>
<item>@drawable/ic_lockscreen_silent</item>
</array>
<array name="lockscreen_target_descriptions_when_soundon">
<item>@null</item>
<item>@string/description_target_unlock</item>
- <item>@null</item>
+ <item>@string/description_target_search</item>
<item>@string/description_target_silent</item>
</array>
<array name="lockscreen_targets_with_camera">
<item>@null</item>
<item>@drawable/ic_lockscreen_unlock</item>
- <item>@null</item>
+ <item>@drawable/ic_lockscreen_search</item>
<item>@drawable/ic_lockscreen_camera</item>
</array>
<array name="lockscreen_target_descriptions_with_camera">
<item>@null</item>
<item>@string/description_target_unlock</item>
- <item>@null</item>
+ <item>@string/description_target_search</item>
<item>@string/description_target_camera</item>
</array>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 8aeb170..4d67940 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Įveskite 8 skaitmenų ar ilgesnį PUK kodą."</string>
<string name="needPuk" msgid="919668385956251611">"Jūsų SIM kortelė yra užrakinta PUK kodu. Jei norite ją atrakinti, įveskite PUK kodą."</string>
<string name="needPuk2" msgid="4526033371987193070">"Įveskite PUK2 kodą, kad panaikintumėte SIM kortelės blokavimą."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Įeinančio skambintojo ID"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Išeinančio skambintojo ID"</string>
<string name="CfMmi" msgid="5123218989141573515">"Skambučio peradresavimas"</string>
@@ -1021,6 +1019,8 @@
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Nustatyti laiką"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Nustatyti datą"</string>
<string name="date_time_set" msgid="5777075614321087758">"Nustatyti"</string>
+ <!-- no translation found for date_time_done (2507683751759308828) -->
+ <skip />
<string name="default_permission_group" msgid="2690160991405646128">"Numatytasis"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NAUJAS: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Nereikia leidimų"</string>
@@ -1170,22 +1170,35 @@
<string name="add_account_label" msgid="2935267344849993553">"Pridėti paskyrą"</string>
<string name="choose_account_text" msgid="6303348737197849675">"Kurią paskyrą norite naudoti?"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"Pridėti paskyrą"</string>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Padidinti"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Sumažinti"</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_scroll_mode" msgid="3073101067441638428">"Palieskite <xliff:g id="VALUE">%s</xliff:g> ir laikykite."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Slinkite aukštyn, kad būtų parodytas padidėjimas, ir žemyn, kad būtų parodytas sumažėjimas."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Padidėjimo minutė"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Sumažėjimo minutė"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Padidėjimo valanda"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Sumažėjimo valanda"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Nustatyti po pusiaudienio"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Nustatyti prieš pusiaudienį"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Padidėjimo mėnuo"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Sumažėjimo mėnuo"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Padidėjimo diena"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Sumažėjimo diena"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Padidėjimo metai"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Sumažėjimo metai"</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="checkbox_checked" msgid="7222044992652711167">"pažymėtas"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"nepatikrinta"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"pasirinkta"</string>
@@ -1205,10 +1218,14 @@
<string name="shareactionprovider_share_with" msgid="806688056141131819">"Bendrinti su"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Bendrinti su „<xliff:g id="APPLICATION_NAME">%s</xliff:g>“"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"Slydimo valdymas. Palieskite ir laikykite."</string>
- <string name="description_direction_up" msgid="1983114130441878529">"Aukštyn į <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Žemyn į <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Kairėn į <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Dešinėn į <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Atrakinti"</string>
<string name="description_target_camera" msgid="969071997552486814">"Vaizdo kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Begarsis"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index f434e09..12a0e58 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Ierakstiet PUK kodu, kas sastāv no 8 vai vairāk cipariem."</string>
<string name="needPuk" msgid="919668385956251611">"SIM karte ir bloķēta ar PUK kodu. Ierakstiet PUK kodu, lai to atbloķētu."</string>
<string name="needPuk2" msgid="4526033371987193070">"Ierakstiet PUK2 kodu, lai atbloķētu SIM karti."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Ienākošā zvana zvanītāja ID"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Izejošā zvana zvanītāja ID"</string>
<string name="CfMmi" msgid="5123218989141573515">"Zvanu pāradresācija"</string>
@@ -1021,6 +1019,8 @@
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Laika iestatīšana"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Datuma iestatīšana"</string>
<string name="date_time_set" msgid="5777075614321087758">"Iestatīt"</string>
+ <!-- no translation found for date_time_done (2507683751759308828) -->
+ <skip />
<string name="default_permission_group" msgid="2690160991405646128">"Noklusējums"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"JAUNA: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Atļaujas nav nepieciešamas."</string>
@@ -1170,22 +1170,35 @@
<string name="add_account_label" msgid="2935267344849993553">"Pievienot kontu"</string>
<string name="choose_account_text" msgid="6303348737197849675">"Kuru kontu vēlaties izmantot?"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"Pievienot kontu"</string>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Palielināt"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Samazināt"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g>: pieskarieties un turiet nospiestu."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Bīdiet uz augšu, lai palielinātu vērtību, un uz leju, lai to samazinātu."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Palielināt minūtes vērtību"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Samazināt minūtes vērtību"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Palielināt stundas vērtību"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Samazināt stundas vērtību"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Iestatīt pēcpusdienas laiku"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Iestatīt priekšpusdienas laiku"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Palielināt mēneša vērtību"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Samazināt mēneša vērtību"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Palielināt datuma vērtību"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Samazināt datuma vērtību"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Palielināt gada vērtību"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Samazināt gada vērtību"</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="checkbox_checked" msgid="7222044992652711167">"atzīmēta"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"nav atzīmēta"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"atlasīta"</string>
@@ -1205,10 +1218,14 @@
<string name="shareactionprovider_share_with" msgid="806688056141131819">"Kopīgot ar:"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Kopīgot ar lietojumprogrammu <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"Bīdāms turis. Pieskarieties tam un turiet to nospiestu."</string>
- <string name="description_direction_up" msgid="1983114130441878529">"Bīdiet uz augšu, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Bīdiet uz leju, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Bīdiet pa kreisi, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Bīdiet pa labi, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Atbloķēt"</string>
<string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Klusums"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index a2dd90c..f725896 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Taipkan PUK yang mempunyai 8 nombor atau lebih panjang."</string>
<string name="needPuk" msgid="919668385956251611">"Kad SIM anda dikunci PUK. Taipkan kod PUK untuk membuka kuncinya."</string>
<string name="needPuk2" msgid="4526033371987193070">"Taipkan PUK2 untuk menyahsekat kad SIM."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"ID Pemanggil Masuk"</string>
<string name="ClirMmi" msgid="7784673673446833091">"ID Pemanggil Keluar"</string>
<string name="CfMmi" msgid="5123218989141573515">"Pemajuan panggilan"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Kenaikan"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Penyusutan"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> sentuh terus."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Luncurkan ke atas untuk kenaikan dan ke bawah untuk penyusutan."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Minit kenaikan"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Minit penyusutan"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Jam kenaikan"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Jam penyusutan"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Tetapkan PM"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Tetapkan AM"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Bulan kenaikan"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Bulan penyusutan"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Hari kenaikan"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Hari penyusutan"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Tahun kenaikan"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Tahun penyusutan"</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="checkbox_checked" msgid="7222044992652711167">"ditandakan"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"tidak ditandakan"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"dipilih"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"Atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Bawah untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Kanan untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_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>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index b3ea39ff..8bc9dab 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Skriv inn en PUK-kode på åtte tall eller mer."</string>
<string name="needPuk" msgid="919668385956251611">"SIM-kortet ditt er PUK-låst. Skriv inn PUK-koden for å låse det opp."</string>
<string name="needPuk2" msgid="4526033371987193070">"Skriv inn PUK2 for å låse opp SIM-kortet."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Inngående nummervisning"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Utgående nummervisning"</string>
<string name="CfMmi" msgid="5123218989141573515">"Viderekobling"</string>
@@ -1021,6 +1019,8 @@
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Stille klokken"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Angi dato"</string>
<string name="date_time_set" msgid="5777075614321087758">"Lagre"</string>
+ <!-- no translation found for date_time_done (2507683751759308828) -->
+ <skip />
<string name="default_permission_group" msgid="2690160991405646128">"Standard"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NYTT: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Trenger ingen rettigheter"</string>
@@ -1170,22 +1170,35 @@
<string name="add_account_label" msgid="2935267344849993553">"Legg til en konto"</string>
<string name="choose_account_text" msgid="6303348737197849675">"Hvilken konto vil du bruke?"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"Legg til konto"</string>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Øke"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Senke"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> – trykk og hold inne."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Skyv opp for å øke og ned for å redusere."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Endre minutter (fremover)"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Endre minutter (bakover)"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Endre timer (fremover)"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Endre time (bakover)"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Angi p.m."</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Angi a.m."</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Endre måned (fremover)"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Endre måned (bakover)"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Endre dag (fremover)"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Endre dag (bakover)"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Endre år (fremover)"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Endre år (bakover)"</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="checkbox_checked" msgid="7222044992652711167">"valgt"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"ikke valgt"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"valgt"</string>
@@ -1205,10 +1218,14 @@
<string name="shareactionprovider_share_with" msgid="806688056141131819">"Del med"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Del med <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"Glidebryter. Trykk og hold inne."</string>
- <string name="description_direction_up" msgid="1983114130441878529">"Opp for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Ned for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Venstre for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Høyre for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Lås opp"</string>
<string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Stille"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 5698f03..61f08e0 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Typ een PUK-code die 8 cijfers of langer is."</string>
<string name="needPuk" msgid="919668385956251611">"Uw SIM-kaart is vergrendeld met de PUK-code. Typ de PUK-code om te ontgrendelen."</string>
<string name="needPuk2" msgid="4526033371987193070">"Voer de PUK2-code in om de SIM-kaart te ontgrendelen."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Inkomende beller-id"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Uitgaande beller-id"</string>
<string name="CfMmi" msgid="5123218989141573515">"Oproep doorschakelen"</string>
@@ -1021,6 +1019,8 @@
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Tijd instellen"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Datum instellen"</string>
<string name="date_time_set" msgid="5777075614321087758">"Instellen"</string>
+ <!-- no translation found for date_time_done (2507683751759308828) -->
+ <skip />
<string name="default_permission_group" msgid="2690160991405646128">"Standaard"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NIEUW: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Geen machtigingen vereist"</string>
@@ -1170,22 +1170,35 @@
<string name="add_account_label" msgid="2935267344849993553">"Een account toevoegen"</string>
<string name="choose_account_text" msgid="6303348737197849675">"Welk account wilt u gebruiken?"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"Account toevoegen"</string>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Hoger"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Lager"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> blijven aanraken."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Schuif omhoog om te verhogen en omlaag om te verlagen."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Minuten verhogen"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Minuten verlagen"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Uren verhogen"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Uren verlagen"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"PM instellen"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"AM instellen"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Maand verhogen"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Maand verlagen"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Dag verhogen"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Dag verlagen"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Jaar verhogen"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Jaar verlagen"</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="checkbox_checked" msgid="7222044992652711167">"aangevinkt"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"niet aangevinkt"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"geselecteerd"</string>
@@ -1205,10 +1218,14 @@
<string name="shareactionprovider_share_with" msgid="806688056141131819">"Delen met"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Delen met <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"Schuifgreep. Tikken en blijven aanraken."</string>
- <string name="description_direction_up" msgid="1983114130441878529">"Omhoog voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Omlaag voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Links voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Rechts voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Ontgrendelen"</string>
<string name="description_target_camera" msgid="969071997552486814">"Camera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Stil"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index da2f78d..77f8adc 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Wpisz kod PUK składający się z co najmniej 8 cyfr."</string>
<string name="needPuk" msgid="919668385956251611">"Karta SIM jest zablokowana kodem PUK. Wprowadź kod PUK, aby odblokować kartę."</string>
<string name="needPuk2" msgid="4526033371987193070">"Wprowadź kod PUK2, aby odblokować kartę SIM."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Identyfikator rozmówcy przy połączeniach przychodzących"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Identyfikator rozmówcy przy połączeniach wychodzących"</string>
<string name="CfMmi" msgid="5123218989141573515">"Przekazywanie połączeń"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Zwiększ"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Zmniejsz"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> dotknij i przytrzymaj."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Przesuń w górę, aby zwiększyć wartość, lub w dół, aby ją zmniejszyć."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Następna minuta"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Poprzednia minuta"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Następna godzina"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Poprzednia godzina"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Ustaw PM"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Ustaw AM"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Następny miesiąc"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Poprzedni miesiąc"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Następny dzień"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Poprzedni dzień"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Następny rok"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Poprzedni rok"</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="checkbox_checked" msgid="7222044992652711167">"zaznaczono"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"nie zaznaczono"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"wybrano"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>: w górę"</string>
- <string name="description_direction_down" msgid="4294993639091088240">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>: w dół"</string>
- <string name="description_direction_left" msgid="6814008463839915747">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>: w lewo"</string>
- <string name="description_direction_right" msgid="4296057241963012862">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>: w prawo"</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_target_unlock" msgid="2228524900439801453">"Odblokuj"</string>
<string name="description_target_camera" msgid="969071997552486814">"Aparat"</string>
<string name="description_target_silent" msgid="893551287746522182">"Wyciszenie"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index ec43491..2a3e2b9 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Introduza um PUK que tenha 8 ou mais algarismos."</string>
<string name="needPuk" msgid="919668385956251611">"O seu cartão SIM está bloqueado com PUK. Introduza o código PUK para desbloqueá-lo."</string>
<string name="needPuk2" msgid="4526033371987193070">"Introduza o PUK2 para desbloquear o cartão SIM."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"ID do Autor da Chamada"</string>
<string name="ClirMmi" msgid="7784673673446833091">"ID do autor da chamada efetuada"</string>
<string name="CfMmi" msgid="5123218989141573515">"Encaminhamento de chamadas"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Aumentar"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Diminuir"</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_scroll_mode" msgid="3073101067441638428">"Toque sem soltar em <xliff:g id="VALUE">%s</xliff:g>."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Deslize lentamente para cima para aumentar e para baixo para diminuir."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Aumentar minuto"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Diminuir minuto"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Aumentar hora"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Diminuir hora"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Definir PM"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Definir AM"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Aumentar mês"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Diminuir mês"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Aumentar dia"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Diminuir dia"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Aumentar ano"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Diminuir ano"</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="checkbox_checked" msgid="7222044992652711167">"marcado"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"desmarcado"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"selecionado"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"Para cima para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Para baixo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Para a esquerda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Para a direita para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_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>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 53e2a96..88b7a57 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Digite um PUK com oito números ou mais."</string>
<string name="needPuk" msgid="919668385956251611">"O seu cartão SIM está bloqueado por um PUK. Digite o código PUK para desbloqueá-lo."</string>
<string name="needPuk2" msgid="4526033371987193070">"Digite o PUK2 para desbloquear o cartão SIM."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"ID do chamador de entrada"</string>
<string name="ClirMmi" msgid="7784673673446833091">"ID do chamador de saída"</string>
<string name="CfMmi" msgid="5123218989141573515">"Encaminhamento de chamada"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Incremento"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Redução"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> toque e mantenha pressionado."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Deslize para cima para aumentar e para baixo para diminuir."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Aumentar minuto"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Diminuir minuto"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Aumentar hora"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Diminuir hora"</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="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>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Aumentar mês"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Diminuir mês"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Aumentar dia"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Reduzir dia"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Aumentar ano"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Diminuir ano"</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="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>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"Deslize para cima para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Deslize para baixo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Deslize para a esquerda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Deslize para a direita para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_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>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 5f0561b..75c5c7e 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -1509,6 +1509,8 @@
<!-- no translation found for date_picker_dialog_title (5879450659453782278) -->
<skip />
<string name="date_time_set" msgid="5777075614321087758">"Definir"</string>
+ <!-- no translation found for date_time_done (2507683751759308828) -->
+ <skip />
<string name="default_permission_group" msgid="2690160991405646128">"Standard"</string>
<!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
<skip />
@@ -1746,37 +1748,37 @@
<skip />
<!-- no translation found for add_account_button_label (3611982894853435874) -->
<skip />
- <!-- no translation found for number_picker_increment_button (4830170763103463443) -->
+ <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
<skip />
- <!-- no translation found for number_picker_decrement_button (2576606679160067262) -->
+ <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
<skip />
<!-- no translation found for number_picker_increment_scroll_mode (3073101067441638428) -->
<skip />
- <!-- no translation found for number_picker_increment_scroll_action (4628981789985093179) -->
+ <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
<skip />
- <!-- no translation found for time_picker_increment_minute_button (2843066823236250329) -->
+ <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
<skip />
- <!-- no translation found for time_picker_decrement_minute_button (4357907223628449595) -->
+ <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
<skip />
- <!-- no translation found for time_picker_increment_hour_button (2484204991937119057) -->
+ <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
<skip />
- <!-- no translation found for time_picker_decrement_hour_button (4659353501775842780) -->
+ <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
<skip />
<!-- no translation found for time_picker_increment_set_pm_button (4147590696151230863) -->
<skip />
<!-- no translation found for time_picker_decrement_set_am_button (8302140353539486752) -->
<skip />
- <!-- no translation found for date_picker_increment_month_button (6324978841467899081) -->
+ <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
<skip />
- <!-- no translation found for date_picker_decrement_month_button (7304349355000398077) -->
+ <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
<skip />
- <!-- no translation found for date_picker_increment_day_button (4397040141921413183) -->
+ <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
<skip />
- <!-- no translation found for date_picker_decrement_day_button (2427816793443629131) -->
+ <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
<skip />
- <!-- no translation found for date_picker_increment_year_button (3058553394722295105) -->
+ <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
<skip />
- <!-- no translation found for date_picker_decrement_year_button (5193062846559743823) -->
+ <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
<skip />
<!-- no translation found for checkbox_checked (7222044992652711167) -->
<skip />
@@ -1816,13 +1818,13 @@
<skip />
<!-- no translation found for content_description_sliding_handle (415975056159262248) -->
<skip />
- <!-- no translation found for description_direction_up (1983114130441878529) -->
+ <!-- no translation found for description_direction_up (7169032478259485180) -->
<skip />
- <!-- no translation found for description_direction_down (4294993639091088240) -->
+ <!-- no translation found for description_direction_down (5087739728639014595) -->
<skip />
- <!-- no translation found for description_direction_left (6814008463839915747) -->
+ <!-- no translation found for description_direction_left (7207478719805562165) -->
<skip />
- <!-- no translation found for description_direction_right (4296057241963012862) -->
+ <!-- no translation found for description_direction_right (8034433242579600980) -->
<skip />
<!-- no translation found for description_target_unlock (2228524900439801453) -->
<skip />
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 11199b0..5409290 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Introduceţi un cod PUK care să aibă 8 cifre sau mai mult."</string>
<string name="needPuk" msgid="919668385956251611">"Cardul SIM este blocat cu codul PUK. Introduceţi codul PUK pentru a-l debloca."</string>
<string name="needPuk2" msgid="4526033371987193070">"Introduceţi codul PUK2 pentru a debloca cardul SIM."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"ID apelant de primire"</string>
<string name="ClirMmi" msgid="7784673673446833091">"ID apelant"</string>
<string name="CfMmi" msgid="5123218989141573515">"Redirecţionarea apelurilor"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Incrementaţi"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Decrementaţi"</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_scroll_mode" msgid="3073101067441638428">"Atingeţi şi ţineţi apăsat <xliff:g id="VALUE">%s</xliff:g>."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Glisaţi în sus pentru incrementare şi în jos pentru decrementare."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Incrementaţi valoarea pentru minut"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Decrementaţi valoarea pentru minut"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Incrementaţi valoarea pentru oră"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Decrementaţi valoarea pentru oră"</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="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>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Incrementaţi valoarea pentru lună"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Decrementaţi valoarea pentru lună"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Incrementaţi valoarea pentru zi"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Decrementaţi valoarea pentru zi"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Incrementaţi valoarea pentru an"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Decrementaţi valoarea pentru an"</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="checkbox_checked" msgid="7222044992652711167">"bifată"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"nebifată"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"selectat"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"În sus pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"În jos pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"La stânga pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"La dreapta pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_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>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index d4adfb4..9d8e4a6 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Введите PUK-код из 8 или более цифр."</string>
<string name="needPuk" msgid="919668385956251611">"SIM-карта заблокирована с помощью кода PUK. Для разблокировки введите код PUK."</string>
<string name="needPuk2" msgid="4526033371987193070">"Для разблокировки SIM-карты введите PUK2."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Идентификация вызывающего абонента"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Идентификация звонящего абонента"</string>
<string name="CfMmi" msgid="5123218989141573515">"Переадресация вызова"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Увеличить"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Уменьшить"</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_scroll_mode" msgid="3073101067441638428">"Нажмите и удерживайте <xliff:g id="VALUE">%s</xliff:g>."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Проведите вверх, чтобы увеличить значение, и вниз, чтобы уменьшить его."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"На минуту вперед"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"На минуту назад"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"На час вперед"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"На час назад"</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="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="6324978841467899081">"На месяц вперед"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"На месяц назад"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"На день вперед"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"На день назад"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"На год вперед"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"На год назад"</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="checkbox_checked" msgid="7222044992652711167">"установлено"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"не установлено"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"выбрано"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"Проведите вверх, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Проведите вниз, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Проведите влево, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Проведите вправо, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Разблокировать"</string>
<string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
<string name="description_target_silent" msgid="893551287746522182">"Без звука"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index bad739f9..ca80f6b 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Zadajte kód PUK, ktorý má 8 alebo viac čísel."</string>
<string name="needPuk" msgid="919668385956251611">"Karta SIM je uzamknutá pomocou kódu PUK. Odomknite ju zadaním kódu PUK."</string>
<string name="needPuk2" msgid="4526033371987193070">"Ak chcete odblokovať kartu SIM, zadajte kód PUK2."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Prichádzajúca identifikácia volajúceho"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Odchádzajúca identifikácia volajúceho"</string>
<string name="CfMmi" msgid="5123218989141573515">"Presmerovanie hovorov"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Zvýšenie"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Zníženie"</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_scroll_mode" msgid="3073101067441638428">"Dotknite sa a podržte <xliff:g id="VALUE">%s</xliff:g>."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Ak chcete pripočítať, potiahnite prst nahor. Ak chcete odpočítať, potiahnite prst nadol."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Pripočítať minútu"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Odpočítať minútu"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Pripočítať hodinu"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Odpočítať hodinu"</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="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>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Pripočítať mesiac"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Odpočítať mesiac"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Pripočítať deň"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Odpočítať deň"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Pripočítať rok"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Odpočítať rok"</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="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>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"Nahor na <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Nadol na <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Doľava na <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Doprava na <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_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>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 767305c..e664d9c 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Vnesite 8- ali več mestni PUK."</string>
<string name="needPuk" msgid="919668385956251611">"Kartica SIM je zaklenjena s kodo PUK. Če jo želite odkleniti, vnesite kodo PUK."</string>
<string name="needPuk2" msgid="4526033371987193070">"Če želite odstraniti blokiranje kartice SIM, vnesite PUK2."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"ID dohodnega klicatelja"</string>
<string name="ClirMmi" msgid="7784673673446833091">"ID odhodnega klicatelja"</string>
<string name="CfMmi" msgid="5123218989141573515">"Preusmerjanje klicev"</string>
@@ -430,7 +428,7 @@
<string name="permlab_readPhoneState" msgid="2326172951448691631">"branje stanja in identitete telefona"</string>
<string name="permdesc_readPhoneState" msgid="5127767618743602782">"Programu omogoča dostop do funkcij telefona v napravi. Program lahko s tem dovoljenjem določi telefonsko številko in serijsko številko tega telefona, določi lahko tudi, ali je klic aktiven, številko, s katero je klic povezan, in podobno."</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"preprečitev prehoda tabličnega računalnika v stanje pripravljenosti"</string>
- <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"preprečevanje prehod v stanje pripravljenosti telefona"</string>
+ <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"preprečevanje prehoda v stanje pripravljenosti telefona"</string>
<string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Omogoča, da program prepreči prehod tabličnega računalnika v stanje pripravljenosti."</string>
<string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Programu omogoča, da v telefonu prepreči prehod v stanje pripravljenosti."</string>
<string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"vklop ali izklop tabličnega računalnika"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Povečaj"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Zmanjšaj"</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_scroll_mode" msgid="3073101067441638428">"Dotaknite se vrednosti <xliff:g id="VALUE">%s</xliff:g> in jo pridržite."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Povlecite gor za povečanje in dol za zmanjšanje."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Povečaj minute"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Zmanjšaj minute"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Povečaj uro"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Zmanjšaj uro"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Nastavi PM"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Nastavi AM"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Naslednji mesec"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Prejšnji mesec"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Naslednji dan"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Prejšnji dan"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Naslednje leto"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Prejšnje leto"</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="checkbox_checked" msgid="7222044992652711167">"potrjeno"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"ni odkljukano"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"izbrano"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"Gor za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Dol za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Levo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Desno za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Odkleni"</string>
<string name="description_target_camera" msgid="969071997552486814">"Fotoaparat"</string>
<string name="description_target_silent" msgid="893551287746522182">"Tiho"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index d03abd7..4a3839b 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Унесите PUK који се састоји од 8 цифара или више."</string>
<string name="needPuk" msgid="919668385956251611">"SIM картица је закључана PUK кодом. Унесите PUK кôд да бисте је откључали."</string>
<string name="needPuk2" msgid="4526033371987193070">"Унесите PUK2 да бисте деблокирали SIM картицу."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Долазни ИД позиваоца"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Одлазни ИД позиваоца"</string>
<string name="CfMmi" msgid="5123218989141573515">"Преусмеравање позива"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Повећање"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Смањење"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> додирните и задржите."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Превуците нагоре за повећање, а надоле за смањење."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Повећај минуте"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Смањи минуте"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Повећај сате"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Смањи сате"</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="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="6324978841467899081">"Повећај месеце"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Смањи месеце"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Повећај дане"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Смањи дане"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Повећај године"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Смањи године"</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="checkbox_checked" msgid="7222044992652711167">"изабрано"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"није потврђено"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"изабрано"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"Нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Надоле за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Улево за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Удесно за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Откључај"</string>
<string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
<string name="description_target_silent" msgid="893551287746522182">"Нечујно"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index ddaa30a..7ba32ce 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Ange en PUK-kod med minst 8 siffror."</string>
<string name="needPuk" msgid="919668385956251611">"Ditt SIM-kort är PUK-låst. Ange PUK-koden om du vill låsa upp det."</string>
<string name="needPuk2" msgid="4526033371987193070">"Ange PUK2-koden för att häva spärren av SIM-kortet."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI-kod"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Nummerpresentatör för inkommande samtal"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Nummerpresentatör för utgående samtal"</string>
<string name="CfMmi" msgid="5123218989141573515">"Vidarebefordra samtal"</string>
@@ -1021,6 +1019,8 @@
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Ange tid"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Ange datum"</string>
<string name="date_time_set" msgid="5777075614321087758">"Ställ in"</string>
+ <!-- no translation found for date_time_done (2507683751759308828) -->
+ <skip />
<string name="default_permission_group" msgid="2690160991405646128">"Standardinställning"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NY: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Inga behörigheter krävs"</string>
@@ -1170,22 +1170,35 @@
<string name="add_account_label" msgid="2935267344849993553">"Lägg till ett konto"</string>
<string name="choose_account_text" msgid="6303348737197849675">"Vilket konto vill du använda?"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"Lägg till konto"</string>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Öka"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Minska"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> tryck länge."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Skjut uppåt för att öka och nedåt för att minska."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Öka minuter"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Minska minuter"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Öka timmar"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Minska timmar"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Ange em"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Ange fm"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Öka månad"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Minska månad"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Öka dagar"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Minska dag"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Öka år"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Minska år"</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="checkbox_checked" msgid="7222044992652711167">"markerat"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"inte markerat"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"markerade"</string>
@@ -1205,10 +1218,14 @@
<string name="shareactionprovider_share_with" msgid="806688056141131819">"Dela med"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Dela med <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"Skärmlåsfunktion. Tryck och dra."</string>
- <string name="description_direction_up" msgid="1983114130441878529">"Upp för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Ned för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Vänster för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Höger för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Lås upp"</string>
<string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Tyst"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 0424964..1744095 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Andika PUK ambayo ina urefu wa nambari 8 au zaidi."</string>
<string name="needPuk" msgid="919668385956251611">"Kadi yako ya SIM imefungwa na PUK. Anika msimbo wa PUK ili kuifungua."</string>
<string name="needPuk2" msgid="4526033371987193070">"Chapisha PUK2 ili kufungua SIM kadi."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Kitambulisho cha Mpigaji wa Simu Inayoingia"</string>
<string name="ClirMmi" msgid="7784673673446833091">"ID ya Mpigaji simu Inayotoka nje"</string>
<string name="CfMmi" msgid="5123218989141573515">"Kusambaza simu"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Ongezeko"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Punguza"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> gusa na ushikilie."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Nyiririsha juu kuongeza na chini kupunguza."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Dakika ya nyongeza"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Dakika pungufu"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Saa ya nyongeza"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Saa pungufu."</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Seti PM"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Seti AM"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Mwezi wa nyongeza"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Mwezi pungufu"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Siku ya nyongeza"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Siku pungufu"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Mwaka wa nyongeza"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Mwaka pungufu"</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="checkbox_checked" msgid="7222044992652711167">"imeangaliwa"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"haijakaguliwa"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"Iliyochaguliwa"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"Juu ajili ya<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Chini kwa ajili ya<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Kushoto kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Kulia kwa ajili ya <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</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_target_unlock" msgid="2228524900439801453">"Fungua"</string>
<string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Kimya"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 7197f90..32281b5 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"พิมพ์รหัส PUK ซึ่งต้องเป็นตัวเลขอย่างน้อย 8 หลัก"</string>
<string name="needPuk" msgid="919668385956251611">"ซิมการ์ดของคุณถูกล็อกด้วย PUK พิมพ์รหัส PUK เพื่อปลดล็อก"</string>
<string name="needPuk2" msgid="4526033371987193070">"พิมพ์ PUK2 เพื่อยกเลิกการปิดกั้นซิมการ์ด"</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"หมายเลขผู้โทรเข้า"</string>
<string name="ClirMmi" msgid="7784673673446833091">"หมายเลขผู้โทรออก"</string>
<string name="CfMmi" msgid="5123218989141573515">"การโอนสาย"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"การเพิ่ม"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"การลด"</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_scroll_mode" msgid="3073101067441638428">"แตะ <xliff:g id="VALUE">%s</xliff:g> ค้างไว้"</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"เลื่อนขึ้นเพื่อเพิ่มและเลื่อนลงเพื่อลด"</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"เพิ่มนาที"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"ลดนาที"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"เพิ่มชั่วโมง"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"ลดชั่วโมง"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"ตั้งค่า PM"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"ตั้งค่า AM"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"เพิ่มเดือน"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"ลดเดือน"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"เพิ่มวัน"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"ลดวัน"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"เพิ่มปี"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"ลดปี"</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="checkbox_checked" msgid="7222044992652711167">"เลือกไว้"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"ไม่ได้ตรวจสอบ"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"เลือกแล้ว"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"เลื่อนขึ้นเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
- <string name="description_direction_down" msgid="4294993639091088240">"เลื่อนลงเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
- <string name="description_direction_left" msgid="6814008463839915747">"เลื่อนไปทางซ้ายเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
- <string name="description_direction_right" msgid="4296057241963012862">"เลื่อนไปทางขวาเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</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_target_unlock" msgid="2228524900439801453">"ปลดล็อก"</string>
<string name="description_target_camera" msgid="969071997552486814">"กล้องถ่ายรูป"</string>
<string name="description_target_silent" msgid="893551287746522182">"ปิดเสียง"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index ff2e7ea..fd88fc1 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Mag-type ng PUK na may 8 numbero o mas mahaba."</string>
<string name="needPuk" msgid="919668385956251611">"Na-PUK-lock ang iyong SIM card. I-type ang PUK code upang i-unlock ito."</string>
<string name="needPuk2" msgid="4526033371987193070">"I-type ang PUK2 upang i-unblock ang SIM card."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Papasok na Caller ID"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Papalabas na Caller ID"</string>
<string name="CfMmi" msgid="5123218989141573515">"Pagpapasa ng tawag"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Taasan"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Babaan"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> pindutin nang matagal."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"I-slide pataas upang magdagdag at pababa upang magbawas."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Minuto ng pagdaragdag"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Minuto ng pagbawas"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Oras ng pagdaragdag"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Oras ng pagbawas"</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="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>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Buwan ng pagdagdag"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Buwan ng pagbawas"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Araw ng pagdaragdag"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Araw ng pagbawas"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Taon ng pagdaragdag"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Taon ng pagbawas"</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="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>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"Nakataas para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Nakababa para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Pakaliwa para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Pakanan para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_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>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index c450761..251e47c 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"8 veya daha uzun basamaklı bir PUK kodu yazın."</string>
<string name="needPuk" msgid="919668385956251611">"SIM kartınızın PUK kilidi devrede. Kilidi açmak için PUK kodunu yazın."</string>
<string name="needPuk2" msgid="4526033371987193070">"Engellenen SIM kartı açmak için PUK2 kodunu yazın."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Gelen Çağrı Kimliği"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Giden Çağrı Kimliği"</string>
<string name="CfMmi" msgid="5123218989141573515">"Çağrı yönlendirme"</string>
@@ -1021,6 +1019,8 @@
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Saati ayarla"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Tarihi ayarla"</string>
<string name="date_time_set" msgid="5777075614321087758">"Ayarla"</string>
+ <!-- no translation found for date_time_done (2507683751759308828) -->
+ <skip />
<string name="default_permission_group" msgid="2690160991405646128">"Varsayılan"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"YENİ: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"İzin gerektirmez"</string>
@@ -1170,22 +1170,35 @@
<string name="add_account_label" msgid="2935267344849993553">"Hesap ekleyin"</string>
<string name="choose_account_text" msgid="6303348737197849675">"Hangi hesabı kullanmak istiyorsunuz?"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"Hesap ekle"</string>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Artır"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Azalt"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> rakamına dokunun ve basılı tutun."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Artırmak için yukarı, azaltmak için aşağı kaydırın."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Dakika değerini artır"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Dakika değerini azalt"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Saat değerini artır"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Saat değerini azalt"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"ÖS değerini ayarla"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"ÖÖ değerini ayarla"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Ay değerini artır"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Ay değerini azalt"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Gün değerini artır"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Gün değerini azalt"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Yıl değerini artır"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Yıl değerini azalt"</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="checkbox_checked" msgid="7222044992652711167">"işaretli"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"işaretlenmedi"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"seçili"</string>
@@ -1205,10 +1218,14 @@
<string name="shareactionprovider_share_with" msgid="806688056141131819">"Şununla paylaş:"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> ile paylaş"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"Kayan tutma yeri. Dokunun ve basılı tutun."</string>
- <string name="description_direction_up" msgid="1983114130441878529">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için yukarı."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için aşağı."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için sola."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için sağa."</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_target_unlock" msgid="2228524900439801453">"Kilidi aç"</string>
<string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Sessiz"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 2afb95f..9054295 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Введіть PUK-код із 8 або більше цифр."</string>
<string name="needPuk" msgid="919668385956251611">"SIM-карта заблок. PUK-кодом. Введіть PUK-код, щоб її розблок."</string>
<string name="needPuk2" msgid="4526033371987193070">"Введ. PUK2, щоб розбл. SIM-карту."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Вхідн. ід. абонента"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Вихід. ід. абонента"</string>
<string name="CfMmi" msgid="5123218989141573515">"Переадрес. виклику"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Додати"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Відняти"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> – торкніться й утримуйте."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Перемістіть угору, щоб додати, і вниз, щоб відняти."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Додати хвилину"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Відняти хвилину"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Додати годину"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Відняти годину"</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="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="6324978841467899081">"Додати місяць"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Відняти місяць"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Додати день"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Відняти день"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Додати рік"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Відняти рік"</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="checkbox_checked" msgid="7222044992652711167">"перевірено"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"не перевірено"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"вибрано"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"Угору, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Униз, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Ліворуч, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Праворуч, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Розблокувати"</string>
<string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
<string name="description_target_silent" msgid="893551287746522182">"Без звуку"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 329917e..609452d 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Nhập PUK có từ 8 số trở lên."</string>
<string name="needPuk" msgid="919668385956251611">"Thẻ SIM của bạn đã bị khóa PUK. Nhập mã PUK để mở khóa thẻ SIM đó."</string>
<string name="needPuk2" msgid="4526033371987193070">"Nhập mã PUK2 để bỏ chặn thẻ SIM."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"Số gọi đến"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Số gọi đi"</string>
<string name="CfMmi" msgid="5123218989141573515">"Chuyển tiếp cuộc gọi"</string>
@@ -1021,6 +1019,8 @@
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Đặt giờ"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Đặt ngày"</string>
<string name="date_time_set" msgid="5777075614321087758">"Đặt"</string>
+ <!-- no translation found for date_time_done (2507683751759308828) -->
+ <skip />
<string name="default_permission_group" msgid="2690160991405646128">"Mặc định"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"MỚI: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Không yêu cầu quyền"</string>
@@ -1170,22 +1170,35 @@
<string name="add_account_label" msgid="2935267344849993553">"Thêm tài khoản"</string>
<string name="choose_account_text" msgid="6303348737197849675">"Bạn muốn sử dụng tài khoản nào?"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"Thêm tài khoản"</string>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Tăng dần"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Giảm dần"</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_scroll_mode" msgid="3073101067441638428">"Chạm và giữ <xliff:g id="VALUE">%s</xliff:g>."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Trượt lên để tăng và trượt xuống để giảm."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Phút tăng dần"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Phút giảm dần"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Giờ tăng dần"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Giờ giảm dần."</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Đặt CH"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Đặt SA"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Tháng tăng dần"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Tháng giảm dần"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Ngày tăng dần"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Ngày giảm dần"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Năm tăng dần"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Năm giảm dần."</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="checkbox_checked" msgid="7222044992652711167">"đã kiểm tra"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"chưa chọn"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"đã chọn"</string>
@@ -1205,10 +1218,14 @@
<string name="shareactionprovider_share_with" msgid="806688056141131819">"Chia sẻ với"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Chia sẻ với <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"Tay trượt. Chạm & giữ."</string>
- <string name="description_direction_up" msgid="1983114130441878529">"Lên để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Xuống để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Sang trái để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Sang phải để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Mở khóa"</string>
<string name="description_target_camera" msgid="969071997552486814">"Máy ảnh"</string>
<string name="description_target_silent" msgid="893551287746522182">"Im lặng"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index d6ed9a9..5a9cadc 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"请键入至少 8 位数字的 PUK 码。"</string>
<string name="needPuk" msgid="919668385956251611">"已对 SIM 卡进行 PUK 码锁定。键入 PUK 码将其解锁。"</string>
<string name="needPuk2" msgid="4526033371987193070">"输入 PUK2 码以解锁 SIM 卡。"</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"来电显示"</string>
<string name="ClirMmi" msgid="7784673673446833091">"本机号码"</string>
<string name="CfMmi" msgid="5123218989141573515">"来电转接"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"增加"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"减少"</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_scroll_mode" msgid="3073101067441638428">"触摸 <xliff:g id="VALUE">%s</xliff:g> 次并按住。"</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"向上滑动可增加值,向下滑动可减少值。"</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"增加分钟数"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"减少分钟数"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"增加小时数"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"减少小时数"</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="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="6324978841467899081">"增加月份值"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"减少月份值"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"增加天数"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"减少天数"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"增加年数"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"减少年份值"</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="checkbox_checked" msgid="7222044992652711167">"已选中"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"未选中"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"已选择"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"向上滑动<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
- <string name="description_direction_down" msgid="4294993639091088240">"向下滑动<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
- <string name="description_direction_left" msgid="6814008463839915747">"向左滑动<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
- <string name="description_direction_right" msgid="4296057241963012862">"向右滑动<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</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_target_unlock" msgid="2228524900439801453">"解锁"</string>
<string name="description_target_camera" msgid="969071997552486814">"相机"</string>
<string name="description_target_silent" msgid="893551287746522182">"静音"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index bc9337b..aa8eda1 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"輸入 8 位數以上的 PUK。"</string>
<string name="needPuk" msgid="919668385956251611">"SIM 卡的 PUK 已鎖定。請輸入 PUK 碼解除鎖定。"</string>
<string name="needPuk2" msgid="4526033371987193070">"請輸入 PUK2 以解鎖 SIM 卡。"</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"來電顯示"</string>
<string name="ClirMmi" msgid="7784673673446833091">"本機號碼"</string>
<string name="CfMmi" msgid="5123218989141573515">"來電轉接"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"增加"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"減少"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> 輕觸並按住。"</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"向上滑動即可增加,向下滑動即可減少。"</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"增加分鐘數"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"減少分鐘數"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"增加時數"</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"減少時數"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"設定 PM 值"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"設定 AM 值"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"增加月份"</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"減少月份"</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"增加天數"</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"減少天數"</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"增加年份"</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"減少年份"</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="checkbox_checked" msgid="7222044992652711167">"已勾選"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"尚未勾選"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"已選取"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"向上滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
- <string name="description_direction_down" msgid="4294993639091088240">"向下滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
- <string name="description_direction_left" msgid="6814008463839915747">"向左滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
- <string name="description_direction_right" msgid="4296057241963012862">"向右滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</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_target_unlock" msgid="2228524900439801453">"解除鎖定"</string>
<string name="description_target_camera" msgid="969071997552486814">"相機"</string>
<string name="description_target_silent" msgid="893551287746522182">"靜音"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 6471965..200bbea 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -50,10 +50,8 @@
<string name="invalidPuk" msgid="8761456210898036513">"Thayipha i-PUK enezinombolo ezingu-8 noma ngaphezu."</string>
<string name="needPuk" msgid="919668385956251611">"Ikhadi lakho le-SIM livalwe nge-PUK. Thayipha ikhodi ye-PUK ukulivula."</string>
<string name="needPuk2" msgid="4526033371987193070">"Thayipha i-PUK2 ukuze uvule ikhadi le-SIM."</string>
- <!-- no translation found for imei (2625429890869005782) -->
- <skip />
- <!-- no translation found for meid (4841221237681254195) -->
- <skip />
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
<string name="ClipMmi" msgid="6952821216480289285">"I-ID Yocingo Olungenayo"</string>
<string name="ClirMmi" msgid="7784673673446833091">"I-ID Yomshayeli Ephumayo"</string>
<string name="CfMmi" msgid="5123218989141573515">"Ukudlulisa ikholi"</string>
@@ -1021,6 +1019,8 @@
<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="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>
@@ -1170,22 +1170,35 @@
<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>
- <string name="number_picker_increment_button" msgid="4830170763103463443">"Nciphisa"</string>
- <string name="number_picker_decrement_button" msgid="2576606679160067262">"Decrement"</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_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> thinta bese ucindezela."</string>
- <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Shishilizisa kwenyuke kuye ekwenyusweni kwehle kuye ekwehlisweni."</string>
- <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Iminithi wokwenyusa"</string>
- <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Iminithi yokwehlisa"</string>
- <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Ihora lokwenyusa."</string>
- <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Ihora lokwehlisa"</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="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Setha Ntambama"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Setha Ekuseni"</string>
- <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Inyanga yokwenyusa."</string>
- <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Inyanga yokwehlisa."</string>
- <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Usuku lokwenyusa."</string>
- <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Usuku lokwehlisa."</string>
- <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Unyaka wokwenyusa."</string>
- <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Unyaka wokwehlisa"</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="checkbox_checked" msgid="7222044992652711167">"kuhloliwe"</string>
<string name="checkbox_not_checked" msgid="5174639551134444056">"akuhloliwe"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"Okukhethiwe"</string>
@@ -1205,10 +1218,14 @@
<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>
- <string name="description_direction_up" msgid="1983114130441878529">"Phezulu kwe <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_down" msgid="4294993639091088240">"Ngaphansi kwe <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_left" msgid="6814008463839915747">"Kwesokunxeleee kwe <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="description_direction_right" msgid="4296057241963012862">"Ngakwesokudla kwe for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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_target_unlock" msgid="2228524900439801453">"Vula"</string>
<string name="description_target_camera" msgid="969071997552486814">"Ikhamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Thulile"</string>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index 90ddc4b..d05a31c 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -353,49 +353,49 @@
<!-- Resources for MultiWaveView in LockScreen -->
<array name="lockscreen_targets_when_silent">
<item>@drawable/ic_lockscreen_unlock</item>
- <item>@null</item>
+ <item>@drawable/ic_lockscreen_search</item>
<item>@drawable/ic_lockscreen_soundon</item>
<item>@null</item>
</array>
<array name="lockscreen_target_descriptions_when_silent">
<item>@string/description_target_unlock</item>
- <item>@null</item>
+ <item>@string/description_target_search</item>
<item>@string/description_target_soundon</item>
<item>@null</item>
</array>
<array name="lockscreen_direction_descriptions">
<item>@string/description_direction_right</item>
- <item>@null</item>
+ <item>@string/description_direction_up</item>
<item>@string/description_direction_left</item>
<item>@null</item>
</array>
<array name="lockscreen_targets_when_soundon">
<item>@drawable/ic_lockscreen_unlock</item>
- <item>@null</item>
+ <item>@drawable/ic_lockscreen_search</item>
<item>@drawable/ic_lockscreen_silent</item>
<item>@null</item>
</array>
<array name="lockscreen_target_descriptions_when_soundon">
<item>@string/description_target_unlock</item>
- <item>@null</item>
+ <item>@string/description_target_search</item>
<item>@string/description_target_silent</item>
<item>@null</item>
</array>
<array name="lockscreen_targets_with_camera">
<item>@drawable/ic_lockscreen_unlock</item>
- <item>@null</item>
+ <item>@drawable/ic_lockscreen_search</item>
<item>@drawable/ic_lockscreen_camera</item>
<item>@null</item>
</array>
<array name="lockscreen_target_descriptions_with_camera">
<item>@string/description_target_unlock</item>
- <item>@null</item>
+ <item>@string/description_target_search</item>
<item>@string/description_target_camera</item>
<item>@null</item>
</array>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 2b27585..aabe407 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2349,6 +2349,8 @@
<!-- Component name of an activity that allows the user to modify
the settings for this service. -->
<attr name="settingsActivity"/>
+ <!-- Set true when the spell checker supports sentence level spell checking. -->
+ <attr name="supportsSentenceSpellCheck" format="boolean" />
</declare-styleable>
<!-- This is the subtype of the spell checker. Subtype can describe locales (e.g. en_US, fr_FR...) -->
@@ -5552,4 +5554,21 @@
<attr name="settingsActivity" />
</declare-styleable>
+ <!-- Use <code>keyboard-layouts</code> as the root tag of the XML resource that
+ describes a collection of keyboard layouts provided by an application.
+ Each keyboard layout is declared by a <code>keyboard-layout</code> tag
+ with these attributes.
+
+ The XML resource that contains the keyboard layouts must be referenced from its
+ {@link android.hardware.input.InputManager#META_DATA_KEYBOARD_LAYOUTS}
+ meta-data entry used with broadcast receivers for
+ {@link android.hardware.input.InputManager#ACTION_QUERY_KEYBOARD_LAYOUTS}. -->
+ <declare-styleable name="KeyboardLayout">
+ <!-- The name of the keyboard layout, must be unique in the receiver. -->
+ <attr name="name" />
+ <!-- The display label of the keyboard layout. -->
+ <attr name="label" />
+ <!-- The key character map file resource. -->
+ <attr name="kcm" format="reference" />
+ </declare-styleable>
</resources>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 1649c48..d414c7f 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -740,6 +740,9 @@
<flag name="splitActionBarWhenNarrow" value="1" />
</attr>
+ <!-- The name of the logical parent of the activity as it appears in the manifest. -->
+ <attr name="parentActivityName" format="string" />
+
<!-- The <code>manifest</code> tag is the root of an
<code>AndroidManifest.xml</code> file,
describing the contents of an Android package (.apk) file. One
@@ -1348,6 +1351,7 @@
<attr name="immersive" />
<attr name="hardwareAccelerated" />
<attr name="uiOptions" />
+ <attr name="parentActivityName" />
</declare-styleable>
<!-- The <code>activity-alias</code> tag declares a new
@@ -1384,6 +1388,7 @@
component specific values). -->
<attr name="enabled" />
<attr name="exported" />
+ <attr name="parentActivityName" />
</declare-styleable>
<!-- The <code>meta-data</code> tag is used to attach additional
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 6d6b86b..0442be8 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -32,11 +32,9 @@
<dimen name="toast_y_offset">64dip</dimen>
<!-- Height of the status bar -->
<dimen name="status_bar_height">25dip</dimen>
- <!-- Height of the system bar (combined status + navigation, used on large screens) -->
- <dimen name="system_bar_height">48dip</dimen>
- <!-- Height of the horizontal navigation bar on devices that require it -->
+ <!-- Height of the bottom navigation / system bar. -->
<dimen name="navigation_bar_height">48dp</dimen>
- <!-- Width of the vertical navigation bar on devices that require it -->
+ <!-- Width of the navigation bar when it is placed vertically on the screen -->
<dimen name="navigation_bar_width">42dp</dimen>
<!-- Height of notification icons in the status bar -->
<dimen name="status_bar_icon_size">24dip</dimen>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 7341c6c..ca0e913 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -202,6 +202,7 @@
<java-symbol type="id" name="action2" />
<java-symbol type="id" name="big_picture" />
<java-symbol type="id" name="big_text" />
+ <java-symbol type="id" name="chronometer" />
<java-symbol type="attr" name="actionModeShareDrawable" />
<java-symbol type="attr" name="alertDialogCenterButtons" />
@@ -991,6 +992,7 @@
<java-symbol type="drawable" name="ic_lockscreen_camera" />
<java-symbol type="drawable" name="ic_lockscreen_silent" />
<java-symbol type="drawable" name="ic_lockscreen_unlock" />
+ <java-symbol type="drawable" name="ic_lockscreen_search" />
<java-symbol type="layout" name="action_bar_home" />
<java-symbol type="layout" name="action_bar_title_item" />
@@ -1079,6 +1081,8 @@
<java-symbol type="layout" name="notification_intruder_content" />
<java-symbol type="layout" name="notification_template_base" />
<java-symbol type="layout" name="notification_template_big_picture" />
+ <java-symbol type="layout" name="notification_template_part_time" />
+ <java-symbol type="layout" name="notification_template_part_chronometer" />
<java-symbol type="anim" name="slide_in_child_bottom" />
<java-symbol type="anim" name="slide_in_right" />
@@ -1125,6 +1129,14 @@
<!-- From android.policy -->
<java-symbol type="anim" name="app_starting_exit" />
<java-symbol type="anim" name="lock_screen_behind_enter" />
+ <java-symbol type="anim" name="dock_top_enter" />
+ <java-symbol type="anim" name="dock_top_exit" />
+ <java-symbol type="anim" name="dock_bottom_enter" />
+ <java-symbol type="anim" name="dock_bottom_exit" />
+ <java-symbol type="anim" name="dock_left_enter" />
+ <java-symbol type="anim" name="dock_left_exit" />
+ <java-symbol type="anim" name="dock_right_enter" />
+ <java-symbol type="anim" name="dock_right_exit" />
<java-symbol type="array" name="config_keyboardTapVibePattern" />
<java-symbol type="array" name="config_longPressVibePattern" />
<java-symbol type="array" name="config_safeModeDisabledVibePattern" />
@@ -1150,7 +1162,6 @@
<java-symbol type="dimen" name="navigation_bar_height" />
<java-symbol type="dimen" name="navigation_bar_width" />
<java-symbol type="dimen" name="status_bar_height" />
- <java-symbol type="dimen" name="system_bar_height" />
<java-symbol type="drawable" name="ic_jog_dial_sound_off" />
<java-symbol type="drawable" name="ic_jog_dial_sound_on" />
<java-symbol type="drawable" name="ic_jog_dial_unlock" />
@@ -3563,5 +3574,9 @@
<public type="attr" name="layout_marginStart"/>
<public type="attr" name="layout_marginEnd"/>
+ <public type="attr" name="kcm"/>
+ <public type="attr" name="parentActivityName" />
+
+ <public type="attr" name="supportsSentenceSpellCheck" />
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 718de0a..44f2ade 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3303,6 +3303,8 @@
<string name="description_target_silent">Silent</string>
<!-- Description of the sound on target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
<string name="description_target_soundon">Sound on</string>
+ <!-- Description of the unlock target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+ <string name="description_target_search">Search</string>
<!-- Description of the unlock handle in the Slide unlock screen for tablets. [CHAR LIMIT=NONE] -->
<string name="description_target_unlock_tablet">Swipe to unlock.</string>
diff --git a/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java b/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
index ea94fa9..58269a8 100644
--- a/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
+++ b/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
@@ -16,6 +16,7 @@
package com.android.internal.net;
+import static android.net.NetworkStats.SET_ALL;
import static android.net.NetworkStats.SET_DEFAULT;
import static android.net.NetworkStats.SET_FOREGROUND;
import static android.net.NetworkStats.TAG_NONE;
@@ -84,12 +85,12 @@
final NetworkStats stats = mFactory.readNetworkStatsSummary();
assertEquals(6, stats.size());
- assertStatsEntry(stats, "lo", UID_ALL, SET_DEFAULT, TAG_NONE, 8308L, 8308L);
- assertStatsEntry(stats, "rmnet0", UID_ALL, SET_DEFAULT, TAG_NONE, 1507570L, 489339L);
- assertStatsEntry(stats, "ifb0", UID_ALL, SET_DEFAULT, TAG_NONE, 52454L, 0L);
- assertStatsEntry(stats, "ifb1", UID_ALL, SET_DEFAULT, TAG_NONE, 52454L, 0L);
- assertStatsEntry(stats, "sit0", UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L);
- assertStatsEntry(stats, "ip6tnl0", UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L);
+ assertStatsEntry(stats, "lo", UID_ALL, SET_ALL, TAG_NONE, 8308L, 8308L);
+ assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 1507570L, 489339L);
+ assertStatsEntry(stats, "ifb0", UID_ALL, SET_ALL, TAG_NONE, 52454L, 0L);
+ assertStatsEntry(stats, "ifb1", UID_ALL, SET_ALL, TAG_NONE, 52454L, 0L);
+ assertStatsEntry(stats, "sit0", UID_ALL, SET_ALL, TAG_NONE, 0L, 0L);
+ assertStatsEntry(stats, "ip6tnl0", UID_ALL, SET_ALL, TAG_NONE, 0L, 0L);
}
public void testNetworkStatsSummaryDown() throws Exception {
@@ -102,8 +103,8 @@
final NetworkStats stats = mFactory.readNetworkStatsSummary();
assertEquals(7, stats.size());
- assertStatsEntry(stats, "rmnet0", UID_ALL, SET_DEFAULT, TAG_NONE, 1507570L, 489339L);
- assertStatsEntry(stats, "wlan0", UID_ALL, SET_DEFAULT, TAG_NONE, 1024L, 2048L);
+ assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 1507570L, 489339L);
+ assertStatsEntry(stats, "wlan0", UID_ALL, SET_ALL, TAG_NONE, 1024L, 2048L);
}
public void testNetworkStatsCombined() throws Exception {
@@ -115,7 +116,7 @@
stageLong(40L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/tx_packets"));
final NetworkStats stats = mFactory.readNetworkStatsSummary();
- assertStatsEntry(stats, "rmnet0", UID_ALL, SET_DEFAULT, TAG_NONE, 1507570L + 10L,
+ assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 1507570L + 10L,
2205L + 20L, 489339L + 30L, 2237L + 40L);
}
@@ -128,7 +129,7 @@
stageLong(40L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/tx_packets"));
final NetworkStats stats = mFactory.readNetworkStatsSummary();
- assertStatsEntry(stats, "rmnet0", UID_ALL, SET_DEFAULT, TAG_NONE, 10L, 20L, 30L, 40L);
+ assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 10L, 20L, 30L, 40L);
}
public void testKernelTags() throws Exception {
@@ -153,9 +154,9 @@
final NetworkStats stats = mFactory.readNetworkStatsSummary();
assertEquals(6, stats.size());
- assertStatsEntry(stats, "rmnet0", UID_ALL, SET_DEFAULT, TAG_NONE, 2112L, 24L, 700L, 10L);
- assertStatsEntry(stats, "test1", UID_ALL, SET_DEFAULT, TAG_NONE, 6L, 8L, 10L, 12L);
- assertStatsEntry(stats, "test2", UID_ALL, SET_DEFAULT, TAG_NONE, 1L, 2L, 3L, 4L);
+ assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 2112L, 24L, 700L, 10L);
+ assertStatsEntry(stats, "test1", UID_ALL, SET_ALL, TAG_NONE, 6L, 8L, 10L, 12L);
+ assertStatsEntry(stats, "test2", UID_ALL, SET_ALL, TAG_NONE, 1L, 2L, 3L, 4L);
}
/**
diff --git a/docs/html/guide/developing/testing/testing_otheride.jd b/docs/html/guide/developing/testing/testing_otheride.jd
index 93af979..7745ae7 100644
--- a/docs/html/guide/developing/testing/testing_otheride.jd
+++ b/docs/html/guide/developing/testing/testing_otheride.jd
@@ -209,7 +209,7 @@
<p>
To update a test project with the <code>android</code> tool, enter:
</p>
-<pre>android update-test-project -m <main_path> -p <test_path></pre>
+<pre>android update test-project -m <main_path> -p <test_path></pre>
<table>
<tr>
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index ba8dc5e..62d18ae 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -834,12 +834,6 @@
<li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/widget_design.html">
<span class="en">App Widget Design</span>
</a></li>
- <li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/activity_task_design.html">
- <span class="en">Activity and Task Design</span>
- </a></li>
- <li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/menu_design.html">
- <span class="en">Menu Design</span>
- </a></li>
</ul>
</li>
</ul>
diff --git a/docs/html/guide/practices/ui_guidelines/activity_task_design.jd b/docs/html/guide/practices/ui_guidelines/activity_task_design.jd
index f8ca3f8..8e4528e 100644
--- a/docs/html/guide/practices/ui_guidelines/activity_task_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/activity_task_design.jd
@@ -3,6 +3,43 @@
parent.link=index.html
@jd:body
+
+
+
+<div id="deprecatedSticker">
+ <a href="#"
+ onclick="$('#naMessage').show();$('#deprecatedSticker').hide();return false">
+ <strong>This doc is deprecated</strong></a>
+</div>
+
+
+<div id="naMessage" style="display:block">
+<div><p><strong>This document has been deprecated.</strong></p>
+ <p>For information about designing an activity structure and navigation, read the design guidelines
+for <a href="{@docRoot}design/patterns/app-structure.html">App Structure</a> and
+<a href="{@docRoot}design/patterns/navigation.html">Navigation</a>, or the developer guide
+about <a
+href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a>.</p>
+
+ <input style="margin-top:1em;padding:5px" type="button"
+ value="That's nice, but I still want to read this document"
+onclick="$('#naMessage').hide();$('#deprecatedSticker').show()" />
+</div>
+</div>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<div id="qv-wrapper">
<div id="qv">
diff --git a/docs/html/guide/practices/ui_guidelines/index.jd b/docs/html/guide/practices/ui_guidelines/index.jd
index 3255275..24fb855 100644
--- a/docs/html/guide/practices/ui_guidelines/index.jd
+++ b/docs/html/guide/practices/ui_guidelines/index.jd
@@ -39,26 +39,6 @@
design widgets that fit with others on the Home screen. They include links to
graphics files and templates that will make your designer's life easier.</dd>
</dl>
- <dl>
- <dt><a href="{@docRoot}guide/practices/ui_guidelines/activity_task_design.html">Activity and Task Design Guidelines</a> </dt>
- <dd>Activities are the basic, independent building blocks of applications.
- As you design your application's UI and feature set, you are free to
- re-use activities from other applications as if they were yours,
- to enrich and extend your application. These guidelines
- describe how activities work, illustrates them with examples, and
- describes important underlying principles and mechanisms, such as
- multitasking, activity reuse, intents, the activity stack, and
- tasks. It covers this all from a high-level design perspective.
-</dd>
- <dt><a href="{@docRoot}guide/practices/ui_guidelines/menu_design.html">Menu Design Guidelines</a> </dt>
- <dd>Android applications make use of Option menus and Context menus
- that enable users to perform operations and navigate to other parts
- of your application or to other applications. These guidelines describe
- the difference between Options anontext menus, how to arrange
- menu items, when to put commands on-screen, and other details about
- menu design.
-</dd>
-</dl>
diff --git a/docs/html/guide/practices/ui_guidelines/menu_design.jd b/docs/html/guide/practices/ui_guidelines/menu_design.jd
index 7576b6c..b4e2ea7 100644
--- a/docs/html/guide/practices/ui_guidelines/menu_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/menu_design.jd
@@ -2,7 +2,38 @@
parent.title=UI Guidelines
parent.link=index.html
@jd:body
+
+
+
+
+<div id="deprecatedSticker">
+ <a href="#"
+ onclick="$('#naMessage').show();$('#deprecatedSticker').hide();return false">
+ <strong>This doc is deprecated</strong></a>
+</div>
+
+
+<div id="naMessage" style="display:block">
+<div><p><strong>This document has been deprecated.</strong></p>
+ <p>For design guidelines about adding user actions and other options, read the design guidelines
+for <a href="{@docRoot}design/patterns/actionbar.html">Action Bar</a> or the developer guide about
+<a href="{@docRoot}guide/topics/ui/menus.html">Menus</a>.</p>
+
+ <input style="margin-top:1em;padding:5px" type="button"
+ value="That's nice, but I still want to read this document"
+onclick="$('#naMessage').hide();$('#deprecatedSticker').show()" />
+</div>
+</div>
+
+
+
+
+
+
+
+
+
<div id="qv-wrapper">
<div id="qv">
diff --git a/docs/html/resources/resources_toc.cs b/docs/html/resources/resources_toc.cs
index bbbe6fb1..5297c23 100644
--- a/docs/html/resources/resources_toc.cs
+++ b/docs/html/resources/resources_toc.cs
@@ -299,6 +299,31 @@
</li>
</ul>
</li>
+
+ <li class="toggle-list">
+ <div><a href="<?cs var:toroot ?>training/displaying-bitmaps/index.html">
+ <span class="en">Displaying Bitmaps Efficiently<span class="new"> new!</span></span>
+ </a>
+ </div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/displaying-bitmaps/load-bitmap.html">
+ <span class="en">Loading Large Bitmaps Efficiently</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/displaying-bitmaps/process-bitmap.html">
+ <span class="en">Processing Bitmaps Off the UI Thread</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/displaying-bitmaps/cache-bitmap.html">
+ <span class="en">Caching Bitmaps</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/displaying-bitmaps/display-bitmap.html">
+ <span class="en">Displaying Bitmaps in Your UI</span>
+ </a>
+ </li>
+ </ul>
+ </li>
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>training/accessibility/index.html">
diff --git a/docs/html/shareables/training/BitmapFun.zip b/docs/html/shareables/training/BitmapFun.zip
new file mode 100644
index 0000000..e7e71f9
--- /dev/null
+++ b/docs/html/shareables/training/BitmapFun.zip
Binary files differ
diff --git a/docs/html/sitemap.txt b/docs/html/sitemap.txt
index 958fe56..3f26dd0 100644
--- a/docs/html/sitemap.txt
+++ b/docs/html/sitemap.txt
@@ -160,8 +160,6 @@
http://developer.android.com/guide/practices/ui_guidelines/icon_design_dialog.html
http://developer.android.com/guide/practices/ui_guidelines/icon_design_list.html
http://developer.android.com/guide/practices/ui_guidelines/widget_design.html
-http://developer.android.com/guide/practices/ui_guidelines/activity_task_design.html
-http://developer.android.com/guide/practices/ui_guidelines/menu_design.html
http://developer.android.com/guide/practices/design/performance.html
http://developer.android.com/guide/practices/design/responsiveness.html
http://developer.android.com/guide/practices/design/seamlessness.html
diff --git a/docs/html/training/accessibility/index.jd b/docs/html/training/accessibility/index.jd
index d5178a9..333f9f2 100644
--- a/docs/html/training/accessibility/index.jd
+++ b/docs/html/training/accessibility/index.jd
@@ -13,7 +13,6 @@
<h2>Dependencies and prerequisites</h2>
<ul>
<li>Android 2.0 (API Level 5) or higher</li>
-Playback</a></li>
</ul>
<h2>You should also read</h2>
diff --git a/docs/html/training/displaying-bitmaps/cache-bitmap.jd b/docs/html/training/displaying-bitmaps/cache-bitmap.jd
new file mode 100644
index 0000000..94abe21
--- /dev/null
+++ b/docs/html/training/displaying-bitmaps/cache-bitmap.jd
@@ -0,0 +1,337 @@
+page.title=Caching Bitmaps
+parent.title=Displaying Bitmaps Efficiently
+parent.link=index.html
+
+trainingnavtop=true
+next.title=Displaying Bitmaps in Your UI
+next.link=display-bitmap.html
+previous.title=Processing Bitmaps Off the UI Thread
+previous.link=process-bitmap.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#memory-cache">Use a Memory Cache</a></li>
+ <li><a href="#disk-cache">Use a Disk Cache</a></li>
+ <li><a href="#config-changes">Handle Configuration Changes</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime Changes</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="{@docRoot}shareables/training/BitmapFun.zip" class="button">Download the sample</a>
+ <p class="filename">BitmapFun.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>Loading a single bitmap into your user interface (UI) is straightforward, however things get more
+complicated if you need to load a larger set of images at once. In many cases (such as with
+components like {@link android.widget.ListView}, {@link android.widget.GridView} or {@link
+android.support.v4.view.ViewPager }), the total number of images on-screen combined with images that
+might soon scroll onto the screen are essentially unlimited.</p>
+
+<p>Memory usage is kept down with components like this by recycling the child views as they move
+off-screen. The garbage collector also frees up your loaded bitmaps, assuming you don't keep any
+long lived references. This is all good and well, but in order to keep a fluid and fast-loading UI
+you want to avoid continually processing these images each time they come back on-screen. A memory
+and disk cache can often help here, allowing components to quickly reload processed images.</p>
+
+<p>This lesson walks you through using a memory and disk bitmap cache to improve the responsiveness
+and fluidity of your UI when loading multiple bitmaps.</p>
+
+<h2 id="memory-cache">Use a Memory Cache</h2>
+
+<p>A memory cache offers fast access to bitmaps at the cost of taking up valuable application
+memory. The {@link android.util.LruCache} class (also available in the <a
+href="{@docRoot}reference/android/support/v4/util/LruCache.html">Support Library</a> for use back
+to API Level 4) is particularly well suited to the task of caching bitmaps, keeping recently
+referenced objects in a strong referenced {@link java.util.LinkedHashMap} and evicting the least
+recently used member before the cache exceeds its designated size.</p>
+
+<p class="note"><strong>Note:</strong> In the past, a popular memory cache implementation was a
+{@link java.lang.ref.SoftReference} or {@link java.lang.ref.WeakReference} bitmap cache, however
+this is not recommended. Starting from Android 2.3 (API Level 9) the garbage collector is more
+aggressive with collecting soft/weak references which makes them fairly ineffective. In addition,
+prior to Android 3.0 (API Level 11), the backing data of a bitmap was stored in native memory which
+is not released in a predictable manner, potentially causing an application to briefly exceed its
+memory limits and crash.</p>
+
+<p>In order to choose a suitable size for a {@link android.util.LruCache}, a number of factors
+should be taken into consideration, for example:</p>
+
+<ul>
+ <li>How memory intensive is the rest of your activity and/or application?</li>
+ <li>How many images will be on-screen at once? How many need to be available ready to come
+ on-screen?</li>
+ <li>What is the screen size and density of the device? An extra high density screen (xhdpi) device
+ like <a href="http://www.android.com/devices/detail/galaxy-nexus">Galaxy Nexus</a> will need a
+ larger cache to hold the same number of images in memory compared to a device like <a
+ href="http://www.android.com/devices/detail/nexus-s">Nexus S</a> (hdpi).</li>
+ <li>What dimensions and configuration are the bitmaps and therefore how much memory will each take
+ up?</li>
+ <li>How frequently will the images be accessed? Will some be accessed more frequently than others?
+ If so, perhaps you may want to keep certain items always in memory or even have multiple {@link
+ android.util.LruCache} objects for different groups of bitmaps.</li>
+ <li>Can you balance quality against quantity? Sometimes it can be more useful to store a larger
+ number of lower quality bitmaps, potentially loading a higher quality version in another
+ background task.</li>
+</ul>
+
+<p>There is no specific size or formula that suits all applications, it's up to you to analyze your
+usage and come up with a suitable solution. A cache that is too small causes additional overhead with
+no benefit, a cache that is too large can once again cause {@code java.lang.OutOfMemory} exceptions
+and leave the rest of your app little memory to work with.</p>
+
+<p>Here’s an example of setting up a {@link android.util.LruCache} for bitmaps:</p>
+
+<pre>
+private LruCache<String, Bitmap> mMemoryCache;
+
+@Override
+protected void onCreate(Bundle savedInstanceState) {
+ ...
+ // Get memory class of this device, exceeding this amount will throw an
+ // OutOfMemory exception.
+ final int memClass = ((ActivityManager) context.getSystemService(
+ Context.ACTIVITY_SERVICE)).getMemoryClass();
+
+ // Use 1/8th of the available memory for this memory cache.
+ final int cacheSize = 1024 * 1024 * memClass / 8;
+
+ mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
+ @Override
+ protected int sizeOf(String key, Bitmap bitmap) {
+ // The cache size will be measured in bytes rather than number of items.
+ return bitmap.getByteCount();
+ }
+ };
+ ...
+}
+
+public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
+ if (getBitmapFromMemCache(key) == null) {
+ mMemoryCache.put(key, bitmap);
+ }
+}
+
+public Bitmap getBitmapFromMemCache(String key) {
+ return mMemoryCache.get(key);
+}
+</pre>
+
+<p class="note"><strong>Note:</strong> In this example, one eighth of the application memory is
+allocated for our cache. On a normal/hdpi device this is a minimum of around 4MB (32/8). A full
+screen {@link android.widget.GridView} filled with images on a device with 800x480 resolution would
+use around 1.5MB (800*480*4 bytes), so this would cache a minimum of around 2.5 pages of images in
+memory.</p>
+
+<p>When loading a bitmap into an {@link android.widget.ImageView}, the {@link android.util.LruCache}
+is checked first. If an entry is found, it is used immediately to update the {@link
+android.widget.ImageView}, otherwise a background thread is spawned to process the image:</p>
+
+<pre>
+public void loadBitmap(int resId, ImageView imageView) {
+ final String imageKey = String.valueOf(resId);
+
+ final Bitmap bitmap = getBitmapFromMemCache(imageKey);
+ if (bitmap != null) {
+ mImageView.setImageBitmap(bitmap);
+ } else {
+ mImageView.setImageResource(R.drawable.image_placeholder);
+ BitmapWorkerTask task = new BitmapWorkerTask(mImageView);
+ task.execute(resId);
+ }
+}
+</pre>
+
+<p>The <a href="process-bitmap.html#BitmapWorkerTask">{@code BitmapWorkerTask}</a> also needs to be
+updated to add entries to the memory cache:</p>
+
+<pre>
+class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
+ ...
+ // Decode image in background.
+ @Override
+ protected Bitmap doInBackground(Integer... params) {
+ final Bitmap bitmap = decodeSampledBitmapFromResource(
+ getResources(), params[0], 100, 100));
+ addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);
+ return bitmap;
+ }
+ ...
+}
+</pre>
+
+<h2 id="disk-cache">Use a Disk Cache</h2>
+
+<p>A memory cache is useful in speeding up access to recently viewed bitmaps, however you cannot
+rely on images being available in this cache. Components like {@link android.widget.GridView} with
+larger datasets can easily fill up a memory cache. Your application could be interrupted by another
+task like a phone call, and while in the background it might be killed and the memory cache
+destroyed. Once the user resumes, your application it has to process each image again.</p>
+
+<p>A disk cache can be used in these cases to persist processed bitmaps and help decrease loading
+times where images are no longer available in a memory cache. Of course, fetching images from disk
+is slower than loading from memory and should be done in a background thread, as disk read times can
+be unpredictable.</p>
+
+<p class="note"><strong>Note:</strong> A {@link android.content.ContentProvider} might be a more
+appropriate place to store cached images if they are accessed more frequently, for example in an
+image gallery application.</p>
+
+<p>Included in the sample code of this class is a basic {@code DiskLruCache} implementation.
+However, a more robust and recommended {@code DiskLruCache} solution is included in the Android 4.0
+source code ({@code libcore/luni/src/main/java/libcore/io/DiskLruCache.java}). Back-porting this
+class for use on previous Android releases should be fairly straightforward (a <a
+href="http://www.google.com/search?q=disklrucache">quick search</a> shows others who have already
+implemented this solution).</p>
+
+<p>Here’s updated example code that uses the simple {@code DiskLruCache} included in the sample
+application of this class:</p>
+
+<pre>
+private DiskLruCache mDiskCache;
+private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB
+private static final String DISK_CACHE_SUBDIR = "thumbnails";
+
+@Override
+protected void onCreate(Bundle savedInstanceState) {
+ ...
+ // Initialize memory cache
+ ...
+ File cacheDir = getCacheDir(this, DISK_CACHE_SUBDIR);
+ mDiskCache = DiskLruCache.openCache(this, cacheDir, DISK_CACHE_SIZE);
+ ...
+}
+
+class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
+ ...
+ // Decode image in background.
+ @Override
+ protected Bitmap doInBackground(Integer... params) {
+ final String imageKey = String.valueOf(params[0]);
+
+ // Check disk cache in background thread
+ Bitmap bitmap = getBitmapFromDiskCache(imageKey);
+
+ if (bitmap == null) { // Not found in disk cache
+ // Process as normal
+ final Bitmap bitmap = decodeSampledBitmapFromResource(
+ getResources(), params[0], 100, 100));
+ }
+
+ // Add final bitmap to caches
+ addBitmapToCache(String.valueOf(imageKey, bitmap);
+
+ return bitmap;
+ }
+ ...
+}
+
+public void addBitmapToCache(String key, Bitmap bitmap) {
+ // Add to memory cache as before
+ if (getBitmapFromMemCache(key) == null) {
+ mMemoryCache.put(key, bitmap);
+ }
+
+ // Also add to disk cache
+ if (!mDiskCache.containsKey(key)) {
+ mDiskCache.put(key, bitmap);
+ }
+}
+
+public Bitmap getBitmapFromDiskCache(String key) {
+ return mDiskCache.get(key);
+}
+
+// Creates a unique subdirectory of the designated app cache directory. Tries to use external
+// but if not mounted, falls back on internal storage.
+public static File getCacheDir(Context context, String uniqueName) {
+ // Check if media is mounted or storage is built-in, if so, try and use external cache dir
+ // otherwise use internal cache dir
+ final String cachePath = Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED
+ || !Environment.isExternalStorageRemovable() ?
+ context.getExternalCacheDir().getPath() : context.getCacheDir().getPath();
+
+ return new File(cachePath + File.separator + uniqueName);
+}
+</pre>
+
+<p>While the memory cache is checked in the UI thread, the disk cache is checked in the background
+thread. Disk operations should never take place on the UI thread. When image processing is
+complete, the final bitmap is added to both the memory and disk cache for future use.</p>
+
+<h2 id="config-changes">Handle Configuration Changes</h2>
+
+<p>Runtime configuration changes, such as a screen orientation change, cause Android to destroy and
+restart the running activity with the new configuration (For more information about this behavior,
+see <a href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime Changes</a>).
+You want to avoid having to process all your images again so the user has a smooth and fast
+experience when a configuration change occurs.</p>
+
+<p>Luckily, you have a nice memory cache of bitmaps that you built in the <a
+href="#memory-cache">Use a Memory Cache</a> section. This cache can be passed through to the new
+activity instance using a {@link android.app.Fragment} which is preserved by calling {@link
+android.app.Fragment#setRetainInstance setRetainInstance(true)}). After the activity has been
+recreated, this retained {@link android.app.Fragment} is reattached and you gain access to the
+existing cache object, allowing images to be quickly fetched and re-populated into the {@link
+android.widget.ImageView} objects.</p>
+
+<p>Here’s an example of retaining a {@link android.util.LruCache} object across configuration
+changes using a {@link android.app.Fragment}:</p>
+
+<pre>
+private LruCache<String, Bitmap> mMemoryCache;
+
+@Override
+protected void onCreate(Bundle savedInstanceState) {
+ ...
+ RetainFragment mRetainFragment =
+ RetainFragment.findOrCreateRetainFragment(getFragmentManager());
+ mMemoryCache = RetainFragment.mRetainedCache;
+ if (mMemoryCache == null) {
+ mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
+ ... // Initialize cache here as usual
+ }
+ mRetainFragment.mRetainedCache = mMemoryCache;
+ }
+ ...
+}
+
+class RetainFragment extends Fragment {
+ private static final String TAG = "RetainFragment";
+ public LruCache<String, Bitmap> mRetainedCache;
+
+ public RetainFragment() {}
+
+ public static RetainFragment findOrCreateRetainFragment(FragmentManager fm) {
+ RetainFragment fragment = (RetainFragment) fm.findFragmentByTag(TAG);
+ if (fragment == null) {
+ fragment = new RetainFragment();
+ }
+ return fragment;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ <strong>setRetainInstance(true);</strong>
+ }
+}
+</pre>
+
+<p>To test this out, try rotating a device both with and without retaining the {@link
+android.app.Fragment}. You should notice little to no lag as the images populate the activity almost
+instantly from memory when you retain the cache. Any images not found in the memory cache are
+hopefully available in the disk cache, if not, they are processed as usual.</p>
diff --git a/docs/html/training/displaying-bitmaps/display-bitmap.jd b/docs/html/training/displaying-bitmaps/display-bitmap.jd
new file mode 100644
index 0000000..7a93313
--- /dev/null
+++ b/docs/html/training/displaying-bitmaps/display-bitmap.jd
@@ -0,0 +1,400 @@
+page.title=Displaying Bitmaps in Your UI
+parent.title=Displaying Bitmaps Efficiently
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Caching Bitmaps
+previous.link=cache-bitmap.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#viewpager">Load Bitmaps into a ViewPager Implementation</a></li>
+ <li><a href="#gridview">Load Bitmaps into a GridView Implementation</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}design/patterns/swipe-views.html">Android Design: Swipe Views</a></li>
+ <li><a href="{@docRoot}design/building-blocks/grid-lists.html">Android Design: Grid Lists</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="{@docRoot}shareables/training/BitmapFun.zip" class="button">Download the sample</a>
+ <p class="filename">BitmapFun.zip</p>
+</div>
+
+</div>
+</div>
+
+<p></p>
+
+<p>This lesson brings together everything from previous lessons, showing you how to load multiple
+bitmaps into {@link android.support.v4.view.ViewPager} and {@link android.widget.GridView}
+components using a background thread and bitmap cache, while dealing with concurrency and
+configuration changes.</p>
+
+<h2 id="viewpager">Load Bitmaps into a ViewPager Implementation</h2>
+
+<p>The <a href="{@docRoot}design/patterns/swipe-views.html">swipe view pattern</a> is an excellent
+way to navigate the detail view of an image gallery. You can implement this pattern using a {@link
+android.support.v4.view.ViewPager} component backed by a {@link
+android.support.v4.view.PagerAdapter}. However, a more suitable backing adapter is the subclass
+{@link android.support.v4.app.FragmentStatePagerAdapter} which automatically destroys and saves
+state of the {@link android.app.Fragment Fragments} in the {@link android.support.v4.view.ViewPager}
+as they disappear off-screen, keeping memory usage down.</p>
+
+<p class="note"><strong>Note:</strong> If you have a smaller number of images and are confident they
+all fit within the application memory limit, then using a regular {@link
+android.support.v4.view.PagerAdapter} or {@link android.support.v4.app.FragmentPagerAdapter} might
+be more appropriate.</p>
+
+<p>Here’s an implementation of a {@link android.support.v4.view.ViewPager} with {@link
+android.widget.ImageView} children. The main activity holds the {@link
+android.support.v4.view.ViewPager} and the adapter:</p>
+
+<pre>
+public class ImageDetailActivity extends FragmentActivity {
+ public static final String EXTRA_IMAGE = "extra_image";
+
+ private ImagePagerAdapter mAdapter;
+ private ViewPager mPager;
+
+ // A static dataset to back the ViewPager adapter
+ public final static Integer[] imageResIds = new Integer[] {
+ R.drawable.sample_image_1, R.drawable.sample_image_2, R.drawable.sample_image_3,
+ R.drawable.sample_image_4, R.drawable.sample_image_5, R.drawable.sample_image_6,
+ R.drawable.sample_image_7, R.drawable.sample_image_8, R.drawable.sample_image_9};
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.image_detail_pager); // Contains just a ViewPager
+
+ mAdapter = new ImagePagerAdapter(getSupportFragmentManager(), imageResIds.length);
+ mPager = (ViewPager) findViewById(R.id.pager);
+ mPager.setAdapter(mAdapter);
+ }
+
+ public static class ImagePagerAdapter extends FragmentStatePagerAdapter {
+ private final int mSize;
+
+ public ImagePagerAdapter(FragmentManager fm, int size) {
+ super(fm);
+ mSize = size;
+ }
+
+ @Override
+ public int getCount() {
+ return mSize;
+ }
+
+ @Override
+ public Fragment getItem(int position) {
+ return ImageDetailFragment.newInstance(position);
+ }
+ }
+}
+</pre>
+
+<p>The details {@link android.app.Fragment} holds the {@link android.widget.ImageView} children:</p>
+
+<pre>
+public class ImageDetailFragment extends Fragment {
+ private static final String IMAGE_DATA_EXTRA = "resId";
+ private int mImageNum;
+ private ImageView mImageView;
+
+ static ImageDetailFragment newInstance(int imageNum) {
+ final ImageDetailFragment f = new ImageDetailFragment();
+ final Bundle args = new Bundle();
+ args.putInt(IMAGE_DATA_EXTRA, imageNum);
+ f.setArguments(args);
+ return f;
+ }
+
+ // Empty constructor, required as per Fragment docs
+ public ImageDetailFragment() {}
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mImageNum = getArguments() != null ? getArguments().getInt(IMAGE_DATA_EXTRA) : -1;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // image_detail_fragment.xml contains just an ImageView
+ final View v = inflater.inflate(R.layout.image_detail_fragment, container, false);
+ mImageView = (ImageView) v.findViewById(R.id.imageView);
+ return v;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ final int resId = ImageDetailActivity.imageResIds[mImageNum];
+ <strong>mImageView.setImageResource(resId);</strong> // Load image into ImageView
+ }
+}
+</pre>
+
+<p>Hopefully you noticed the issue with this implementation; The images are being read from
+resources on the UI thread which can lead to an application hanging and being force closed. Using an
+{@link android.os.AsyncTask} as described in the <a href="process-bitmap.html">Processing Bitmaps Off
+the UI Thread</a> lesson, it’s straightforward to move image loading and processing to a background
+thread:</p>
+
+<pre>
+public class ImageDetailActivity extends FragmentActivity {
+ ...
+
+ public void loadBitmap(int resId, ImageView imageView) {
+ mImageView.setImageResource(R.drawable.image_placeholder);
+ BitmapWorkerTask task = new BitmapWorkerTask(mImageView);
+ task.execute(resId);
+ }
+
+ ... // include <a href="process-bitmap.html#BitmapWorkerTask">{@code BitmapWorkerTask}</a> class
+}
+
+public class ImageDetailFragment extends Fragment {
+ ...
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ if (ImageDetailActivity.class.isInstance(getActivity())) {
+ final int resId = ImageDetailActivity.imageResIds[mImageNum];
+ // Call out to ImageDetailActivity to load the bitmap in a background thread
+ ((ImageDetailActivity) getActivity()).loadBitmap(resId, mImageView);
+ }
+ }
+}
+</pre>
+
+<p>Any additional processing (such as resizing or fetching images from the network) can take place
+in the <a href="process-bitmap.html#BitmapWorkerTask">{@code BitmapWorkerTask}</a> without affecting
+responsiveness of the main UI. If the background thread is doing more than just loading an image
+directly from disk, it can also be beneficial to add a memory and/or disk cache as described in the
+lesson <a href="cache-bitmap.html#memory-cache">Caching Bitmaps</a>. Here's the additional
+modifications for a memory cache:</p>
+
+<pre>
+public class ImageDetailActivity extends FragmentActivity {
+ ...
+ private LruCache<String, Bitmap> mMemoryCache;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ ...
+ // initialize LruCache as per <a href="cache-bitmap.html#memory-cache">Use a Memory Cache</a> section
+ }
+
+ public void loadBitmap(int resId, ImageView imageView) {
+ final String imageKey = String.valueOf(resId);
+
+ final Bitmap bitmap = mMemoryCache.get(imageKey);
+ if (bitmap != null) {
+ mImageView.setImageBitmap(bitmap);
+ } else {
+ mImageView.setImageResource(R.drawable.image_placeholder);
+ BitmapWorkerTask task = new BitmapWorkerTask(mImageView);
+ task.execute(resId);
+ }
+ }
+
+ ... // include updated BitmapWorkerTask from <a href="cache-bitmap.html#memory-cache">Use a Memory Cache</a> section
+}
+</pre>
+
+<p>Putting all these pieces together gives you a responsive {@link
+android.support.v4.view.ViewPager} implementation with minimal image loading latency and the ability
+to do as much or as little background processing on your images as needed.</p>
+
+<h2 id="gridview">Load Bitmaps into a GridView Implementation</h2>
+
+<p>The <a href="{@docRoot}design/building-blocks/grid-lists.html">grid list building block</a> is
+useful for showing image data sets and can be implemented using a {@link android.widget.GridView}
+component in which many images can be on-screen at any one time and many more need to be ready to
+appear if the user scrolls up or down. When implementing this type of control, you must ensure the
+UI remains fluid, memory usage remains under control and concurrency is handled correctly (due to
+the way {@link android.widget.GridView} recycles its children views).</p>
+
+<p>To start with, here is a standard {@link android.widget.GridView} implementation with {@link
+android.widget.ImageView} children placed inside a {@link android.app.Fragment}:</p>
+
+<pre>
+public class ImageGridFragment extends Fragment implements AdapterView.OnItemClickListener {
+ private ImageAdapter mAdapter;
+
+ // A static dataset to back the GridView adapter
+ public final static Integer[] imageResIds = new Integer[] {
+ R.drawable.sample_image_1, R.drawable.sample_image_2, R.drawable.sample_image_3,
+ R.drawable.sample_image_4, R.drawable.sample_image_5, R.drawable.sample_image_6,
+ R.drawable.sample_image_7, R.drawable.sample_image_8, R.drawable.sample_image_9};
+
+ // Empty constructor as per Fragment docs
+ public ImageGridFragment() {}
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mAdapter = new ImageAdapter(getActivity());
+ }
+
+ @Override
+ public View onCreateView(
+ LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ final View v = inflater.inflate(R.layout.image_grid_fragment, container, false);
+ final GridView mGridView = (GridView) v.findViewById(R.id.gridView);
+ mGridView.setAdapter(mAdapter);
+ mGridView.setOnItemClickListener(this);
+ return v;
+ }
+
+ @Override
+ public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
+ final Intent i = new Intent(getActivity(), ImageDetailActivity.class);
+ i.putExtra(ImageDetailActivity.EXTRA_IMAGE, position);
+ startActivity(i);
+ }
+
+ private class ImageAdapter extends BaseAdapter {
+ private final Context mContext;
+
+ public ImageAdapter(Context context) {
+ super();
+ mContext = context;
+ }
+
+ @Override
+ public int getCount() {
+ return imageResIds.length;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return imageResIds[position];
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup container) {
+ ImageView imageView;
+ if (convertView == null) { // if it's not recycled, initialize some attributes
+ imageView = new ImageView(mContext);
+ imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
+ imageView.setLayoutParams(new GridView.LayoutParams(
+ LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+ } else {
+ imageView = (ImageView) convertView;
+ }
+ <strong>imageView.setImageResource(imageResIds[position]);</strong> // Load image into ImageView
+ return imageView;
+ }
+ }
+}
+</pre>
+
+<p>Once again, the problem with this implementation is that the image is being set in the UI thread.
+While this may work for small, simple images (due to system resource loading and caching), if any
+additional processing needs to be done, your UI grinds to a halt.</p>
+
+<p>The same asynchronous processing and caching methods from the previous section can be implemented
+here. However, you also need to wary of concurrency issues as the {@link android.widget.GridView}
+recycles its children views. To handle this, use the techniques discussed in the <a
+href="process-bitmap#concurrency">Processing Bitmaps Off the UI Thread</a> lesson. Here is the updated
+solution:</p>
+
+<pre>
+public class ImageGridFragment extends Fragment implements AdapterView.OnItemClickListener {
+ ...
+
+ private class ImageAdapter extends BaseAdapter {
+ ...
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup container) {
+ ...
+ <strong>loadBitmap(imageResIds[position], imageView)</strong>
+ return imageView;
+ }
+ }
+
+ public void loadBitmap(int resId, ImageView imageView) {
+ if (cancelPotentialWork(resId, imageView)) {
+ final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
+ final AsyncDrawable asyncDrawable =
+ new AsyncDrawable(getResources(), mPlaceHolderBitmap, task);
+ imageView.setImageDrawable(asyncDrawable);
+ task.execute(resId);
+ }
+ }
+
+ static class AsyncDrawable extends BitmapDrawable {
+ private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
+
+ public AsyncDrawable(Resources res, Bitmap bitmap,
+ BitmapWorkerTask bitmapWorkerTask) {
+ super(res, bitmap);
+ bitmapWorkerTaskReference =
+ new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
+ }
+
+ public BitmapWorkerTask getBitmapWorkerTask() {
+ return bitmapWorkerTaskReference.get();
+ }
+ }
+
+ public static boolean cancelPotentialWork(int data, ImageView imageView) {
+ final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
+
+ if (bitmapWorkerTask != null) {
+ final int bitmapData = bitmapWorkerTask.data;
+ if (bitmapData != data) {
+ // Cancel previous task
+ bitmapWorkerTask.cancel(true);
+ } else {
+ // The same work is already in progress
+ return false;
+ }
+ }
+ // No task associated with the ImageView, or an existing task was cancelled
+ return true;
+ }
+
+ private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
+ if (imageView != null) {
+ final Drawable drawable = imageView.getDrawable();
+ if (drawable instanceof AsyncDrawable) {
+ final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
+ return asyncDrawable.getBitmapWorkerTask();
+ }
+ }
+ return null;
+ }
+
+ ... // include updated <a href="process-bitmap.html#BitmapWorkerTaskUpdated">{@code BitmapWorkerTask}</a> class
+</pre>
+
+<p class="note"><strong>Note:</strong> The same code can easily be adapted to work with {@link
+android.widget.ListView} as well.</p>
+
+<p>This implementation allows for flexibility in how the images are processed and loaded without
+impeding the smoothness of the UI. In the background task you can load images from the network or
+resize large digital camera photos and the images appear as the tasks finish processing.</p>
+
+<p>For a full example of this and other concepts discussed in this lesson, please see the included
+sample application.</p>
diff --git a/docs/html/training/displaying-bitmaps/index.jd b/docs/html/training/displaying-bitmaps/index.jd
new file mode 100644
index 0000000..6755c24
--- /dev/null
+++ b/docs/html/training/displaying-bitmaps/index.jd
@@ -0,0 +1,78 @@
+page.title=Displaying Bitmaps Efficiently
+
+trainingnavtop=true
+startpage=true
+next.title=Loading Large Bitmaps Efficiently
+next.link=load-bitmap.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>Dependencies and prerequisites</h2>
+<ul>
+ <li>Android 2.1 (API Level 7) or higher</li>
+ <li><a href="{@docRoot}sdk/compatibility-library.html">Support Library</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="{@docRoot}shareables/training/BitmapFun.zip" class="button">Download the sample</a>
+ <p class="filename">BitmapFun.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>This class covers some common techniques for processing and loading {@link
+android.graphics.Bitmap} objects in a way that keeps your user interface (UI) components responsive
+and avoids exceeding your application memory limit. If you're not careful, bitmaps can quickly
+consume your available memory budget leading to an application crash due to the dreaded
+exception:<br />{@code java.lang.OutofMemoryError: bitmap size exceeds VM budget}.</p>
+
+<p>There are a number of reasons why loading bitmaps in your Android application is tricky:</p>
+
+<ul>
+ <li>Mobile devices typically have constrained system resources. Android devices can have as little
+ as 16MB of memory available to a single application. The <a
+ href="http://source.android.com/compatibility/downloads.html">Android Compatibility Definition
+ Document</a> (CDD), <i>Section 3.7. Virtual Machine Compatibility</i> gives the required minimum
+ application memory for various screen sizes and densities. Applications should be optimized to
+ perform under this minimum memory limit. However, keep in mind many devices are configured with
+ higher limits.</li>
+ <li>Bitmaps take up a lot of memory, especially for rich images like photographs. For example, the
+ camera on the <a href="http://www.google.com/nexus/">Galaxy Nexus</a> takes photos up to 2592x1936
+ pixels (5 megapixels). If the bitmap configuration used is {@link
+ android.graphics.Bitmap.Config ARGB_8888} (the default from the Android 2.3 onward) then loading
+ this image into memory takes about 19MB of memory (2592*1936*4 bytes), immediately exhausting the
+ per-app limit on some devices.</li>
+ <li>Android app UI’s frequently require several bitmaps to be loaded at once. Components such as
+ {@link android.widget.ListView}, {@link android.widget.GridView} and {@link
+ android.support.v4.view.ViewPager} commonly include multiple bitmaps on-screen at once with many
+ more potentially off-screen ready to show at the flick of a finger.</li>
+</ul>
+
+<h2>Lessons</h2>
+
+<dl>
+ <dt><b><a href="load-bitmap.html">Loading Large Bitmaps Efficiently</a></b></dt>
+ <dd>This lesson walks you through decoding large bitmaps without exceeding the per application
+ memory limit.</dd>
+
+ <dt><b><a href="process-bitmap.html">Processing Bitmaps Off the UI Thread</a></b></dt>
+ <dd>Bitmap processing (resizing, downloading from a remote source, etc.) should never take place
+ on the main UI thread. This lesson walks you through processing bitmaps in a background thread
+ using {@link android.os.AsyncTask} and explains how to handle concurrency issues.</dd>
+
+ <dt><b><a href="cache-bitmap.html">Caching Bitmaps</a></b></dt>
+ <dd>This lesson walks you through using a memory and disk bitmap cache to improve the
+ responsiveness and fluidity of your UI when loading multiple bitmaps.</dd>
+
+ <dt><b><a href="display-bitmap.html">Displaying Bitmaps in Your UI</a></b></dt>
+ <dd>This lesson brings everything together, showing you how to load multiple bitmaps into
+ components like {@link android.support.v4.view.ViewPager} and {@link android.widget.GridView}
+ using a background thread and bitmap cache.</dd>
+
+</dl>
\ No newline at end of file
diff --git a/docs/html/training/displaying-bitmaps/load-bitmap.jd b/docs/html/training/displaying-bitmaps/load-bitmap.jd
new file mode 100644
index 0000000..c0a5709
--- /dev/null
+++ b/docs/html/training/displaying-bitmaps/load-bitmap.jd
@@ -0,0 +1,165 @@
+page.title=Loading Large Bitmaps Efficiently
+parent.title=Displaying Bitmaps Efficiently
+parent.link=index.html
+
+trainingnavtop=true
+next.title=Processing Bitmaps Off the UI Thread
+next.link=process-bitmap.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#read-bitmap">Read Bitmap Dimensions and Type</a></li>
+ <li><a href="#load-bitmap">Load a Scaled Down Version into Memory</a></li>
+</ol>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="{@docRoot}shareables/training/BitmapFun.zip" class="button">Download the sample</a>
+ <p class="filename">BitmapFun.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>Images come in all shapes and sizes. In many cases they are larger than required for a typical
+application user interface (UI). For example, the system Gallery application displays photos taken
+using your Android devices's camera which are typically much higher resolution than the screen
+density of your device.</p>
+
+<p>Given that you are working with limited memory, ideally you only want to load a lower resolution
+version in memory. The lower resolution version should match the size of the UI component that
+displays it. An image with a higher resolution does not provide any visible benefit, but still takes
+up precious memory and incurs additional performance overhead due to additional on the fly
+scaling.</p>
+
+<p>This lesson walks you through decoding large bitmaps without exceeding the per application
+memory limit by loading a smaller subsampled version in memory.</p>
+
+<h2 id="read-bitmap">Read Bitmap Dimensions and Type</h2>
+
+<p>The {@link android.graphics.BitmapFactory} class provides several decoding methods ({@link
+android.graphics.BitmapFactory#decodeByteArray(byte[],int,int,android.graphics.BitmapFactory.Options)
+decodeByteArray()}, {@link
+android.graphics.BitmapFactory#decodeFile(java.lang.String,android.graphics.BitmapFactory.Options)
+decodeFile()}, {@link
+android.graphics.BitmapFactory#decodeResource(android.content.res.Resources,int,android.graphics.BitmapFactory.Options)
+decodeResource()}, etc.) for creating a {@link android.graphics.Bitmap} from various sources. Choose
+the most appropriate decode method based on your image data source. These methods attempt to
+allocate memory for the constructed bitmap and therefore can easily result in an {@code OutOfMemory}
+exception. Each type of decode method has additional signatures that let you specify decoding
+options via the {@link android.graphics.BitmapFactory.Options} class. Setting the {@link
+android.graphics.BitmapFactory.Options#inJustDecodeBounds} property to {@code true} while decoding
+avoids memory allocation, returning {@code null} for the bitmap object but setting {@link
+android.graphics.BitmapFactory.Options#outWidth}, {@link
+android.graphics.BitmapFactory.Options#outHeight} and {@link
+android.graphics.BitmapFactory.Options#outMimeType}. This technique allows you to read the
+dimensions and type of the image data prior to construction (and memory allocation) of the
+bitmap.</p>
+
+<pre>
+BitmapFactory.Options options = new BitmapFactory.Options();
+options.inJustDecodeBounds = true;
+BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
+int imageHeight = options.outHeight;
+int imageWidth = options.outWidth;
+String imageType = options.outMimeType;
+</pre>
+
+<p>To avoid {@code java.lang.OutOfMemory} exceptions, check the dimensions of a bitmap before
+decoding it, unless you absolutely trust the source to provide you with predictably sized image data
+that comfortably fits within the available memory.</p>
+
+<h2 id="load-bitmap">Load a Scaled Down Version into Memory</h2>
+
+<p>Now that the image dimensions are known, they can be used to decide if the full image should be
+loaded into memory or if a subsampled version should be loaded instead. Here are some factors to
+consider:</p>
+
+<ul>
+ <li>Estimated memory usage of loading the full image in memory.</li>
+ <li>Amount of memory you are willing to commit to loading this image given any other memory
+ requirements of your application.</li>
+ <li>Dimensions of the target {@link android.widget.ImageView} or UI component that the image
+ is to be loaded into.</li>
+ <li>Screen size and density of the current device.</li>
+</ul>
+
+<p>For example, it’s not worth loading a 1024x768 pixel image into memory if it will eventually be
+displayed in a 128x96 pixel thumbnail in an {@link android.widget.ImageView}.</p>
+
+<p>To tell the decoder to subsample the image, loading a smaller version into memory, set {@link
+android.graphics.BitmapFactory.Options#inSampleSize} to {@code true} in your {@link
+android.graphics.BitmapFactory.Options} object. For example, an image with resolution 2048x1536 that
+is decoded with an {@link android.graphics.BitmapFactory.Options#inSampleSize} of 4 produces a
+bitmap of approximately 512x384. Loading this into memory uses 0.75MB rather than 12MB for the full
+image (assuming a bitmap configuration of {@link android.graphics.Bitmap.Config ARGB_8888}). Here’s
+a method to calculate a the sample size value based on a target width and height:</p>
+
+<pre>
+public static int calculateInSampleSize(
+ BitmapFactory.Options options, int reqWidth, int reqHeight) {
+ // Raw height and width of image
+ final int height = options.outHeight;
+ final int width = options.outWidth;
+ int inSampleSize = 1;
+
+ if (height > reqHeight || width > reqWidth) {
+ if (width > height) {
+ inSampleSize = Math.round((float)height / (float)reqHeight);
+ } else {
+ inSampleSize = Math.round((float)width / (float)reqWidth);
+ }
+ }
+ return inSampleSize;
+}
+</pre>
+
+<p class="note"><strong>Note:</strong> Using powers of 2 for {@link
+android.graphics.BitmapFactory.Options#inSampleSize} values is faster and more efficient for the
+decoder. However, if you plan to cache the resized versions in memory or on disk, it’s usually still
+worth decoding to the most appropriate image dimensions to save space.</p>
+
+<p>To use this method, first decode with {@link
+android.graphics.BitmapFactory.Options#inJustDecodeBounds} set to {@code true}, pass the options
+through and then decode again using the new {@link
+android.graphics.BitmapFactory.Options#inSampleSize} value and {@link
+android.graphics.BitmapFactory.Options#inJustDecodeBounds} set to {@code false}:</p>
+
+<a name="decodeSampledBitmapFromResource"></a>
+<pre>
+public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
+ int reqWidth, int reqHeight) {
+
+ // First decode with inJustDecodeBounds=true to check dimensions
+ final BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inJustDecodeBounds = true;
+ BitmapFactory.decodeResource(res, resId, options);
+
+ // Calculate inSampleSize
+ options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
+
+ // Decode bitmap with inSampleSize set
+ options.inJustDecodeBounds = false;
+ return BitmapFactory.decodeResource(res, resId, options);
+}
+</pre>
+
+<p>This method makes it easy to load a bitmap of arbitrarily large size into an {@link
+android.widget.ImageView} that displays a 100x100 pixel thumbnail, as shown in the following example
+code:</p>
+
+<pre>
+mImageView.setImageBitmap(
+ decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));
+</pre>
+
+<p>You can follow a similar process to decode bitmaps from other sources, by substituting the
+appropriate {@link
+android.graphics.BitmapFactory#decodeByteArray(byte[],int,int,android.graphics.BitmapFactory.Options)
+BitmapFactory.decode*} method as needed.</p>
\ No newline at end of file
diff --git a/docs/html/training/displaying-bitmaps/process-bitmap.jd b/docs/html/training/displaying-bitmaps/process-bitmap.jd
new file mode 100644
index 0000000..c1450b4
--- /dev/null
+++ b/docs/html/training/displaying-bitmaps/process-bitmap.jd
@@ -0,0 +1,239 @@
+page.title=Processing Bitmaps Off the UI Thread
+parent.title=Displaying Bitmaps Efficiently
+parent.link=index.html
+
+trainingnavtop=true
+next.title=Caching Bitmaps
+next.link=cache-bitmap.html
+previous.title=Loading Large Bitmaps Efficiently
+previous.link=load-bitmap.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#async-task">Use an AsyncTask</a></li>
+ <li><a href="#concurrency">Handle Concurrency</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}guide/practices/design/responsiveness.html">Designing for Responsiveness</a></li>
+ <li><a
+ href="http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html">Multithreading
+ for Performance</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="{@docRoot}shareables/training/BitmapFun.zip" class="button">Download the sample</a>
+ <p class="filename">BitmapFun.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>The {@link
+android.graphics.BitmapFactory#decodeByteArray(byte[],int,int,android.graphics.BitmapFactory.Options)
+BitmapFactory.decode*} methods, discussed in the <a href="load-bitmap.html">Load Large Bitmaps
+Efficiently</a> lesson, should not be executed on the main UI thread if the source data is read from
+disk or a network location (or really any source other than memory). The time this data takes to
+load is unpredictable and depends on a variety of factors (speed of reading from disk or network,
+size of image, power of CPU, etc.). If one of these tasks blocks the UI thread, the system flags
+your application as non-responsive and the user has the option of closing it (see <a
+href="{@docRoot}guide/practices/design/responsiveness.html">Designing for Responsiveness</a> for
+more information).</p>
+
+<p>This lesson walks you through processing bitmaps in a background thread using
+{@link android.os.AsyncTask} and shows you how to handle concurrency issues.</p>
+
+<h2 id="async-task">Use an AsyncTask</h2>
+
+<p>The {@link android.os.AsyncTask} class provides an easy way to execute some work in a background
+thread and publish the results back on the UI thread. To use it, create a subclass and override the
+provided methods. Here’s an example of loading a large image into an {@link
+android.widget.ImageView} using {@link android.os.AsyncTask} and <a
+href="load-bitmap.html#decodeSampledBitmapFromResource">{@code
+decodeSampledBitmapFromResource()}</a>: </p>
+
+<a name="BitmapWorkerTask"></a>
+<pre>
+class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
+ private final WeakReference<ImageView> imageViewReference;
+ private int data = 0;
+
+ public BitmapWorkerTask(ImageView imageView) {
+ // Use a WeakReference to ensure the ImageView can be garbage collected
+ imageViewReference = new WeakReference<ImageView>(imageView);
+ }
+
+ // Decode image in background.
+ @Override
+ protected Bitmap doInBackground(Integer... params) {
+ data = params[0];
+ return decodeSampledBitmapFromResource(getResources(), data, 100, 100));
+ }
+
+ // Once complete, see if ImageView is still around and set bitmap.
+ @Override
+ protected void onPostExecute(Bitmap bitmap) {
+ if (imageViewReference != null && bitmap != null) {
+ final ImageView imageView = imageViewReference.get();
+ if (imageView != null) {
+ imageView.setImageBitmap(bitmap);
+ }
+ }
+ }
+}
+</pre>
+
+<p>The {@link java.lang.ref.WeakReference} to the {@link android.widget.ImageView} ensures that the
+{@link android.os.AsyncTask} does not prevent the {@link android.widget.ImageView} and anything it
+references from being garbage collected. There’s no guarantee the {@link android.widget.ImageView}
+is still around when the task finishes, so you must also check the reference in {@link
+android.os.AsyncTask#onPostExecute(Result) onPostExecute()}. The {@link android.widget.ImageView}
+may no longer exist, if for example, the user navigates away from the activity or if a
+configuration change happens before the task finishes.</p>
+
+<p>To start loading the bitmap asynchronously, simply create a new task and execute it:</p>
+
+<pre>
+public void loadBitmap(int resId, ImageView imageView) {
+ BitmapWorkerTask task = new BitmapWorkerTask(imageView);
+ task.execute(resId);
+}
+</pre>
+
+<h2 id="concurrency">Handle Concurrency</h2>
+
+<p>Common view components such as {@link android.widget.ListView} and {@link
+android.widget.GridView} introduce another issue when used in conjunction with the {@link
+android.os.AsyncTask} as demonstrated in the previous section. In order to be efficient with memory,
+these components recycle child views as the user scrolls. If each child view triggers an {@link
+android.os.AsyncTask}, there is no guarantee that when it completes, the associated view has not
+already been recycled for use in another child view. Furthermore, there is no guarantee that the
+order in which asynchronous tasks are started is the order that they complete.</p>
+
+<p>The blog post <a
+href="http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html">Multithreading
+for Performance</a> further discusses dealing with concurrency, and offers a solution where the
+{@link android.widget.ImageView} stores a reference to the most recent {@link android.os.AsyncTask}
+which can later be checked when the task completes. Using a similar method, the {@link
+android.os.AsyncTask} from the previous section can be extended to follow a similar pattern.</p>
+
+<p>Create a dedicated {@link android.graphics.drawable.Drawable} subclass to store a reference
+back to the worker task. In this case, a {@link android.graphics.drawable.BitmapDrawable} is used so
+that a placeholder image can be displayed in the {@link android.widget.ImageView} while the task
+completes:</p>
+
+<a name="AsyncDrawable"></a>
+<pre>
+static class AsyncDrawable extends BitmapDrawable {
+ private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
+
+ public AsyncDrawable(Resources res, Bitmap bitmap,
+ BitmapWorkerTask bitmapWorkerTask) {
+ super(res, bitmap);
+ bitmapWorkerTaskReference =
+ new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
+ }
+
+ public BitmapWorkerTask getBitmapWorkerTask() {
+ return bitmapWorkerTaskReference.get();
+ }
+}
+</pre>
+
+<p>Before executing the <a href="#BitmapWorkerTask">{@code BitmapWorkerTask}</a>, you create an <a
+href="#AsyncDrawable">{@code AsyncDrawable}</a> and bind it to the target {@link
+android.widget.ImageView}:</p>
+
+<pre>
+public void loadBitmap(int resId, ImageView imageView) {
+ if (cancelPotentialWork(resId, imageView)) {
+ final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
+ final AsyncDrawable asyncDrawable =
+ new AsyncDrawable(getResources(), mPlaceHolderBitmap, task);
+ imageView.setImageDrawable(asyncDrawable);
+ task.execute(resId);
+ }
+}
+</pre>
+
+<p>The {@code cancelPotentialWork} method referenced in the code sample above checks if another
+running task is already associated with the {@link android.widget.ImageView}. If so, it attempts to
+cancel the previous task by calling {@link android.os.AsyncTask#cancel cancel()}. In a small number
+of cases, the new task data matches the existing task and nothing further needs to happen. Here is
+the implementation of {@code cancelPotentialWork}:</p>
+
+<pre>
+public static boolean cancelPotentialWork(int data, ImageView imageView) {
+ final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
+
+ if (bitmapWorkerTask != null) {
+ final int bitmapData = bitmapWorkerTask.data;
+ if (bitmapData != data) {
+ // Cancel previous task
+ bitmapWorkerTask.cancel(true);
+ } else {
+ // The same work is already in progress
+ return false;
+ }
+ }
+ // No task associated with the ImageView, or an existing task was cancelled
+ return true;
+}
+</pre>
+
+<p>A helper method, {@code getBitmapWorkerTask()}, is used above to retrieve the task associated
+with a particular {@link android.widget.ImageView}:</p>
+
+<pre>
+private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
+ if (imageView != null) {
+ final Drawable drawable = imageView.getDrawable();
+ if (drawable instanceof AsyncDrawable) {
+ final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
+ return asyncDrawable.getBitmapWorkerTask();
+ }
+ }
+ return null;
+}
+</pre>
+
+<p>The last step is updating {@code onPostExecute()} in <a href="#BitmapWorkerTask">{@code
+BitmapWorkerTask}</a> so that it checks if the task is cancelled and if the current task matches the
+one associated with the {@link android.widget.ImageView}:</p>
+
+<a name="BitmapWorkerTaskUpdated"></a>
+<pre>
+class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
+ ...
+
+ @Override
+ protected void onPostExecute(Bitmap bitmap) {
+ <strong>if (isCancelled()) {
+ bitmap = null;
+ }</strong>
+
+ if (imageViewReference != null && bitmap != null) {
+ final ImageView imageView = imageViewReference.get();
+ <strong>final BitmapWorkerTask bitmapWorkerTask =
+ getBitmapWorkerTask(imageView);</strong>
+ if (<strong>this == bitmapWorkerTask &&</strong> imageView != null) {
+ imageView.setImageBitmap(bitmap);
+ }
+ }
+ }
+}
+</pre>
+
+<p>This implementation is now suitable for use in {@link android.widget.ListView} and {@link
+android.widget.GridView} components as well as any other components that recycle their child
+views. Simply call {@code loadBitmap} where you normally set an image to your {@link
+android.widget.ImageView}. For example, in a {@link android.widget.GridView} implementation this
+would be in the {@link android.widget.Adapter#getView getView()} method of the backing adapter.</p>
\ No newline at end of file
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index ed5b2f6..c726d0e 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -16,11 +16,9 @@
package android.graphics;
-import android.os.Debug;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.DisplayMetrics;
-import android.util.Log;
import java.io.OutputStream;
import java.nio.Buffer;
@@ -183,7 +181,7 @@
/**
* Sets the layout bounds as an array of left, top, right, bottom integers
- * @param padding the array containing the padding values
+ * @param bounds the array containing the padding values
*
* @hide
*/
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index 0521e69..e101581 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -161,7 +161,31 @@
public void updateTexImage() {
int err = nativeUpdateTexImage();
if (err != 0) {
- throw new RuntimeException("Error during updateTexImage (see logs)");
+ throw new RuntimeException("Error during updateTexImage (see logcat for details)");
+ }
+ }
+
+ /**
+ * Detach the SurfaceTexture from the OpenGL ES context with which it is currently associated.
+ * This can be used to change from one OpenGL ES context to another.
+ *
+ * @hide
+ */
+ public void detachFromGLContext() {
+ int err = nativeDetachFromGLContext();
+ if (err != 0) {
+ throw new RuntimeException("Error during detachFromGLContext (see logcat for details)");
+ }
+ }
+
+ /**
+ *
+ * @hide
+ */
+ public void attachToGLContext(int texName) {
+ int err = nativeAttachToGLContext(texName);
+ if (err != 0) {
+ throw new RuntimeException("Error during detachFromGLContext (see logcat for details)");
}
}
@@ -269,6 +293,8 @@
private native long nativeGetTimestamp();
private native void nativeSetDefaultBufferSize(int width, int height);
private native int nativeUpdateTexImage();
+ private native int nativeDetachFromGLContext();
+ private native int nativeAttachToGLContext(int texName);
private native int nativeGetQueuedCount();
private native void nativeRelease();
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 82dd308..c7e71eb 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -903,9 +903,18 @@
* @hide
*/
public void setMasterMute(boolean state) {
+ setMasterMute(state, FLAG_SHOW_UI);
+ }
+
+ /**
+ * set master mute state with optional flags.
+ *
+ * @hide
+ */
+ public void setMasterMute(boolean state, int flags) {
IAudioService service = getService();
try {
- service.setMasterMute(state, mICallBack);
+ service.setMasterMute(state, flags, mICallBack);
} catch (RemoteException e) {
Log.e(TAG, "Dead object in setMasterMute", e);
}
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index f59848f..2e456f0 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -827,13 +827,13 @@
}
/** @see AudioManager#setMasterMute(boolean, IBinder) */
- public void setMasterMute(boolean state, IBinder cb) {
+ public void setMasterMute(boolean state, int flags, IBinder cb) {
if (state != AudioSystem.getMasterMute()) {
AudioSystem.setMasterMute(state);
// Post a persist master volume msg
sendMsg(mAudioHandler, MSG_PERSIST_MASTER_VOLUME_MUTE, SENDMSG_REPLACE, state ? 1
: 0, 0, null, PERSIST_DELAY);
- sendMasterMuteUpdate(state, AudioManager.FLAG_SHOW_UI);
+ sendMasterMuteUpdate(state, flags);
}
}
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 17d8e4d..b775095 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -45,7 +45,7 @@
boolean isStreamMute(int streamType);
- void setMasterMute(boolean state, IBinder cb);
+ void setMasterMute(boolean state, int flags, IBinder cb);
boolean isMasterMute();
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediaplayback/MediaPlayerApiTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediaplayback/MediaPlayerApiTest.java
index c501d3f..7be2707 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediaplayback/MediaPlayerApiTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediaplayback/MediaPlayerApiTest.java
@@ -22,7 +22,7 @@
import com.android.mediaframeworktest.functional.CodecTest;
import android.content.Context;
-import android.test.ActivityInstrumentationTestCase;
+import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
@@ -33,25 +33,28 @@
/**
* Junit / Instrumentation test case for the media player api
*/
-public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFrameworkTest> {
- private boolean duratoinWithinTolerence = false;
- private String TAG = "MediaPlayerApiTest";
- private boolean isWMAEnable = false;
- private boolean isWMVEnable = false;
+public class MediaPlayerApiTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
+ private boolean duratoinWithinTolerence = false;
+ private String TAG = "MediaPlayerApiTest";
+ private boolean isWMAEnable = false;
+ private boolean isWMVEnable = false;
- Context mContext;
+ Context mContext;
- public MediaPlayerApiTest() {
- super("com.android.mediaframeworktest", MediaFrameworkTest.class);
- isWMAEnable = MediaProfileReader.getWMAEnable();
- isWMVEnable = MediaProfileReader.getWMVEnable();
- }
+ public MediaPlayerApiTest() {
+ super("com.android.mediaframeworktest", MediaFrameworkTest.class);
+ isWMAEnable = MediaProfileReader.getWMAEnable();
+ isWMVEnable = MediaProfileReader.getWMVEnable();
+ }
protected void setUp() throws Exception {
- super.setUp();
-
- }
-
+ //Insert a 2 second before launching the test activity. This is
+ //the workaround for the race condition of requesting the updated surface.
+ Thread.sleep(2000);
+ getActivity();
+ super.setUp();
+ }
+
public boolean verifyDuration(int duration, int expectedDuration){
if ((duration > expectedDuration * 1.1) || (duration < expectedDuration * 0.9))
return false;
diff --git a/packages/InputDevices/Android.mk b/packages/InputDevices/Android.mk
new file mode 100644
index 0000000..446b47e
--- /dev/null
+++ b/packages/InputDevices/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAVA_LIBRARIES :=
+
+LOCAL_PACKAGE_NAME := InputDevices
+LOCAL_CERTIFICATE := platform
+
+include $(BUILD_PACKAGE)
+
+########################
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/InputDevices/AndroidManifest.xml b/packages/InputDevices/AndroidManifest.xml
new file mode 100644
index 0000000..6831a74
--- /dev/null
+++ b/packages/InputDevices/AndroidManifest.xml
@@ -0,0 +1,19 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.inputdevices"
+ coreApp="true"
+ android:sharedUserId="android.uid.system">
+
+ <application
+ android:allowClearUserData="false"
+ android:label="@string/app_label"
+ android:process="system">
+
+ <receiver android:name=".InputDeviceReceiver">
+ <intent-filter>
+ <action android:name="android.hardware.input.action.QUERY_KEYBOARD_LAYOUTS" />
+ </intent-filter>
+ <meta-data android:name="android.hardware.input.metadata.KEYBOARD_LAYOUTS"
+ android:resource="@xml/keyboard_layouts" />
+ </receiver>
+ </application>
+</manifest>
diff --git a/packages/InputDevices/MODULE_LICENSE_APACHE2 b/packages/InputDevices/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/packages/InputDevices/MODULE_LICENSE_APACHE2
diff --git a/packages/InputDevices/NOTICE b/packages/InputDevices/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/packages/InputDevices/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2005-2008, The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+
+ 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.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/packages/InputDevices/res/raw/keyboard_layout_english_us.kcm b/packages/InputDevices/res/raw/keyboard_layout_english_us.kcm
new file mode 100644
index 0000000..a7823fd
--- /dev/null
+++ b/packages/InputDevices/res/raw/keyboard_layout_english_us.kcm
@@ -0,0 +1,15 @@
+# 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.
+
+# PLACEHOLDER CONTENT #
diff --git a/packages/InputDevices/res/raw/keyboard_layout_english_us_dvorak.kcm b/packages/InputDevices/res/raw/keyboard_layout_english_us_dvorak.kcm
new file mode 100644
index 0000000..a7823fd
--- /dev/null
+++ b/packages/InputDevices/res/raw/keyboard_layout_english_us_dvorak.kcm
@@ -0,0 +1,15 @@
+# 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.
+
+# PLACEHOLDER CONTENT #
diff --git a/packages/InputDevices/res/raw/keyboard_layout_german.kcm b/packages/InputDevices/res/raw/keyboard_layout_german.kcm
new file mode 100644
index 0000000..a7823fd
--- /dev/null
+++ b/packages/InputDevices/res/raw/keyboard_layout_german.kcm
@@ -0,0 +1,15 @@
+# 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.
+
+# PLACEHOLDER CONTENT #
diff --git a/packages/InputDevices/res/values/strings.xml b/packages/InputDevices/res/values/strings.xml
new file mode 100644
index 0000000..6d5ee98
--- /dev/null
+++ b/packages/InputDevices/res/values/strings.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Name of the application. [CHAR LIMIT=35] -->
+ <string name="app_label">Input Devices</string>
+
+ <!-- US English keyboard layout label. [CHAR LIMIT=35] -->
+ <string name="keyboard_layout_english_us_label">English (US)</string>
+
+ <!-- US English (Dvorak style) keyboard layout label. [CHAR LIMIT=35] -->
+ <string name="keyboard_layout_english_us_dvorak_label">English (US), Dvorak</string>
+
+ <!-- German keyboard layout label. [CHAR LIMIT=35] -->
+ <string name="keyboard_layout_german_label">German</string>
+</resources>
diff --git a/packages/InputDevices/res/xml/keyboard_layouts.xml b/packages/InputDevices/res/xml/keyboard_layouts.xml
new file mode 100644
index 0000000..459a0e4
--- /dev/null
+++ b/packages/InputDevices/res/xml/keyboard_layouts.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<keyboard-layouts xmlns:android="http://schemas.android.com/apk/res/android">
+ <keyboard-layout android:name="keyboard_layout_english_us"
+ android:label="@string/keyboard_layout_english_us_label"
+ android:kcm="@raw/keyboard_layout_english_us" />
+
+ <keyboard-layout android:name="keyboard_layout_english_us_dvorak"
+ android:label="@string/keyboard_layout_english_us_dvorak_label"
+ android:kcm="@raw/keyboard_layout_english_us_dvorak" />
+
+ <keyboard-layout android:name="keyboard_layout_german"
+ android:label="@string/keyboard_layout_german_label"
+ android:kcm="@raw/keyboard_layout_german" />
+</keyboard-layouts>
diff --git a/packages/InputDevices/src/com/android/inputdevices/InputDeviceReceiver.java b/packages/InputDevices/src/com/android/inputdevices/InputDeviceReceiver.java
new file mode 100644
index 0000000..50a7c2f
--- /dev/null
+++ b/packages/InputDevices/src/com/android/inputdevices/InputDeviceReceiver.java
@@ -0,0 +1,28 @@
+/*
+ * 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.inputdevices;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class InputDeviceReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // Nothing to do at this time.
+ }
+}
diff --git a/packages/SystemUI/res/anim/status_bar_in.xml b/packages/SystemUI/res/anim/status_bar_in.xml
deleted file mode 100644
index 79fe5f1..0000000
--- a/packages/SystemUI/res/anim/status_bar_in.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- >
- <translate android:fromYDelta="100%p" android:toYDelta="0"
- android:duration="@android:integer/config_longAnimTime"
- android:interpolator="@anim/hydraulic_brake_interpolator"
- />
- <alpha android:fromAlpha="0.5" android:toAlpha="1.0"
- android:duration="@android:integer/config_longAnimTime"
- />
-</set>
diff --git a/packages/SystemUI/res/anim/status_bar_out.xml b/packages/SystemUI/res/anim/status_bar_out.xml
deleted file mode 100644
index 80863cf..0000000
--- a/packages/SystemUI/res/anim/status_bar_out.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- >
- <translate android:toYDelta="100%p" android:fromYDelta="0"
- android:duration="@android:integer/config_longAnimTime"
- android:interpolator="@anim/hydraulic_brake_interpolator"
- />
- <alpha android:toAlpha="0.5" android:fromAlpha="1.0"
- android:duration="@android:integer/config_longAnimTime"
- />
-</set>
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index b1aaade..0ba8cce 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -26,6 +26,7 @@
android:orientation="vertical"
android:focusable="true"
android:descendantFocusability="afterDescendants"
+ android:fitsSystemWindows="true"
>
<LinearLayout android:id="@+id/icons"
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index dc5c540..02411d4 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -67,8 +67,6 @@
<!-- Standard animations for hiding and showing the status bar. -->
<style name="Animation.StatusBar">
- <item name="android:windowEnterAnimation">@anim/status_bar_enter</item>
- <item name="android:windowExitAnimation">@anim/status_bar_exit</item>
</style>
<style name="Animation.StatusBar.IntruderAlert">
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
index d7a5056..1ae15be 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@@ -69,9 +69,9 @@
IWindowManager wm = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE));
try {
- SERVICES[0] = wm.canStatusBarHide()
- ? R.string.config_statusBarComponent
- : R.string.config_systemBarComponent;
+ SERVICES[0] = wm.hasSystemNavBar()
+ ? R.string.config_systemBarComponent
+ : R.string.config_statusBarComponent;
} catch (RemoteException e) {
Slog.w(TAG, "Failing checking whether status bar can hide", e);
}
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 12c05ed..5ba72c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1766,11 +1766,6 @@
// HWComposer is unable to handle SW-rendered RGBX_8888 layers.
PixelFormat.RGB_565);
- // the status bar should be in an overlay if possible
- final Display defaultDisplay
- = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
- .getDefaultDisplay();
-
// We explicitly leave FLAG_HARDWARE_ACCELERATED out of the flags. The status bar occupies
// very little screen real-estate and is updated fairly frequently. By using CPU rendering
// for the status bar, we prevent the GPU from having to wake up just to do these small
@@ -1779,9 +1774,7 @@
lp.gravity = getStatusBarGravity();
lp.setTitle("StatusBar");
lp.packageName = mContext.getPackageName();
- lp.windowAnimations = R.style.Animation_StatusBar;
WindowManagerImpl.getDefault().addView(makeStatusBarView(), lp);
-
}
void addExpandedWindow() {
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 cc07240..0c8208f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -23,6 +23,7 @@
import android.graphics.drawable.Drawable;
import android.graphics.Canvas;
import android.graphics.RectF;
+import android.hardware.input.InputManager;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.ServiceManager;
@@ -47,7 +48,6 @@
final float GLOW_MAX_SCALE_FACTOR = 1.8f;
final float BUTTON_QUIESCENT_ALPHA = 0.6f;
- IWindowManager mWindowManager;
long mDownTime;
int mCode;
int mTouchSlop;
@@ -93,9 +93,6 @@
a.recycle();
- mWindowManager = IWindowManager.Stub.asInterface(
- ServiceManager.getService(Context.WINDOW_SERVICE));
-
setClickable(true);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
@@ -276,12 +273,7 @@
0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
flags | KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
InputDevice.SOURCE_KEYBOARD);
- try {
- //Slog.d(TAG, "injecting event " + ev);
- mWindowManager.injectInputEventNoWait(ev);
- } catch (RemoteException ex) {
- // System process is dead
- }
+ InputManager.injectInputEvent(ev, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HeightReceiver.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HeightReceiver.java
deleted file mode 100644
index 3e9a9d8..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HeightReceiver.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.tablet;
-
-import java.util.ArrayList;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.util.DisplayMetrics;
-import android.util.Slog;
-import android.view.Display;
-import android.view.WindowManager;
-import android.view.WindowManagerImpl;
-import android.view.WindowManagerPolicy;
-
-public class HeightReceiver extends BroadcastReceiver {
- private static final String TAG = "StatusBar.HeightReceiver";
-
- public interface OnBarHeightChangedListener {
- public void onBarHeightChanged(int height);
- }
-
- Context mContext;
- ArrayList<OnBarHeightChangedListener> mListeners = new ArrayList<OnBarHeightChangedListener>();
- WindowManager mWindowManager;
- int mHeight;
- boolean mPlugged;
-
- public HeightReceiver(Context context) {
- mContext = context;
- mWindowManager = WindowManagerImpl.getDefault();
- }
-
- public void addOnBarHeightChangedListener(OnBarHeightChangedListener l) {
- mListeners.add(l);
- l.onBarHeightChanged(mHeight);
- }
-
- public void removeOnBarHeightChangedListener(OnBarHeightChangedListener l) {
- mListeners.remove(l);
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- final boolean plugged
- = intent.getBooleanExtra(WindowManagerPolicy.EXTRA_HDMI_PLUGGED_STATE, false);
- setPlugged(plugged);
- }
-
- public void registerReceiver() {
- final IntentFilter filter = new IntentFilter();
- filter.addAction(WindowManagerPolicy.ACTION_HDMI_PLUGGED);
- final Intent val = mContext.registerReceiver(this, filter);
- onReceive(mContext, val);
- }
-
- private void setPlugged(boolean plugged) {
- mPlugged = plugged;
- updateHeight();
- }
-
- public void updateHeight() {
- final Resources res = mContext.getResources();
-
- int height = -1;
- if (mPlugged) {
- final DisplayMetrics metrics = new DisplayMetrics();
- Display display = mWindowManager.getDefaultDisplay();
- display.getRealMetrics(metrics);
-
- //Slog.i(TAG, "updateHeight: display metrics=" + metrics);
- final int shortSide = Math.min(metrics.widthPixels, metrics.heightPixels);
- final int externalShortSide = Math.min(display.getRawExternalWidth(),
- display.getRawExternalHeight());
- height = shortSide - externalShortSide;
- }
-
- final int minHeight
- = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
- if (height < minHeight) {
- height = minHeight;
- }
- Slog.i(TAG, "Resizing status bar plugged=" + mPlugged + " height="
- + height + " old=" + mHeight);
- mHeight = height;
-
- final int N = mListeners.size();
- for (int i=0; i<N; i++) {
- mListeners.get(i).onBarHeightChanged(height);
- }
- }
-
- public int getHeight() {
- return mHeight;
- }
-}
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 7325a37..09283f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -87,7 +87,6 @@
import com.android.systemui.statusbar.policy.Prefs;
public class TabletStatusBar extends BaseStatusBar implements
- HeightReceiver.OnBarHeightChangedListener,
InputMethodsPanel.OnHardKeyboardEnabledChangeListener,
RecentsPanelView.OnRecentsPanelVisibilityChangedListener {
public static final boolean DEBUG = false;
@@ -162,7 +161,6 @@
ViewGroup mPile;
- HeightReceiver mHeightReceiver;
BatteryController mBatteryController;
BluetoothController mBluetoothController;
LocationController mLocationController;
@@ -204,12 +202,11 @@
private void addStatusBarWindow() {
final View sb = makeStatusBarView();
- final int height = getStatusBarHeight();
final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
- height,
- WindowManager.LayoutParams.TYPE_STATUS_BAR,
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
@@ -218,20 +215,14 @@
// HWComposer is unable to handle SW-rendered RGBX_8888 layers.
PixelFormat.RGB_565);
- // the status bar should be in an overlay if possible
- final Display defaultDisplay
- = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
- .getDefaultDisplay();
-
// We explicitly leave FLAG_HARDWARE_ACCELERATED out of the flags. The status bar occupies
// very little screen real-estate and is updated fairly frequently. By using CPU rendering
// for the status bar, we prevent the GPU from having to wake up just to do these small
// updates, which should help keep power consumption down.
lp.gravity = getStatusBarGravity();
- lp.setTitle("StatusBar");
+ lp.setTitle("SystemBar");
lp.packageName = mContext.getPackageName();
- lp.windowAnimations = R.style.Animation_StatusBar;
WindowManagerImpl.getDefault().addView(sb, lp);
}
@@ -414,7 +405,6 @@
@Override
protected void onConfigurationChanged(Configuration newConfig) {
- mHeightReceiver.updateHeight(); // display size may have changed
loadDimens();
mNotificationPanelParams.height = getNotificationPanelHeight();
WindowManagerImpl.getDefault().updateViewLayout(mNotificationPanel,
@@ -426,7 +416,7 @@
final Resources res = mContext.getResources();
mNaturalBarHeight = res.getDimensionPixelSize(
- com.android.internal.R.dimen.system_bar_height);
+ com.android.internal.R.dimen.navigation_bar_height);
int newIconSize = res.getDimensionPixelSize(
com.android.internal.R.dimen.system_bar_icon_size);
@@ -478,10 +468,6 @@
mWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE));
- // This guy will listen for HDMI plugged broadcasts so we can resize the
- // status bar as appropriate.
- mHeightReceiver = new HeightReceiver(mContext);
- mHeightReceiver.registerReceiver();
loadDimens();
final TabletStatusBarView sb = (TabletStatusBarView)View.inflate(
@@ -637,8 +623,6 @@
// set the initial view visibility
setAreThereNotifications();
- mHeightReceiver.addOnBarHeightChangedListener(this);
-
// receive broadcasts
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
@@ -674,7 +658,9 @@
}
public int getStatusBarHeight() {
- return mHeightReceiver.getHeight();
+ return mStatusBarView != null ? mStatusBarView.getHeight()
+ : mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.navigation_bar_height);
}
protected int getStatusBarGravity() {
@@ -1336,14 +1322,6 @@
}
}
- private void sendKey(KeyEvent key) {
- try {
- if (DEBUG) Slog.d(TAG, "injecting key event: " + key);
- mWindowManager.injectInputEventNoWait(key);
- } catch (RemoteException ex) {
- }
- }
-
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
public void onClick(View v) {
if (v == mRecentButton) {
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index 804cd9e..a472375 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -105,6 +105,7 @@
private static final int MSG_CLOCK_VISIBILITY_CHANGED = 307;
private static final int MSG_DEVICE_PROVISIONED = 308;
protected static final int MSG_DPM_STATE_CHANGED = 309;
+ protected static final int MSG_USER_CHANGED = 310;
/**
* When we receive a
@@ -209,6 +210,9 @@
case MSG_DPM_STATE_CHANGED:
handleDevicePolicyManagerStateChanged();
break;
+ case MSG_USER_CHANGED:
+ handleUserChanged(msg.arg1);
+ break;
}
}
};
@@ -268,6 +272,8 @@
filter.addAction(SPN_STRINGS_UPDATED_ACTION);
filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
+ filter.addAction(Intent.ACTION_USER_SWITCHED);
+ filter.addAction(Intent.ACTION_USER_REMOVED);
context.registerReceiver(new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
@@ -302,6 +308,9 @@
} else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
.equals(action)) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_DPM_STATE_CHANGED));
+ } else if (Intent.ACTION_USER_SWITCHED.equals(action)) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_CHANGED,
+ intent.getIntExtra(Intent.EXTRA_USERID, 0), 0));
}
}
}, filter);
@@ -313,6 +322,12 @@
}
}
+ protected void handleUserChanged(int userId) {
+ for (int i = 0; i < mInfoCallbacks.size(); i++) {
+ mInfoCallbacks.get(i).onUserChanged(userId);
+ }
+ }
+
protected void handleDeviceProvisioned() {
for (int i = 0; i < mInfoCallbacks.size(); i++) {
mInfoCallbacks.get(i).onDeviceProvisioned();
@@ -542,6 +557,11 @@
* See {@link DevicePolicyManager#ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED}
*/
void onDevicePolicyManagerStateChanged();
+
+ /**
+ * Called when the user changes.
+ */
+ void onUserChanged(int userId);
}
// Simple class that allows methods to easily be overwritten
@@ -570,6 +590,9 @@
public void onDevicePolicyManagerStateChanged() {
}
+
+ public void onUserChanged(int userId) {
+ }
}
/**
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index 377ea66..52fb875 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -85,7 +85,7 @@
* This class is created by the initialization routine of the {@link WindowManagerPolicy},
* and runs on its thread. The keyguard UI is created from that thread in the
* constructor of this class. The apis may be called from other threads, including the
- * {@link com.android.server.wm.InputManager}'s and {@link android.view.WindowManager}'s.
+ * {@link com.android.server.input.InputManagerService}'s and {@link android.view.WindowManager}'s.
* Therefore, methods on this class are synchronized, and any action that is pointed
* directly to the keyguard UI is posted to a {@link Handler} to ensure it is taken on the UI
* thread of the keyguard.
@@ -342,6 +342,10 @@
if (soundPath == null || mUnlockSoundId == 0) {
if (DEBUG) Log.d(TAG, "failed to load sound from " + soundPath);
}
+ IntentFilter userFilter = new IntentFilter();
+ userFilter.addAction(Intent.ACTION_USER_SWITCHED);
+ userFilter.addAction(Intent.ACTION_USER_REMOVED);
+ mContext.registerReceiver(mUserChangeReceiver, userFilter);
}
/**
@@ -801,6 +805,29 @@
return mKeyguardViewProperties.isSecure();
}
+ private void onUserSwitched(int userId) {
+ mLockPatternUtils.setCurrentUser(userId);
+ synchronized (KeyguardViewMediator.this) {
+ resetStateLocked();
+ }
+ }
+
+ private void onUserRemoved(int userId) {
+ mLockPatternUtils.removeUser(userId);
+ }
+
+ private BroadcastReceiver mUserChangeReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (Intent.ACTION_USER_SWITCHED.equals(action)) {
+ onUserSwitched(intent.getIntExtra(Intent.EXTRA_USERID, 0));
+ } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
+ onUserRemoved(intent.getIntExtra(Intent.EXTRA_USERID, 0));
+ }
+ }
+ };
+
private BroadcastReceiver mBroadCastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 2e7769b..404dc6f 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -757,6 +757,12 @@
hideFaceLockArea();
}
}
+
+ @Override
+ public void onUserChanged(int userId) {
+ mLockPatternUtils.setCurrentUser(userId);
+ updateScreen(getInitialMode(), true);
+ }
};
@Override
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index c9a130b..e8ba21d 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -17,10 +17,8 @@
package com.android.internal.policy.impl;
import com.android.internal.R;
-import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallback;
import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallbackImpl;
import com.android.internal.policy.impl.KeyguardUpdateMonitor.SimStateCallback;
-import com.android.internal.policy.impl.LockScreen.MultiWaveViewMethods;
import com.android.internal.telephony.IccCard.State;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.SlidingTab;
@@ -29,6 +27,7 @@
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
+import android.app.SearchManager;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
@@ -39,6 +38,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
+import android.speech.RecognizerIntent;
import android.util.Log;
import android.media.AudioManager;
import android.os.RemoteException;
@@ -79,7 +79,8 @@
private KeyguardStatusViewManager mStatusViewManager;
private UnlockWidgetCommonMethods mUnlockWidgetMethods;
private View mUnlockWidget;
- public boolean mCameraDisabled;
+ private boolean mCameraDisabled;
+ private boolean mSearchDisabled;
InfoCallbackImpl mInfoCallback = new InfoCallbackImpl() {
@@ -94,14 +95,14 @@
@Override
public void onDevicePolicyManagerStateChanged() {
- updateCameraTarget();
+ updateTargets();
}
};
SimStateCallback mSimStateCallback = new SimStateCallback() {
public void onSimStateChanged(State simState) {
- updateCameraTarget();
+ updateTargets();
}
};
@@ -243,11 +244,12 @@
MultiWaveViewMethods(MultiWaveView multiWaveView) {
mMultiWaveView = multiWaveView;
+
+ // TODO: get search icon. See Launcher.updateGlobalSearchIcon()
}
- public boolean isCameraTargetPresent() {
- return mMultiWaveView
- .getTargetPosition(com.android.internal.R.drawable.ic_lockscreen_camera) != -1;
+ public boolean isTargetPresent(int resId) {
+ return mMultiWaveView.getTargetPosition(resId) != -1;
}
public void updateResources() {
@@ -263,6 +265,7 @@
mMultiWaveView.setTargetResources(resId);
}
setEnabled(com.android.internal.R.drawable.ic_lockscreen_camera, !mCameraDisabled);
+ setEnabled(com.android.internal.R.drawable.ic_lockscreen_search, !mSearchDisabled);
}
public void onGrabbed(View v, int handle) {
@@ -276,8 +279,13 @@
public void onTrigger(View v, int target) {
final int resId = mMultiWaveView.getResourceIdForTarget(target);
switch (resId) {
+ case com.android.internal.R.drawable.ic_lockscreen_search:
+ launchActivity(new Intent(RecognizerIntent.ACTION_WEB_SEARCH));
+ mCallback.pokeWakelock();
+ break;
+
case com.android.internal.R.drawable.ic_lockscreen_camera:
- launchCamera();
+ launchActivity(new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA));
mCallback.pokeWakelock();
break;
@@ -292,8 +300,7 @@
}
}
- private void launchCamera() {
- Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
+ private void launchActivity(Intent intent) {
intent.setFlags(
Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_SINGLE_TOP
@@ -457,18 +464,29 @@
}
}
- private void updateCameraTarget() {
+ private void updateTargets() {
boolean disabledByAdmin = mLockPatternUtils.getDevicePolicyManager()
.getCameraDisabled(null);
boolean disabledBySimState = mUpdateMonitor.isSimLocked();
- boolean targetPresent = (mUnlockWidgetMethods instanceof MultiWaveViewMethods)
- ? ((MultiWaveViewMethods) mUnlockWidgetMethods).isCameraTargetPresent() : false;
+ boolean cameraTargetPresent = (mUnlockWidgetMethods instanceof MultiWaveViewMethods)
+ ? ((MultiWaveViewMethods) mUnlockWidgetMethods)
+ .isTargetPresent(com.android.internal.R.drawable.ic_lockscreen_camera)
+ : false;
+ boolean searchTargetPresent = (mUnlockWidgetMethods instanceof MultiWaveViewMethods)
+ ? ((MultiWaveViewMethods) mUnlockWidgetMethods)
+ .isTargetPresent(com.android.internal.R.drawable.ic_lockscreen_search)
+ : false;
+
+ // TODO: test to see if search is available
+ boolean searchActionAvailable = true;
+
if (disabledByAdmin) {
Log.v(TAG, "Camera disabled by Device Policy");
} else if (disabledBySimState) {
Log.v(TAG, "Camera disabled by Sim State");
}
- mCameraDisabled = disabledByAdmin || disabledBySimState || !targetPresent;
+ mCameraDisabled = disabledByAdmin || disabledBySimState || !cameraTargetPresent;
+ mSearchDisabled = disabledBySimState || !searchActionAvailable || !searchTargetPresent;
mUnlockWidgetMethods.updateResources();
}
diff --git a/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java
index 9a6d2cc..17e671d 100644
--- a/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java
@@ -41,7 +41,7 @@
class PatternUnlockScreen extends LinearLayoutWithDefaultTouchRecepient
implements KeyguardScreen {
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = true; /* TODO: revert before JB release */
private static final String TAG = "UnlockScreen";
// how long before we clear the wrong pattern
@@ -321,6 +321,7 @@
implements LockPatternView.OnPatternListener {
public void onPatternStart() {
+ if (DEBUG) Log.d(TAG, "Got pattern start");
mLockPatternView.removeCallbacks(mCancelPatternRunnable);
}
@@ -336,6 +337,7 @@
// Give just a little extra time if they hit one of the first few dots
mCallback.pokeWakelock(UNLOCK_PATTERN_WAKE_INTERVAL_FIRST_DOTS_MS);
}
+ if (DEBUG) Log.d(TAG, "Got pattern cell");
}
public void onPatternDetected(List<LockPatternView.Cell> pattern) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index fb1e106..5697284 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1,5 +1,4 @@
/*
- * Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -72,6 +71,7 @@
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
+import android.view.Display;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.IApplicationToken;
@@ -132,6 +132,9 @@
import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
import android.view.WindowManagerImpl;
import android.view.WindowManagerPolicy;
+import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
+import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN;
+import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_CLOSED;
import android.view.KeyCharacterMap.FallbackAction;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.Animation;
@@ -237,8 +240,6 @@
static final int SYSTEM_UI_CHANGING_LAYOUT =
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN;
- // Useful scan codes.
- private static final int SW_LID = 0x00;
private static final int BTN_MOUSE = 0x110;
/* Table of Application Launch keys. Maps from key codes to intent categories.
@@ -299,11 +300,13 @@
boolean mHeadless;
boolean mSafeMode;
WindowState mStatusBar = null;
- boolean mStatusBarCanHide;
+ boolean mHasSystemNavBar;
int mStatusBarHeight;
final ArrayList<WindowState> mStatusBarPanels = new ArrayList<WindowState>();
WindowState mNavigationBar = null;
boolean mHasNavigationBar = false;
+ boolean mCanHideNavigationBar = false;
+ boolean mNavigationBarOnBottom = true;
int mNavigationBarWidth = 0, mNavigationBarHeight = 0;
WindowState mKeyguard = null;
@@ -320,15 +323,13 @@
RecentApplicationsDialog mRecentAppsDialog;
int mRecentAppsDialogHeldModifiers;
- private static final int LID_ABSENT = -1;
- private static final int LID_CLOSED = 0;
- private static final int LID_OPEN = 1;
-
int mLidOpen = LID_ABSENT;
boolean mSystemReady;
boolean mSystemBooted;
boolean mHdmiPlugged;
+ int mExternalDisplayWidth;
+ int mExternalDisplayHeight;
int mUiMode;
int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED;
int mLidOpenRotation;
@@ -464,6 +465,8 @@
// (See Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR.)
int mIncallPowerBehavior;
+ Display mDisplay;
+
int mLandscapeRotation = 0; // default landscape rotation
int mSeascapeRotation = 0; // "other" landscape rotation, 180 degrees from mLandscapeRotation
int mPortraitRotation = 0; // default portrait rotation
@@ -927,10 +930,13 @@
}
}
- public void setInitialDisplaySize(int width, int height) {
- int shortSize;
+ public void setInitialDisplaySize(Display display, int width, int height) {
+ mDisplay = display;
+
+ int shortSize, longSize;
if (width > height) {
shortSize = height;
+ longSize = width;
mLandscapeRotation = Surface.ROTATION_0;
mSeascapeRotation = Surface.ROTATION_180;
if (mContext.getResources().getBoolean(
@@ -943,6 +949,7 @@
}
} else {
shortSize = width;
+ longSize = height;
mPortraitRotation = Surface.ROTATION_0;
mUpsideDownRotation = Surface.ROTATION_180;
if (mContext.getResources().getBoolean(
@@ -955,36 +962,62 @@
}
}
+ mExternalDisplayWidth = mDisplay.getRawExternalWidth();
+ mExternalDisplayHeight = mDisplay.getRawExternalHeight();
+
+ mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.status_bar_height);
+ mNavigationBarHeight = mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.navigation_bar_height);
+ mNavigationBarWidth = mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.navigation_bar_width);
+
// Determine whether the status bar can hide based on the size
- // of the screen. We assume sizes > 600dp are tablets where we
+ // of the screen. We assume sizes >= 600dp are tablets where we
// will use the system bar.
+ // XXX: This will change to 720dp soon.
int shortSizeDp = shortSize
* DisplayMetrics.DENSITY_DEFAULT
/ DisplayMetrics.DENSITY_DEVICE;
- mStatusBarCanHide = shortSizeDp < 600;
- mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
- mStatusBarCanHide
- ? com.android.internal.R.dimen.status_bar_height
- : com.android.internal.R.dimen.system_bar_height);
+ mHasSystemNavBar = shortSizeDp >= 600;
- mHasNavigationBar = mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_showNavigationBar);
- // Allow a system property to override this. Used by the emulator.
- // See also hasNavigationBar().
- String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
- if (! "".equals(navBarOverride)) {
- if (navBarOverride.equals("1")) mHasNavigationBar = false;
- else if (navBarOverride.equals("0")) mHasNavigationBar = true;
+ if (!mHasSystemNavBar) {
+ mHasNavigationBar = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_showNavigationBar);
+ // Allow a system property to override this. Used by the emulator.
+ // See also hasNavigationBar().
+ String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
+ if (! "".equals(navBarOverride)) {
+ if (navBarOverride.equals("1")) mHasNavigationBar = false;
+ else if (navBarOverride.equals("0")) mHasNavigationBar = true;
+ }
+ } else {
+ mHasNavigationBar = false;
}
- mNavigationBarHeight = mHasNavigationBar
- ? mContext.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.navigation_bar_height)
- : 0;
- mNavigationBarWidth = mHasNavigationBar
- ? mContext.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.navigation_bar_width)
- : 0;
+ if (mHasSystemNavBar) {
+ // The system bar is always at the bottom. If you are watching
+ // a video in landscape, we don't need to hide it if we can still
+ // show a 16:9 aspect ratio with it.
+ int longSizeDp = longSize
+ * DisplayMetrics.DENSITY_DEFAULT
+ / DisplayMetrics.DENSITY_DEVICE;
+ int barHeightDp = mNavigationBarHeight
+ * DisplayMetrics.DENSITY_DEFAULT
+ / DisplayMetrics.DENSITY_DEVICE;
+ int aspect = ((shortSizeDp-barHeightDp) * 16) / longSizeDp;
+ // We have computed the aspect ratio with the bar height taken
+ // out to be 16:aspect. If this is less than 9, then hiding
+ // the navigation bar will provide more useful space for wide
+ // screen movies.
+ mCanHideNavigationBar = aspect < 9;
+ } else if (mHasNavigationBar) {
+ // The navigation bar is at the right in landscape; it seems always
+ // useful to hide it for showing a video.
+ mCanHideNavigationBar = true;
+ } else {
+ mCanHideNavigationBar = false;
+ }
if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
mHdmiRotation = mPortraitRotation;
@@ -1085,16 +1118,11 @@
lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
wm.addView(mPointerLocationView, lp);
- try {
- mPointerLocationInputChannel =
- mWindowManager.monitorInput("PointerLocationView");
- mPointerLocationInputEventReceiver =
- new PointerLocationInputEventReceiver(mPointerLocationInputChannel,
- Looper.myLooper(), mPointerLocationView);
- } catch (RemoteException ex) {
- Slog.e(TAG, "Could not set up input monitoring channel for PointerLocation.",
- ex);
- }
+ mPointerLocationInputChannel =
+ mWindowManagerFuncs.monitorInput("PointerLocationView");
+ mPointerLocationInputEventReceiver =
+ new PointerLocationInputEventReceiver(mPointerLocationInputChannel,
+ Looper.myLooper(), mPointerLocationView);
}
}
@@ -1188,18 +1216,7 @@
}
void readLidState() {
- try {
- int sw = mWindowManager.getSwitchState(SW_LID);
- if (sw > 0) {
- mLidOpen = LID_OPEN;
- } else if (sw == 0) {
- mLidOpen = LID_CLOSED;
- } else {
- mLidOpen = LID_ABSENT;
- }
- } catch (RemoteException e) {
- // Ignore
- }
+ mLidOpen = mWindowManagerFuncs.getLidState();
}
private int determineHiddenState(int mode, int hiddenValue, int visibleValue) {
@@ -1318,13 +1335,13 @@
return STATUS_BAR_LAYER;
}
- public boolean canStatusBarHide() {
- return mStatusBarCanHide;
+ public boolean hasSystemNavBar() {
+ return mHasSystemNavBar;
}
public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation) {
// Assumes that the navigation bar appears on the side of the display in landscape.
- if (fullWidth > fullHeight) {
+ if (mHasNavigationBar && fullWidth > fullHeight) {
return fullWidth - mNavigationBarWidth;
}
return fullWidth;
@@ -1333,8 +1350,8 @@
public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation) {
// Assumes the navigation bar appears on the bottom of the display in portrait.
return fullHeight
- - (mStatusBarCanHide ? 0 : mStatusBarHeight)
- - ((fullWidth > fullHeight) ? 0 : mNavigationBarHeight);
+ - (mHasSystemNavBar ? mNavigationBarHeight : 0)
+ - ((mHasNavigationBar && fullWidth > fullHeight) ? 0 : mNavigationBarHeight);
}
public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation) {
@@ -1348,7 +1365,7 @@
// exclude it since applications can't generally use that part of the
// screen.
return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation)
- - (mStatusBarCanHide ? mStatusBarHeight : 0);
+ - (mHasSystemNavBar ? 0 : mStatusBarHeight);
}
public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs) {
@@ -1357,6 +1374,7 @@
public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs) {
return attrs.type != WindowManager.LayoutParams.TYPE_STATUS_BAR
+ && attrs.type != WindowManager.LayoutParams.TYPE_NAVIGATION_BAR
&& attrs.type != WindowManager.LayoutParams.TYPE_WALLPAPER;
}
@@ -1495,10 +1513,10 @@
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.STATUS_BAR_SERVICE,
"PhoneWindowManager");
- // TODO: Need to handle the race condition of the status bar proc
- // dying and coming back before the removeWindowLw cleanup has happened.
if (mStatusBar != null) {
- return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
+ if (mStatusBar.isAlive()) {
+ return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
+ }
}
mStatusBar = win;
break;
@@ -1506,6 +1524,11 @@
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.STATUS_BAR_SERVICE,
"PhoneWindowManager");
+ if (mNavigationBar != null) {
+ if (mNavigationBar.isAlive()) {
+ return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
+ }
+ }
mNavigationBar = win;
if (DEBUG_LAYOUT) Log.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
break;
@@ -1550,7 +1573,28 @@
public int selectAnimationLw(WindowState win, int transit) {
if (PRINT_ANIM) Log.i(TAG, "selectAnimation in " + win
+ ": transit=" + transit);
- if (transit == TRANSIT_PREVIEW_DONE) {
+ if (win == mStatusBar) {
+ if (transit == TRANSIT_EXIT || transit == TRANSIT_HIDE) {
+ return R.anim.dock_top_exit;
+ } else if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) {
+ return R.anim.dock_top_enter;
+ }
+ } else if (win == mNavigationBar) {
+ // This can be on either the bottom or the right.
+ if (mNavigationBarOnBottom) {
+ if (transit == TRANSIT_EXIT || transit == TRANSIT_HIDE) {
+ return R.anim.dock_bottom_exit;
+ } else if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) {
+ return R.anim.dock_bottom_enter;
+ }
+ } else {
+ if (transit == TRANSIT_EXIT || transit == TRANSIT_HIDE) {
+ return R.anim.dock_right_exit;
+ } else if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) {
+ return R.anim.dock_right_enter;
+ }
+ }
+ } if (transit == TRANSIT_PREVIEW_DONE) {
if (win.hasAppShownWindows()) {
if (PRINT_ANIM) Log.i(TAG, "**** STARTING EXIT");
return com.android.internal.R.anim.app_starting_exit;
@@ -2036,7 +2080,8 @@
if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_FULLSCREEN | FLAG_LAYOUT_INSET_DECOR))
== (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) {
int availRight, availBottom;
- if ((attrs.systemUiVisibility & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0) {
+ if (mCanHideNavigationBar &&
+ (attrs.systemUiVisibility & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0) {
availRight = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth;
availBottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight;
} else {
@@ -2082,8 +2127,9 @@
pf.right = df.right = vf.right = mDockRight;
pf.bottom = df.bottom = vf.bottom = mDockBottom;
- final boolean navVisible = (mNavigationBar == null || mNavigationBar.isVisibleLw()) &&
- (mLastSystemUiFlags&View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
+ // For purposes of putting out fake window up to steal focus, we will
+ // drive nav being hidden only by whether it is requested.
+ boolean navVisible = (mLastSystemUiFlags&View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
// When the navigation bar isn't visible, we put up a fake
// input window to catch all touch events. This way we can
@@ -2101,117 +2147,107 @@
0, false, false, true);
}
- // decide where the status bar goes ahead of time
- if (mStatusBar != null) {
- if (mNavigationBar != null) {
- // Force the navigation bar to its appropriate place and
- // size. We need to do this directly, instead of relying on
- // it to bubble up from the nav bar, because this needs to
- // change atomically with screen rotations.
- if (displayWidth < displayHeight) {
- // Portrait screen; nav bar goes on bottom.
- mTmpNavigationFrame.set(0, displayHeight-mNavigationBarHeight,
- displayWidth, displayHeight);
- mStableBottom = mTmpNavigationFrame.top;
- if (navVisible) {
- mDockBottom = mTmpNavigationFrame.top;
- mRestrictedScreenHeight = mDockBottom - mDockTop;
- } else {
- // We currently want to hide the navigation UI. Do this by just
- // moving it off the screen, so it can still receive input events
- // to know when to be re-shown.
- mTmpNavigationFrame.offset(0, mNavigationBarHeight);
- }
- } else {
- // Landscape screen; nav bar goes to the right.
- mTmpNavigationFrame.set(displayWidth-mNavigationBarWidth, 0,
- displayWidth, displayHeight);
- mStableRight = mTmpNavigationFrame.left;
- if (navVisible) {
- mDockRight = mTmpNavigationFrame.left;
- mRestrictedScreenWidth = mDockRight - mDockLeft;
- } else {
- // We currently want to hide the navigation UI. Do this by just
- // moving it off the screen, so it can still receive input events
- // to know when to be re-shown.
- mTmpNavigationFrame.offset(mNavigationBarWidth, 0);
+ // For purposes of positioning and showing the nav bar, if we have
+ // decided that it can't be hidden (because of the screen aspect ratio),
+ // then take that into account.
+ navVisible |= !mCanHideNavigationBar;
+
+ if (mNavigationBar != null) {
+ // Force the navigation bar to its appropriate place and
+ // size. We need to do this directly, instead of relying on
+ // it to bubble up from the nav bar, because this needs to
+ // change atomically with screen rotations.
+ mNavigationBarOnBottom = !mHasNavigationBar || displayWidth < displayHeight;
+ if (mNavigationBarOnBottom) {
+ // It's a system nav bar or a portrait screen; nav bar goes on bottom.
+ int top = displayHeight - mNavigationBarHeight;
+ if (mHdmiPlugged) {
+ if (top > mExternalDisplayHeight) {
+ top = mExternalDisplayHeight;
}
}
- // Make sure the content and current rectangles are updated to
- // account for the restrictions from the navigation bar.
- mContentTop = mCurTop = mDockTop;
- mContentBottom = mCurBottom = mDockBottom;
- mContentLeft = mCurLeft = mDockLeft;
- mContentRight = mCurRight = mDockRight;
- // And compute the final frame.
- mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame,
- mTmpNavigationFrame, mTmpNavigationFrame);
- if (DEBUG_LAYOUT) Log.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame);
+ mTmpNavigationFrame.set(0, top, displayWidth, displayHeight);
+ mStableBottom = mTmpNavigationFrame.top;
+ if (navVisible) {
+ mNavigationBar.showLw(true);
+ mDockBottom = mTmpNavigationFrame.top;
+ mRestrictedScreenHeight = mDockBottom - mDockTop;
+ } else {
+ // We currently want to hide the navigation UI.
+ mNavigationBar.hideLw(true);
+ }
+ } else {
+ // Landscape screen; nav bar goes to the right.
+ int left = displayWidth - mNavigationBarWidth;
+ if (mHdmiPlugged) {
+ if (left > mExternalDisplayWidth) {
+ left = mExternalDisplayWidth;
+ }
+ }
+ mTmpNavigationFrame.set(left, 0, displayWidth, displayHeight);
+ mStableRight = mTmpNavigationFrame.left;
+ if (navVisible) {
+ mNavigationBar.showLw(true);
+ mDockRight = mTmpNavigationFrame.left;
+ mRestrictedScreenWidth = mDockRight - mDockLeft;
+ } else {
+ // We currently want to hide the navigation UI.
+ mNavigationBar.hideLw(true);
+ }
}
- if (DEBUG_LAYOUT) Log.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)",
- mDockLeft, mDockTop, mDockRight, mDockBottom));
+ // Make sure the content and current rectangles are updated to
+ // account for the restrictions from the navigation bar.
+ mContentTop = mCurTop = mDockTop;
+ mContentBottom = mCurBottom = mDockBottom;
+ mContentLeft = mCurLeft = mDockLeft;
+ mContentRight = mCurRight = mDockRight;
+ // And compute the final frame.
+ mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame,
+ mTmpNavigationFrame, mTmpNavigationFrame);
+ if (DEBUG_LAYOUT) Log.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame);
+ }
+ if (DEBUG_LAYOUT) Log.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)",
+ mDockLeft, mDockTop, mDockRight, mDockBottom));
- // apply navigation bar insets
- pf.left = df.left = vf.left = mDockLeft;
- pf.top = df.top = vf.top = mDockTop;
- pf.right = df.right = vf.right = mDockRight;
- pf.bottom = df.bottom = vf.bottom = mDockBottom;
+ // decide where the status bar goes ahead of time
+ if (mStatusBar != null) {
+ // apply any navigation bar insets
+ pf.left = df.left = mUnrestrictedScreenLeft;
+ pf.top = df.top = mUnrestrictedScreenTop;
+ pf.right = df.right = mUnrestrictedScreenWidth - mUnrestrictedScreenLeft;
+ pf.bottom = df.bottom = mUnrestrictedScreenHeight - mUnrestrictedScreenTop;
+ vf.left = mStableLeft;
+ vf.top = mStableTop;
+ vf.right = mStableRight;
+ vf.bottom = mStableBottom;
mStatusBar.computeFrameLw(pf, df, vf, vf);
final Rect r = mStatusBar.getFrameLw();
// Compute the stable dimensions whether or not the status bar is hidden.
- if (mStatusBarCanHide) {
- if (mDockTop == r.top) mStableTop = r.bottom;
- else if (mDockBottom == r.bottom) mStableBottom = r.top;
- } else {
- if (mStableTop == r.top) {
- mStableTop = r.bottom;
- } else if (mStableBottom == r.bottom) {
- mStableBottom = r.top;
- }
- }
+ if (mDockTop == r.top) mStableTop = r.bottom;
+ else if (mDockBottom == r.bottom) mStableBottom = r.top;
+ // If the status bar is hidden, we don't want to cause
+ // windows behind it to scroll.
if (mStatusBar.isVisibleLw()) {
- // If the status bar is hidden, we don't want to cause
- // windows behind it to scroll.
- if (mStatusBarCanHide) {
- // Status bar may go away, so the screen area it occupies
- // is available to apps but just covering them when the
- // status bar is visible.
- if (mDockTop == r.top) mDockTop = r.bottom;
- else if (mDockBottom == r.bottom) mDockBottom = r.top;
-
- mContentTop = mCurTop = mDockTop;
- mContentBottom = mCurBottom = mDockBottom;
- mContentLeft = mCurLeft = mDockLeft;
- mContentRight = mCurRight = mDockRight;
+ // Status bar may go away, so the screen area it occupies
+ // is available to apps but just covering them when the
+ // status bar is visible.
+ if (mDockTop == r.top) mDockTop = r.bottom;
+ else if (mDockBottom == r.bottom) mDockBottom = r.top;
+
+ mContentTop = mCurTop = mDockTop;
+ mContentBottom = mCurBottom = mDockBottom;
+ mContentLeft = mCurLeft = mDockLeft;
+ mContentRight = mCurRight = mDockRight;
- if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: " +
- String.format(
- "dock=[%d,%d][%d,%d] content=[%d,%d][%d,%d] cur=[%d,%d][%d,%d]",
- mDockLeft, mDockTop, mDockRight, mDockBottom,
- mContentLeft, mContentTop, mContentRight, mContentBottom,
- mCurLeft, mCurTop, mCurRight, mCurBottom));
- } else {
- // Status bar can't go away; the part of the screen it
- // covers does not exist for anything behind it.
- if (mRestrictedScreenTop == r.top) {
- mRestrictedScreenTop = r.bottom;
- mRestrictedScreenHeight -= (r.bottom-r.top);
- } else if ((mRestrictedScreenHeight-mRestrictedScreenTop) == r.bottom) {
- mRestrictedScreenHeight -= (r.bottom-r.top);
- }
-
- mContentTop = mCurTop = mDockTop = mRestrictedScreenTop;
- mContentBottom = mCurBottom = mDockBottom
- = mRestrictedScreenTop + mRestrictedScreenHeight;
- if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: restricted screen area: ("
- + mRestrictedScreenLeft + ","
- + mRestrictedScreenTop + ","
- + (mRestrictedScreenLeft + mRestrictedScreenWidth) + ","
- + (mRestrictedScreenTop + mRestrictedScreenHeight) + ")");
- }
+ if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: " +
+ String.format(
+ "dock=[%d,%d][%d,%d] content=[%d,%d][%d,%d] cur=[%d,%d][%d,%d]",
+ mDockLeft, mDockTop, mDockRight, mDockBottom,
+ mContentLeft, mContentTop, mContentRight, mContentBottom,
+ mCurLeft, mCurTop, mCurRight, mCurBottom));
}
}
}
@@ -2333,7 +2369,8 @@
"Laying out status bar window: (%d,%d - %d,%d)",
pf.left, pf.top, pf.right, pf.bottom));
}
- } else if ((sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
+ } else if (mCanHideNavigationBar
+ && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
&& attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
&& attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
// Asking for layout as if the nav bar is hidden, lets the
@@ -2426,7 +2463,8 @@
pf.right = df.right = cf.right = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
pf.bottom = df.bottom = cf.bottom
= mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
- } else if ((sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
+ } else if (mCanHideNavigationBar
+ && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
&& attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
&& attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
// Asking for layout as if the nav bar is hidden, lets the
@@ -2623,19 +2661,17 @@
// has the FLAG_FULLSCREEN set. Not sure if there is another way that to be the
// case though.
if (topIsFullscreen) {
- if (mStatusBarCanHide) {
- if (DEBUG_LAYOUT) Log.v(TAG, "** HIDING status bar");
- if (mStatusBar.hideLw(true)) {
- changes |= FINISH_LAYOUT_REDO_LAYOUT;
+ if (DEBUG_LAYOUT) Log.v(TAG, "** HIDING status bar");
+ if (mStatusBar.hideLw(true)) {
+ changes |= FINISH_LAYOUT_REDO_LAYOUT;
- mHandler.post(new Runnable() { public void run() {
- if (mStatusBarService != null) {
- try {
- mStatusBarService.collapse();
- } catch (RemoteException ex) {}
- }
- }});
- }
+ mHandler.post(new Runnable() { public void run() {
+ if (mStatusBarService != null) {
+ try {
+ mStatusBarService.collapse();
+ } catch (RemoteException ex) {}
+ }
+ }});
} else if (DEBUG_LAYOUT) {
Log.v(TAG, "Preventing status bar from hiding by policy");
}
@@ -2699,29 +2735,23 @@
// behind it.
return false;
}
- if (false) {
- // Don't do this on the tablet, since the system bar never completely
- // covers the screen, and with all its transparency this will
- // incorrectly think it does cover it when it doesn't. We'll revisit
- // this later when we re-do the phone status bar.
- if (mStatusBar != null && mStatusBar.isVisibleLw()) {
- RectF rect = new RectF(mStatusBar.getShownFrameLw());
- for (int i=mStatusBarPanels.size()-1; i>=0; i--) {
- WindowState w = mStatusBarPanels.get(i);
- if (w.isVisibleLw()) {
- rect.union(w.getShownFrameLw());
- }
+ if (mStatusBar != null && mStatusBar.isVisibleLw()) {
+ RectF rect = new RectF(mStatusBar.getShownFrameLw());
+ for (int i=mStatusBarPanels.size()-1; i>=0; i--) {
+ WindowState w = mStatusBarPanels.get(i);
+ if (w.isVisibleLw()) {
+ rect.union(w.getShownFrameLw());
}
- final int insetw = mRestrictedScreenWidth/10;
- final int inseth = mRestrictedScreenHeight/10;
- if (rect.contains(insetw, inseth, mRestrictedScreenWidth-insetw,
- mRestrictedScreenHeight-inseth)) {
- // All of the status bar windows put together cover the
- // screen, so the app can't be seen. (Note this test doesn't
- // work if the rects of these windows are at off offsets or
- // sizes, causing gaps in the rect union we have computed.)
- return false;
- }
+ }
+ final int insetw = mRestrictedScreenWidth/10;
+ final int inseth = mRestrictedScreenHeight/10;
+ if (rect.contains(insetw, inseth, mRestrictedScreenWidth-insetw,
+ mRestrictedScreenHeight-inseth)) {
+ // All of the status bar windows put together cover the
+ // screen, so the app can't be seen. (Note this test doesn't
+ // work if the rects of these windows are at odd offsets or
+ // sizes, causing gaps in the rect union we have computed.)
+ return false;
}
}
return true;
@@ -2776,7 +2806,11 @@
void setHdmiPlugged(boolean plugged) {
if (mHdmiPlugged != plugged) {
mHdmiPlugged = plugged;
- updateRotation(true);
+ if (plugged && mDisplay != null) {
+ mExternalDisplayWidth = mDisplay.getRawExternalWidth();
+ mExternalDisplayHeight = mDisplay.getRawExternalHeight();
+ }
+ updateRotation(true, true);
Intent intent = new Intent(ACTION_HDMI_PLUGGED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
intent.putExtra(EXTRA_HDMI_PLUGGED_STATE, plugged);
@@ -3596,29 +3630,11 @@
}
}
- public boolean detectSafeMode() {
- try {
- int menuState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_MENU);
- int sState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_S);
- int dpadState = mWindowManager.getDPadKeycodeState(KeyEvent.KEYCODE_DPAD_CENTER);
- int trackballState = mWindowManager.getTrackballScancodeState(BTN_MOUSE);
- int volumeDownState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_VOLUME_DOWN);
- mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
- || volumeDownState > 0;
- performHapticFeedbackLw(null, mSafeMode
- ? HapticFeedbackConstants.SAFE_MODE_ENABLED
- : HapticFeedbackConstants.SAFE_MODE_DISABLED, true);
- if (mSafeMode) {
- Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
- + " dpad=" + dpadState + " trackball=" + trackballState + ")");
- } else {
- Log.i(TAG, "SAFE MODE not enabled");
- }
- return mSafeMode;
- } catch (RemoteException e) {
- // Doom! (it's also local)
- throw new RuntimeException("window manager dead");
- }
+ public void setSafeMode(boolean safeMode) {
+ mSafeMode = safeMode;
+ performHapticFeedbackLw(null, safeMode
+ ? HapticFeedbackConstants.SAFE_MODE_ENABLED
+ : HapticFeedbackConstants.SAFE_MODE_DISABLED, true);
}
static long[] getLongIntArray(Resources r, int resid) {
@@ -3871,7 +3887,16 @@
void updateRotation(boolean alwaysSendConfiguration) {
try {
//set orientation on WindowManager
- mWindowManager.updateRotation(alwaysSendConfiguration);
+ mWindowManager.updateRotation(alwaysSendConfiguration, false);
+ } catch (RemoteException e) {
+ // Ignore
+ }
+ }
+
+ void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
+ try {
+ //set orientation on WindowManager
+ mWindowManager.updateRotation(alwaysSendConfiguration, forceRelayout);
} catch (RemoteException e) {
// Ignore
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e091edf..7dd736d 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -47,6 +47,7 @@
import com.android.internal.app.ShutdownThread;
import com.android.internal.os.BinderInternal;
import com.android.internal.os.SamplingProfilerIntegration;
+import com.android.internal.widget.LockSettingsService;
import com.android.server.accessibility.AccessibilityManagerService;
import com.android.server.am.ActivityManagerService;
import com.android.server.net.NetworkPolicyManagerService;
@@ -220,6 +221,7 @@
factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
!firstBoot);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
+ ServiceManager.addService(Context.INPUT_SERVICE, wm.getInputManagerService());
ActivityManagerService.self().setWindowManager(wm);
@@ -266,6 +268,7 @@
LocationManagerService location = null;
CountryDetectorService countryDetector = null;
TextServicesManagerService tsms = null;
+ LockSettingsService lockSettings = null;
// Bring up services needed for UI.
if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
@@ -308,6 +311,14 @@
if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
try {
+ Slog.i(TAG, "LockSettingsService");
+ lockSettings = new LockSettingsService(context);
+ ServiceManager.addService("lock_settings", lockSettings);
+ } catch (Throwable e) {
+ reportWtf("starting LockSettingsService service", e);
+ }
+
+ try {
Slog.i(TAG, "Device Policy");
devicePolicy = new DevicePolicyManagerService(context);
ServiceManager.addService(Context.DEVICE_POLICY_SERVICE, devicePolicy);
@@ -661,6 +672,11 @@
} catch (Throwable e) {
reportWtf("making Package Manager Service ready", e);
}
+ try {
+ lockSettings.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Lock Settings Service ready", e);
+ }
// These are needed to propagate to the runnable below.
final Context contextF = context;
diff --git a/services/java/com/android/server/TelephonyRegistry.java b/services/java/com/android/server/TelephonyRegistry.java
index 8c8e725..1b1638a 100644
--- a/services/java/com/android/server/TelephonyRegistry.java
+++ b/services/java/com/android/server/TelephonyRegistry.java
@@ -29,6 +29,7 @@
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
+import android.telephony.CellInfo;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Slog;
@@ -107,6 +108,8 @@
private int mOtaspMode = ServiceStateTracker.OTASP_UNKNOWN;
+ private CellInfo mCellInfo = null;
+
static final int PHONE_STATE_PERMISSION_MASK =
PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR |
PhoneStateListener.LISTEN_CALL_STATE |
@@ -236,6 +239,13 @@
remove(r.binder);
}
}
+ if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
+ try {
+ r.callback.onCellInfoChanged(new CellInfo(mCellInfo));
+ } catch (RemoteException ex) {
+ remove(r.binder);
+ }
+ }
}
}
} else {
@@ -325,6 +335,26 @@
broadcastSignalStrengthChanged(signalStrength);
}
+ public void notifyCellInfo(CellInfo cellInfo) {
+ if (!checkNotifyPermission("notifyCellInfo()")) {
+ return;
+ }
+
+ synchronized (mRecords) {
+ mCellInfo = cellInfo;
+ for (Record r : mRecords) {
+ if ((r.events & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
+ try {
+ r.callback.onCellInfoChanged(new CellInfo(cellInfo));
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
+ }
+ }
+ handleRemoveListLocked();
+ }
+ }
+
public void notifyMessageWaitingChanged(boolean mwi) {
if (!checkNotifyPermission("notifyMessageWaitingChanged()")) {
return;
@@ -530,6 +560,7 @@
pw.println(" mDataConnectionLinkProperties=" + mDataConnectionLinkProperties);
pw.println(" mDataConnectionLinkCapabilities=" + mDataConnectionLinkCapabilities);
pw.println(" mCellLocation=" + mCellLocation);
+ pw.println(" mCellInfo=" + mCellInfo);
pw.println("registrations: count=" + recordCount);
for (Record r : mRecords) {
pw.println(" " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events));
@@ -655,6 +686,12 @@
}
+ if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
+
+ }
+
if ((events & PHONE_STATE_PERMISSION_MASK) != 0) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.READ_PHONE_STATE, null);
diff --git a/services/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 769cb6a..31aa21e 100644
--- a/services/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -16,7 +16,7 @@
package com.android.server.accessibility;
-import com.android.server.wm.InputFilter;
+import com.android.server.input.InputFilter;
import android.content.Context;
import android.util.Slog;
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java
index 41cf9a6..d07aa7a 100644
--- a/services/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/java/com/android/server/accessibility/TouchExplorer.java
@@ -29,7 +29,7 @@
import android.view.accessibility.AccessibilityManager;
import com.android.server.accessibility.AccessibilityInputFilter.Explorer;
-import com.android.server.wm.InputFilter;
+import com.android.server.input.InputFilter;
import java.util.Arrays;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index a6fbdd7..2da827e 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -62,10 +62,10 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.content.IIntentReceiver;
import android.content.IIntentSender;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
@@ -75,12 +75,12 @@
import android.content.pm.InstrumentationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PathPermission;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
@@ -113,10 +113,10 @@
import android.provider.Settings;
import android.text.format.Time;
import android.util.EventLog;
-import android.util.Pair;
-import android.util.Slog;
import android.util.Log;
+import android.util.Pair;
import android.util.PrintWriterPrinter;
+import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.util.TimeUtils;
@@ -140,7 +140,6 @@
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
-import java.lang.IllegalStateException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
@@ -10263,6 +10262,29 @@
}
pw.println();
pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
+ final int[] SINGLE_LONG_FORMAT = new int[] {
+ Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
+ };
+ long[] longOut = new long[1];
+ Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
+ SINGLE_LONG_FORMAT, null, longOut, null);
+ long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
+ longOut[0] = 0;
+ Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
+ SINGLE_LONG_FORMAT, null, longOut, null);
+ long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
+ longOut[0] = 0;
+ Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
+ SINGLE_LONG_FORMAT, null, longOut, null);
+ long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
+ longOut[0] = 0;
+ Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
+ SINGLE_LONG_FORMAT, null, longOut, null);
+ long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
+ pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
+ pw.print(shared); pw.println(" kB");
+ pw.print(" "); pw.print(unshared); pw.print(" kB unshared; ");
+ pw.print(voltile); pw.println(" kB volatile");
}
}
@@ -13281,6 +13303,102 @@
}
}
+ @Override
+ public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
+ ActivityRecord srec = ActivityRecord.forToken(token);
+ return srec.task.affinity != null && srec.task.affinity.equals(destAffinity);
+ }
+
+ public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
+ Intent resultData) {
+ ComponentName dest = destIntent.getComponent();
+
+ synchronized (this) {
+ ActivityRecord srec = ActivityRecord.forToken(token);
+ ArrayList<ActivityRecord> history = srec.stack.mHistory;
+ final int start = history.indexOf(srec);
+ if (start < 0) {
+ // Current activity is not in history stack; do nothing.
+ return false;
+ }
+ int finishTo = start - 1;
+ ActivityRecord parent = null;
+ boolean foundParentInTask = false;
+ if (dest != null) {
+ TaskRecord tr = srec.task;
+ for (int i = start - 1; i >= 0; i--) {
+ ActivityRecord r = history.get(i);
+ if (tr != r.task) {
+ // Couldn't find parent in the same task; stop at the one above this.
+ // (Root of current task; in-app "home" behavior)
+ // Always at least finish the current activity.
+ finishTo = Math.min(start - 1, i + 1);
+ parent = history.get(finishTo);
+ break;
+ } else if (r.info.packageName.equals(dest.getPackageName()) &&
+ r.info.name.equals(dest.getClassName())) {
+ finishTo = i;
+ parent = r;
+ foundParentInTask = true;
+ break;
+ }
+ }
+ }
+
+ if (mController != null) {
+ ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
+ if (next != null) {
+ // ask watcher if this is allowed
+ boolean resumeOK = true;
+ try {
+ resumeOK = mController.activityResuming(next.packageName);
+ } catch (RemoteException e) {
+ mController = null;
+ }
+
+ if (!resumeOK) {
+ return false;
+ }
+ }
+ }
+ final long origId = Binder.clearCallingIdentity();
+ for (int i = start; i > finishTo; i--) {
+ ActivityRecord r = history.get(i);
+ mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
+ "navigate-up");
+ // Only return the supplied result for the first activity finished
+ resultCode = Activity.RESULT_CANCELED;
+ resultData = null;
+ }
+
+ if (parent != null && foundParentInTask) {
+ final int parentLaunchMode = parent.info.launchMode;
+ final int destIntentFlags = destIntent.getFlags();
+ if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
+ parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
+ parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
+ (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
+ parent.deliverNewIntentLocked(srec.app.uid, destIntent);
+ } else {
+ try {
+ ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
+ destIntent.getComponent(), 0, UserId.getCallingUserId());
+ int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
+ null, aInfo, parent.appToken, null,
+ 0, -1, parent.launchedFromUid, 0, null, true, null);
+ foundParentInTask = res == ActivityManager.START_SUCCESS;
+ } catch (RemoteException e) {
+ foundParentInTask = false;
+ }
+ mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
+ resultData, "navigate-up");
+ }
+ }
+ Binder.restoreCallingIdentity(origId);
+ return foundParentInTask;
+ }
+ }
+
// =========================================================
// LIFETIME MANAGEMENT
// =========================================================
diff --git a/services/java/com/android/server/wm/InputApplicationHandle.java b/services/java/com/android/server/input/InputApplicationHandle.java
similarity index 90%
rename from services/java/com/android/server/wm/InputApplicationHandle.java
rename to services/java/com/android/server/input/InputApplicationHandle.java
index 1812f11..42c1052 100644
--- a/services/java/com/android/server/wm/InputApplicationHandle.java
+++ b/services/java/com/android/server/input/InputApplicationHandle.java
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-package com.android.server.wm;
-
+package com.android.server.input;
/**
* Functions as a handle for an application that can receive input.
@@ -30,7 +29,7 @@
private int ptr;
// The window manager's application window token.
- public final AppWindowToken appWindowToken;
+ public final Object appWindowToken;
// Application name.
public String name;
@@ -40,7 +39,7 @@
private native void nativeDispose();
- public InputApplicationHandle(AppWindowToken appWindowToken) {
+ public InputApplicationHandle(Object appWindowToken) {
this.appWindowToken = appWindowToken;
}
diff --git a/services/java/com/android/server/wm/InputFilter.java b/services/java/com/android/server/input/InputFilter.java
similarity index 96%
rename from services/java/com/android/server/wm/InputFilter.java
rename to services/java/com/android/server/input/InputFilter.java
index 8f0001a..2ce0a02 100644
--- a/services/java/com/android/server/wm/InputFilter.java
+++ b/services/java/com/android/server/input/InputFilter.java
@@ -14,7 +14,9 @@
* limitations under the License.
*/
-package com.android.server.wm;
+package com.android.server.input;
+
+import com.android.server.wm.WindowManagerService;
import android.os.Handler;
import android.os.Looper;
@@ -33,7 +35,7 @@
* system's behavior changes as follows:
* <ul>
* <li>Input events are first delivered to the {@link WindowManagerPolicy}
- * interception methods before queueing as usual. This critical step takes care of managing
+ * interception methods before queuing as usual. This critical step takes care of managing
* the power state of the device and handling wake keys.</li>
* <li>Input events are then asynchronously delivered to the input filter's
* {@link #onInputEvent(InputEvent)} method instead of being enqueued for dispatch to
@@ -79,7 +81,7 @@
* {@link WindowManagerPolicy#FLAG_PASS_TO_USER} policy flag. The input filter may
* sometimes receive events that do not have this flag set. It should take note of
* the fact that the policy intends to drop the event, clean up its state, and
- * then send appropriate cancelation events to the dispatcher if needed.
+ * then send appropriate cancellation events to the dispatcher if needed.
* </p><p>
* For example, suppose the input filter is processing a gesture and one of the touch events
* it receives does not have the {@link WindowManagerPolicy#FLAG_PASS_TO_USER} flag set.
@@ -89,8 +91,8 @@
* Corollary: Events that set sent to the dispatcher should usually include the
* {@link WindowManagerPolicy#FLAG_PASS_TO_USER} flag. Otherwise, they will be dropped!
* </p><p>
- * It may be prudent to disable automatic key repeating for synthetically generated
- * keys by setting the {@link WindowManagerPolicy#FLAG_DISABLE_KEY_REPEAT} policy flag.
+ * It may be prudent to disable automatic key repeating for synthetic key events
+ * by setting the {@link WindowManagerPolicy#FLAG_DISABLE_KEY_REPEAT} policy flag.
* </p>
*/
public abstract class InputFilter {
diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java
new file mode 100644
index 0000000..b8cc65e
--- /dev/null
+++ b/services/java/com/android/server/input/InputManagerService.java
@@ -0,0 +1,743 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.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.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.database.ContentObserver;
+import android.hardware.input.IInputManager;
+import android.hardware.input.InputManager;
+import android.os.Binder;
+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.Slog;
+import android.util.Xml;
+import android.view.InputChannel;
+import android.view.InputDevice;
+import android.view.InputEvent;
+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 java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/*
+ * Wraps the C++ InputManager and provides its callbacks.
+ */
+public class InputManagerService extends IInputManager.Stub implements Watchdog.Monitor {
+ static final String TAG = "InputManager";
+ static final boolean DEBUG = false;
+
+ private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml";
+
+ // Pointer to native input manager service object.
+ private final int mPtr;
+
+ private final Context mContext;
+ private final Callbacks mCallbacks;
+ private final Handler mHandler;
+
+ private static native int nativeInit(InputManagerService service,
+ Context context, MessageQueue messageQueue);
+ private static native void nativeStart(int ptr);
+ private static native void nativeSetDisplaySize(int ptr, int displayId,
+ int width, int height, int externalWidth, int externalHeight);
+ private static native void nativeSetDisplayOrientation(int ptr, int displayId, int rotation);
+
+ private static native int nativeGetScanCodeState(int ptr,
+ int deviceId, int sourceMask, int scanCode);
+ private static native int nativeGetKeyCodeState(int ptr,
+ int deviceId, int sourceMask, int keyCode);
+ private static native int nativeGetSwitchState(int ptr,
+ int deviceId, int sourceMask, int sw);
+ private static native boolean nativeHasKeys(int ptr,
+ int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists);
+ private static native void nativeRegisterInputChannel(int ptr, InputChannel inputChannel,
+ InputWindowHandle inputWindowHandle, boolean monitor);
+ private static native void nativeUnregisterInputChannel(int ptr, InputChannel inputChannel);
+ private static native void nativeSetInputFilterEnabled(int ptr, boolean enable);
+ private static native int nativeInjectInputEvent(int ptr, InputEvent event,
+ int injectorPid, int injectorUid, int syncMode, int timeoutMillis,
+ int policyFlags);
+ private static native void nativeSetInputWindows(int ptr, InputWindowHandle[] windowHandles);
+ private static native void nativeSetInputDispatchMode(int ptr, boolean enabled, boolean frozen);
+ private static native void nativeSetSystemUiVisibility(int ptr, int visibility);
+ private static native void nativeSetFocusedApplication(int ptr,
+ InputApplicationHandle application);
+ private static native InputDevice nativeGetInputDevice(int ptr, int deviceId);
+ private static native void nativeGetInputConfiguration(int ptr, Configuration configuration);
+ private static native int[] nativeGetInputDeviceIds(int ptr);
+ private static native boolean nativeTransferTouchFocus(int ptr,
+ InputChannel fromChannel, InputChannel toChannel);
+ private static native void nativeSetPointerSpeed(int ptr, int speed);
+ private static native void nativeSetShowTouches(int ptr, boolean enabled);
+ private static native String nativeDump(int ptr);
+ private static native void nativeMonitor(int ptr);
+
+ // Input event injection constants defined in InputDispatcher.h.
+ private static final int INPUT_EVENT_INJECTION_SUCCEEDED = 0;
+ private static final int INPUT_EVENT_INJECTION_PERMISSION_DENIED = 1;
+ private static final int INPUT_EVENT_INJECTION_FAILED = 2;
+ private static final int INPUT_EVENT_INJECTION_TIMED_OUT = 3;
+
+ // Maximum number of milliseconds to wait for input event injection.
+ private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000;
+
+ // Key states (may be returned by queries about the current state of a
+ // particular key code, scan code or switch).
+
+ /** The key state is unknown or the requested key itself is not supported. */
+ public static final int KEY_STATE_UNKNOWN = -1;
+
+ /** The key is up. /*/
+ public static final int KEY_STATE_UP = 0;
+
+ /** The key is down. */
+ public static final int KEY_STATE_DOWN = 1;
+
+ /** 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;
+
+ // State for the currently installed input filter.
+ final Object mInputFilterLock = new Object();
+ InputFilter mInputFilter;
+ InputFilterHost mInputFilterHost;
+
+ public InputManagerService(Context context, Callbacks callbacks) {
+ this.mContext = context;
+ this.mCallbacks = callbacks;
+ this.mHandler = new Handler();
+
+ Slog.i(TAG, "Initializing input manager");
+ mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
+ }
+
+ public void start() {
+ Slog.i(TAG, "Starting input manager");
+ nativeStart(mPtr);
+
+ // Add ourself to the Watchdog monitors.
+ Watchdog.getInstance().addMonitor(this);
+
+ registerPointerSpeedSettingObserver();
+ registerShowTouchesSettingObserver();
+
+ updatePointerSpeedFromSettings();
+ updateShowTouchesFromSettings();
+ }
+
+ public void setDisplaySize(int displayId, int width, int height,
+ int externalWidth, int externalHeight) {
+ if (width <= 0 || height <= 0 || externalWidth <= 0 || externalHeight <= 0) {
+ throw new IllegalArgumentException("Invalid display id or dimensions.");
+ }
+
+ if (DEBUG) {
+ Slog.d(TAG, "Setting display #" + displayId + " size to " + width + "x" + height
+ + " external size " + externalWidth + "x" + externalHeight);
+ }
+ nativeSetDisplaySize(mPtr, displayId, width, height, externalWidth, externalHeight);
+ }
+
+ public void setDisplayOrientation(int displayId, int rotation) {
+ if (rotation < Surface.ROTATION_0 || rotation > Surface.ROTATION_270) {
+ throw new IllegalArgumentException("Invalid rotation.");
+ }
+
+ if (DEBUG) {
+ Slog.d(TAG, "Setting display #" + displayId + " orientation to " + rotation);
+ }
+ nativeSetDisplayOrientation(mPtr, displayId, rotation);
+ }
+
+ public void getInputConfiguration(Configuration config) {
+ if (config == null) {
+ throw new IllegalArgumentException("config must not be null.");
+ }
+
+ nativeGetInputConfiguration(mPtr, config);
+ }
+
+ /**
+ * Gets the current state of a key or button by key code.
+ * @param deviceId The input device id, or -1 to consult all devices.
+ * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
+ * consider all input sources. An input device is consulted if at least one of its
+ * non-class input source bits matches the specified source mask.
+ * @param keyCode The key code to check.
+ * @return The key state.
+ */
+ public int getKeyCodeState(int deviceId, int sourceMask, int keyCode) {
+ return nativeGetKeyCodeState(mPtr, deviceId, sourceMask, keyCode);
+ }
+
+ /**
+ * Gets the current state of a key or button by scan code.
+ * @param deviceId The input device id, or -1 to consult all devices.
+ * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
+ * consider all input sources. An input device is consulted if at least one of its
+ * non-class input source bits matches the specified source mask.
+ * @param scanCode The scan code to check.
+ * @return The key state.
+ */
+ public int getScanCodeState(int deviceId, int sourceMask, int scanCode) {
+ return nativeGetScanCodeState(mPtr, deviceId, sourceMask, scanCode);
+ }
+
+ /**
+ * Gets the current state of a switch by switch code.
+ * @param deviceId The input device id, or -1 to consult all devices.
+ * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
+ * consider all input sources. An input device is consulted if at least one of its
+ * non-class input source bits matches the specified source mask.
+ * @param switchCode The switch code to check.
+ * @return The switch state.
+ */
+ public int getSwitchState(int deviceId, int sourceMask, int switchCode) {
+ return nativeGetSwitchState(mPtr, deviceId, sourceMask, switchCode);
+ }
+
+ /**
+ * Determines whether the specified key codes are supported by a particular device.
+ * @param deviceId The input device id, or -1 to consult all devices.
+ * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
+ * consider all input sources. An input device is consulted if at least one of its
+ * non-class input source bits matches the specified source mask.
+ * @param keyCodes The array of key codes to check.
+ * @param keyExists An array at least as large as keyCodes whose entries will be set
+ * to true or false based on the presence or absence of support for the corresponding
+ * key codes.
+ * @return True if the lookup was successful, false otherwise.
+ */
+ @Override
+ public boolean hasKeys(int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists) {
+ if (keyCodes == null) {
+ throw new IllegalArgumentException("keyCodes must not be null.");
+ }
+ if (keyExists == null || keyExists.length < keyCodes.length) {
+ throw new IllegalArgumentException("keyExists must not be null and must be at "
+ + "least as large as keyCodes.");
+ }
+
+ return nativeHasKeys(mPtr, deviceId, sourceMask, keyCodes, keyExists);
+ }
+
+ /**
+ * Creates an input channel that will receive all input from the input dispatcher.
+ * @param inputChannelName The input channel name.
+ * @return The input channel.
+ */
+ public InputChannel monitorInput(String inputChannelName) {
+ if (inputChannelName == null) {
+ throw new IllegalArgumentException("inputChannelName must not be null.");
+ }
+
+ InputChannel[] inputChannels = InputChannel.openInputChannelPair(inputChannelName);
+ nativeRegisterInputChannel(mPtr, inputChannels[0], null, true);
+ inputChannels[0].dispose(); // don't need to retain the Java object reference
+ return inputChannels[1];
+ }
+
+ /**
+ * Registers an input channel so that it can be used as an input event target.
+ * @param inputChannel The input channel to register.
+ * @param inputWindowHandle The handle of the input window associated with the
+ * input channel, or null if none.
+ */
+ public void registerInputChannel(InputChannel inputChannel,
+ InputWindowHandle inputWindowHandle) {
+ if (inputChannel == null) {
+ throw new IllegalArgumentException("inputChannel must not be null.");
+ }
+
+ nativeRegisterInputChannel(mPtr, inputChannel, inputWindowHandle, false);
+ }
+
+ /**
+ * Unregisters an input channel.
+ * @param inputChannel The input channel to unregister.
+ */
+ public void unregisterInputChannel(InputChannel inputChannel) {
+ if (inputChannel == null) {
+ throw new IllegalArgumentException("inputChannel must not be null.");
+ }
+
+ nativeUnregisterInputChannel(mPtr, inputChannel);
+ }
+
+ /**
+ * Sets an input filter that will receive all input events before they are dispatched.
+ * The input filter may then reinterpret input events or inject new ones.
+ *
+ * To ensure consistency, the input dispatcher automatically drops all events
+ * in progress whenever an input filter is installed or uninstalled. After an input
+ * filter is uninstalled, it can no longer send input events unless it is reinstalled.
+ * Any events it attempts to send after it has been uninstalled will be dropped.
+ *
+ * @param filter The input filter, or null to remove the current filter.
+ */
+ public void setInputFilter(InputFilter filter) {
+ synchronized (mInputFilterLock) {
+ final InputFilter oldFilter = mInputFilter;
+ if (oldFilter == filter) {
+ return; // nothing to do
+ }
+
+ if (oldFilter != null) {
+ mInputFilter = null;
+ mInputFilterHost.disconnectLocked();
+ mInputFilterHost = null;
+ oldFilter.uninstall();
+ }
+
+ if (filter != null) {
+ mInputFilter = filter;
+ mInputFilterHost = new InputFilterHost();
+ filter.install(mInputFilterHost);
+ }
+
+ nativeSetInputFilterEnabled(mPtr, filter != null);
+ }
+ }
+
+ @Override
+ public boolean injectInputEvent(InputEvent event, int mode) {
+ if (event == null) {
+ throw new IllegalArgumentException("event must not be null");
+ }
+ if (mode != InputManager.INJECT_INPUT_EVENT_MODE_ASYNC
+ && mode != InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH
+ && mode != InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT) {
+ throw new IllegalArgumentException("mode is invalid");
+ }
+
+ final int pid = Binder.getCallingPid();
+ final int uid = Binder.getCallingUid();
+ final long ident = Binder.clearCallingIdentity();
+ final int result;
+ try {
+ result = nativeInjectInputEvent(mPtr, event, pid, uid, mode,
+ INJECTION_TIMEOUT_MILLIS, WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ switch (result) {
+ case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
+ Slog.w(TAG, "Input event injection from pid " + pid + " permission denied.");
+ throw new SecurityException(
+ "Injecting to another application requires INJECT_EVENTS permission");
+ case INPUT_EVENT_INJECTION_SUCCEEDED:
+ return true;
+ case INPUT_EVENT_INJECTION_TIMED_OUT:
+ Slog.w(TAG, "Input event injection from pid " + pid + " timed out.");
+ return false;
+ case INPUT_EVENT_INJECTION_FAILED:
+ default:
+ Slog.w(TAG, "Input event injection from pid " + pid + " failed.");
+ return false;
+ }
+ }
+
+ /**
+ * Gets information about the input device with the specified id.
+ * @param id The device id.
+ * @return The input device or null if not found.
+ */
+ @Override
+ public InputDevice getInputDevice(int deviceId) {
+ return nativeGetInputDevice(mPtr, deviceId);
+ }
+
+ /**
+ * Gets the ids of all input devices in the system.
+ * @return The input device ids.
+ */
+ @Override
+ public int[] getInputDeviceIds() {
+ return nativeGetInputDeviceIds(mPtr);
+ }
+
+ public void setInputWindows(InputWindowHandle[] windowHandles) {
+ nativeSetInputWindows(mPtr, windowHandles);
+ }
+
+ public void setFocusedApplication(InputApplicationHandle application) {
+ nativeSetFocusedApplication(mPtr, application);
+ }
+
+ public void setInputDispatchMode(boolean enabled, boolean frozen) {
+ nativeSetInputDispatchMode(mPtr, enabled, frozen);
+ }
+
+ public void setSystemUiVisibility(int visibility) {
+ nativeSetSystemUiVisibility(mPtr, visibility);
+ }
+
+ /**
+ * Atomically transfers touch focus from one window to another as identified by
+ * their input channels. It is possible for multiple windows to have
+ * touch focus if they support split touch dispatch
+ * {@link android.view.WindowManager.LayoutParams#FLAG_SPLIT_TOUCH} but this
+ * method only transfers touch focus of the specified window without affecting
+ * other windows that may also have touch focus at the same time.
+ * @param fromChannel The channel of a window that currently has touch focus.
+ * @param toChannel The channel of the window that should receive touch focus in
+ * place of the first.
+ * @return True if the transfer was successful. False if the window with the
+ * specified channel did not actually have touch focus at the time of the request.
+ */
+ public boolean transferTouchFocus(InputChannel fromChannel, InputChannel toChannel) {
+ if (fromChannel == null) {
+ throw new IllegalArgumentException("fromChannel must not be null.");
+ }
+ if (toChannel == null) {
+ throw new IllegalArgumentException("toChannel must not be null.");
+ }
+ 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
+ public void tryPointerSpeed(int speed) {
+ if (!checkCallingPermission(android.Manifest.permission.SET_POINTER_SPEED,
+ "tryPointerSpeed()")) {
+ throw new SecurityException("Requires SET_POINTER_SPEED permission");
+ }
+
+ setPointerSpeedUnchecked(speed);
+ }
+
+ public void updatePointerSpeedFromSettings() {
+ int speed = getPointerSpeedSetting();
+ setPointerSpeedUnchecked(speed);
+ }
+
+ private void setPointerSpeedUnchecked(int speed) {
+ speed = Math.min(Math.max(speed, InputManager.MIN_POINTER_SPEED),
+ InputManager.MAX_POINTER_SPEED);
+ nativeSetPointerSpeed(mPtr, speed);
+ }
+
+ private void registerPointerSpeedSettingObserver() {
+ mContext.getContentResolver().registerContentObserver(
+ Settings.System.getUriFor(Settings.System.POINTER_SPEED), true,
+ new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ updatePointerSpeedFromSettings();
+ }
+ });
+ }
+
+ private int getPointerSpeedSetting() {
+ int speed = InputManager.DEFAULT_POINTER_SPEED;
+ try {
+ speed = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.POINTER_SPEED);
+ } catch (SettingNotFoundException snfe) {
+ }
+ return speed;
+ }
+
+ public void updateShowTouchesFromSettings() {
+ int setting = getShowTouchesSetting(0);
+ nativeSetShowTouches(mPtr, setting != 0);
+ }
+
+ private void registerShowTouchesSettingObserver() {
+ mContext.getContentResolver().registerContentObserver(
+ Settings.System.getUriFor(Settings.System.SHOW_TOUCHES), true,
+ new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ updateShowTouchesFromSettings();
+ }
+ });
+ }
+
+ private int getShowTouchesSetting(int defaultValue) {
+ int result = defaultValue;
+ try {
+ result = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.SHOW_TOUCHES);
+ } catch (SettingNotFoundException snfe) {
+ }
+ return result;
+ }
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
+ != PackageManager.PERMISSION_GRANTED) {
+ pw.println("Permission Denial: can't dump InputManager from from pid="
+ + Binder.getCallingPid()
+ + ", uid=" + Binder.getCallingUid());
+ return;
+ }
+
+ pw.println("INPUT MANAGER (dumpsys input)\n");
+ String dumpStr = nativeDump(mPtr);
+ if (dumpStr != null) {
+ pw.println(dumpStr);
+ }
+ }
+
+ private boolean checkCallingPermission(String permission, String func) {
+ // Quick check: if the calling permission is me, it's all okay.
+ if (Binder.getCallingPid() == Process.myPid()) {
+ return true;
+ }
+
+ if (mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED) {
+ return true;
+ }
+ String msg = "Permission Denial: " + func + " from pid="
+ + Binder.getCallingPid()
+ + ", uid=" + Binder.getCallingUid()
+ + " requires " + permission;
+ Slog.w(TAG, msg);
+ return false;
+ }
+
+ // Called by the heartbeat to ensure locks are not held indefinitely (for deadlock detection).
+ public void monitor() {
+ synchronized (mInputFilterLock) { }
+ nativeMonitor(mPtr);
+ }
+
+ // Native callback.
+ private void notifyConfigurationChanged(long whenNanos) {
+ mCallbacks.notifyConfigurationChanged();
+ }
+
+ // Native callback.
+ private void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
+ mCallbacks.notifyLidSwitchChanged(whenNanos, lidOpen);
+ }
+
+ // Native callback.
+ private void notifyInputChannelBroken(InputWindowHandle inputWindowHandle) {
+ mCallbacks.notifyInputChannelBroken(inputWindowHandle);
+ }
+
+ // Native callback.
+ private long notifyANR(InputApplicationHandle inputApplicationHandle,
+ InputWindowHandle inputWindowHandle) {
+ return mCallbacks.notifyANR(inputApplicationHandle, inputWindowHandle);
+ }
+
+ // Native callback.
+ final boolean filterInputEvent(InputEvent event, int policyFlags) {
+ synchronized (mInputFilterLock) {
+ if (mInputFilter != null) {
+ mInputFilter.filterInputEvent(event, policyFlags);
+ return false;
+ }
+ }
+ event.recycle();
+ return true;
+ }
+
+ // Native callback.
+ private int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn) {
+ return mCallbacks.interceptKeyBeforeQueueing(
+ event, policyFlags, isScreenOn);
+ }
+
+ // Native callback.
+ private int interceptMotionBeforeQueueingWhenScreenOff(int policyFlags) {
+ return mCallbacks.interceptMotionBeforeQueueingWhenScreenOff(policyFlags);
+ }
+
+ // Native callback.
+ private long interceptKeyBeforeDispatching(InputWindowHandle focus,
+ KeyEvent event, int policyFlags) {
+ return mCallbacks.interceptKeyBeforeDispatching(focus, event, policyFlags);
+ }
+
+ // Native callback.
+ private KeyEvent dispatchUnhandledKey(InputWindowHandle focus,
+ KeyEvent event, int policyFlags) {
+ return mCallbacks.dispatchUnhandledKey(focus, event, policyFlags);
+ }
+
+ // Native callback.
+ private boolean checkInjectEventsPermission(int injectorPid, int injectorUid) {
+ return mContext.checkPermission(android.Manifest.permission.INJECT_EVENTS,
+ injectorPid, injectorUid) == PackageManager.PERMISSION_GRANTED;
+ }
+
+ // Native callback.
+ private int getVirtualKeyQuietTimeMillis() {
+ return mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_virtualKeyQuietTimeMillis);
+ }
+
+ // Native callback.
+ private String[] getExcludedDeviceNames() {
+ ArrayList<String> names = new ArrayList<String>();
+
+ // Read partner-provided list of excluded input devices
+ XmlPullParser parser = null;
+ // Environment.getRootDirectory() is a fancy way of saying ANDROID_ROOT or "/system".
+ File confFile = new File(Environment.getRootDirectory(), EXCLUDED_DEVICES_PATH);
+ FileReader confreader = null;
+ try {
+ confreader = new FileReader(confFile);
+ parser = Xml.newPullParser();
+ parser.setInput(confreader);
+ XmlUtils.beginDocument(parser, "devices");
+
+ while (true) {
+ XmlUtils.nextElement(parser);
+ if (!"device".equals(parser.getName())) {
+ break;
+ }
+ String name = parser.getAttributeValue(null, "name");
+ if (name != null) {
+ names.add(name);
+ }
+ }
+ } catch (FileNotFoundException e) {
+ // It's ok if the file does not exist.
+ } catch (Exception e) {
+ Slog.e(TAG, "Exception while parsing '" + confFile.getAbsolutePath() + "'", e);
+ } finally {
+ try { if (confreader != null) confreader.close(); } catch (IOException e) { }
+ }
+
+ return names.toArray(new String[names.size()]);
+ }
+
+ // Native callback.
+ private int getKeyRepeatTimeout() {
+ return ViewConfiguration.getKeyRepeatTimeout();
+ }
+
+ // Native callback.
+ private int getKeyRepeatDelay() {
+ return ViewConfiguration.getKeyRepeatDelay();
+ }
+
+ // Native callback.
+ private int getHoverTapTimeout() {
+ return ViewConfiguration.getHoverTapTimeout();
+ }
+
+ // Native callback.
+ private int getHoverTapSlop() {
+ return ViewConfiguration.getHoverTapSlop();
+ }
+
+ // Native callback.
+ private int getDoubleTapTimeout() {
+ return ViewConfiguration.getDoubleTapTimeout();
+ }
+
+ // Native callback.
+ private int getLongPressTimeout() {
+ return ViewConfiguration.getLongPressTimeout();
+ }
+
+ // Native callback.
+ private int getPointerLayer() {
+ return mCallbacks.getPointerLayer();
+ }
+
+ // Native callback.
+ private PointerIcon getPointerIcon() {
+ return PointerIcon.getDefaultIcon(mContext);
+ }
+
+ /**
+ * Callback interface implemented by the Window Manager.
+ */
+ public interface Callbacks {
+ public void notifyConfigurationChanged();
+
+ public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen);
+
+ public void notifyInputChannelBroken(InputWindowHandle inputWindowHandle);
+
+ public long notifyANR(InputApplicationHandle inputApplicationHandle,
+ InputWindowHandle inputWindowHandle);
+
+ public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn);
+
+ public int interceptMotionBeforeQueueingWhenScreenOff(int policyFlags);
+
+ public long interceptKeyBeforeDispatching(InputWindowHandle focus,
+ KeyEvent event, int policyFlags);
+
+ public KeyEvent dispatchUnhandledKey(InputWindowHandle focus,
+ KeyEvent event, int policyFlags);
+
+ public int getPointerLayer();
+ }
+
+ /**
+ * Hosting interface for input filters to call back into the input manager.
+ */
+ private final class InputFilterHost implements InputFilter.Host {
+ private boolean mDisconnected;
+
+ public void disconnectLocked() {
+ mDisconnected = true;
+ }
+
+ public void sendInputEvent(InputEvent event, int policyFlags) {
+ if (event == null) {
+ throw new IllegalArgumentException("event must not be null");
+ }
+
+ synchronized (mInputFilterLock) {
+ if (!mDisconnected) {
+ nativeInjectInputEvent(mPtr, event, 0, 0,
+ InputManager.INJECT_INPUT_EVENT_MODE_ASYNC, 0,
+ policyFlags | WindowManagerPolicy.FLAG_FILTERED);
+ }
+ }
+ }
+ }
+}
diff --git a/services/java/com/android/server/wm/InputWindowHandle.java b/services/java/com/android/server/input/InputWindowHandle.java
similarity index 93%
rename from services/java/com/android/server/wm/InputWindowHandle.java
rename to services/java/com/android/server/input/InputWindowHandle.java
index 264877c..03d66af 100644
--- a/services/java/com/android/server/wm/InputWindowHandle.java
+++ b/services/java/com/android/server/input/InputWindowHandle.java
@@ -14,11 +14,10 @@
* limitations under the License.
*/
-package com.android.server.wm;
+package com.android.server.input;
import android.graphics.Region;
import android.view.InputChannel;
-import android.view.WindowManagerPolicy;
/**
* Functions as a handle for a window that can receive input.
@@ -35,7 +34,7 @@
public final InputApplicationHandle inputApplicationHandle;
// The window manager's window state.
- public final WindowManagerPolicy.WindowState windowState;
+ public final Object windowState;
// The input channel associated with the window.
public InputChannel inputChannel;
@@ -91,7 +90,7 @@
private native void nativeDispose();
public InputWindowHandle(InputApplicationHandle inputApplicationHandle,
- WindowManagerPolicy.WindowState windowState) {
+ Object windowState) {
this.inputApplicationHandle = inputApplicationHandle;
this.windowState = windowState;
}
diff --git a/services/java/com/android/server/net/NetworkIdentitySet.java b/services/java/com/android/server/net/NetworkIdentitySet.java
index af03fb3..397f9f4 100644
--- a/services/java/com/android/server/net/NetworkIdentitySet.java
+++ b/services/java/com/android/server/net/NetworkIdentitySet.java
@@ -21,7 +21,6 @@
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
-import java.net.ProtocolException;
import java.util.HashSet;
/**
@@ -33,48 +32,46 @@
public class NetworkIdentitySet extends HashSet<NetworkIdentity> {
private static final int VERSION_INIT = 1;
private static final int VERSION_ADD_ROAMING = 2;
+ private static final int VERSION_ADD_NETWORK_ID = 3;
public NetworkIdentitySet() {
}
public NetworkIdentitySet(DataInputStream in) throws IOException {
final int version = in.readInt();
- switch (version) {
- case VERSION_INIT: {
- final int size = in.readInt();
- for (int i = 0; i < size; i++) {
- final int ignoredVersion = in.readInt();
- final int type = in.readInt();
- final int subType = in.readInt();
- final String subscriberId = readOptionalString(in);
- add(new NetworkIdentity(type, subType, subscriberId, false));
- }
- break;
+ final int size = in.readInt();
+ for (int i = 0; i < size; i++) {
+ if (version <= VERSION_INIT) {
+ final int ignored = in.readInt();
}
- case VERSION_ADD_ROAMING: {
- final int size = in.readInt();
- for (int i = 0; i < size; i++) {
- final int type = in.readInt();
- final int subType = in.readInt();
- final String subscriberId = readOptionalString(in);
- final boolean roaming = in.readBoolean();
- add(new NetworkIdentity(type, subType, subscriberId, roaming));
- }
- break;
+ final int type = in.readInt();
+ final int subType = in.readInt();
+ final String subscriberId = readOptionalString(in);
+ final String networkId;
+ if (version >= VERSION_ADD_NETWORK_ID) {
+ networkId = readOptionalString(in);
+ } else {
+ networkId = null;
}
- default: {
- throw new ProtocolException("unexpected version: " + version);
+ final boolean roaming;
+ if (version >= VERSION_ADD_ROAMING) {
+ roaming = in.readBoolean();
+ } else {
+ roaming = false;
}
+
+ add(new NetworkIdentity(type, subType, subscriberId, networkId, false));
}
}
public void writeToStream(DataOutputStream out) throws IOException {
- out.writeInt(VERSION_ADD_ROAMING);
+ out.writeInt(VERSION_ADD_NETWORK_ID);
out.writeInt(size());
for (NetworkIdentity ident : this) {
out.writeInt(ident.getType());
out.writeInt(ident.getSubType());
writeOptionalString(out, ident.getSubscriberId());
+ writeOptionalString(out, ident.getNetworkId());
out.writeBoolean(ident.getRoaming());
}
}
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 1f1e720..b0657a6 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -48,6 +48,7 @@
import static android.net.NetworkTemplate.MATCH_WIFI;
import static android.net.NetworkTemplate.buildTemplateMobileAll;
import static android.net.TrafficStats.MB_IN_BYTES;
+import static android.telephony.TelephonyManager.SIM_STATE_READY;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static com.android.internal.util.Preconditions.checkNotNull;
import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
@@ -113,6 +114,7 @@
import com.android.internal.R;
import com.android.internal.os.AtomicFile;
import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Objects;
import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
@@ -160,6 +162,8 @@
private static final int VERSION_ADDED_TIMEZONE = 6;
private static final int VERSION_ADDED_INFERRED = 7;
private static final int VERSION_SWITCH_APP_ID = 8;
+ private static final int VERSION_ADDED_NETWORK_ID = 9;
+ private static final int VERSION_LATEST = VERSION_ADDED_NETWORK_ID;
// @VisibleForTesting
public static final int TYPE_WARNING = 0x1;
@@ -175,6 +179,7 @@
private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground";
private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate";
private static final String ATTR_SUBSCRIBER_ID = "subscriberId";
+ private static final String ATTR_NETWORK_ID = "networkId";
private static final String ATTR_CYCLE_DAY = "cycleDay";
private static final String ATTR_CYCLE_TIMEZONE = "cycleTimezone";
private static final String ATTR_WARNING_BYTES = "warningBytes";
@@ -491,6 +496,7 @@
for (NetworkPolicy policy : mNetworkPolicy.values()) {
// ignore policies that aren't relevant to user
if (!isTemplateRelevant(policy.template)) continue;
+ if (!policy.hasCycle()) continue;
final long start = computeLastCycleBoundary(currentTime, policy);
final long end = currentTime;
@@ -528,21 +534,24 @@
/**
* Test if given {@link NetworkTemplate} is relevant to user based on
- * current device state, such as when {@link #getActiveSubscriberId()}
- * matches. This is regardless of data connection status.
+ * current device state, such as when
+ * {@link TelephonyManager#getSubscriberId()} matches. This is regardless of
+ * data connection status.
*/
private boolean isTemplateRelevant(NetworkTemplate template) {
+ final TelephonyManager tele = TelephonyManager.from(mContext);
+
switch (template.getMatchRule()) {
case MATCH_MOBILE_3G_LOWER:
case MATCH_MOBILE_4G:
case MATCH_MOBILE_ALL:
- // mobile templates aren't relevant in airplane mode
- if (isAirplaneModeOn(mContext)) {
+ // mobile templates are relevant when SIM is ready and
+ // subscriberId matches.
+ if (tele.getSimState() == SIM_STATE_READY) {
+ return Objects.equal(tele.getSubscriberId(), template.getSubscriberId());
+ } else {
return false;
}
-
- // mobile templates are relevant when subscriberid is active
- return Objects.equal(getActiveSubscriberId(), template.getSubscriberId());
}
return true;
}
@@ -761,7 +770,7 @@
final long currentTime = currentTimeMillis();
for (NetworkPolicy policy : mNetworkPolicy.values()) {
// shortcut when policy has no limit
- if (policy.limitBytes == LIMIT_DISABLED) {
+ if (policy.limitBytes == LIMIT_DISABLED || !policy.hasCycle()) {
setNetworkTemplateEnabled(policy.template, true);
continue;
}
@@ -784,13 +793,16 @@
* for the given {@link NetworkTemplate}.
*/
private void setNetworkTemplateEnabled(NetworkTemplate template, boolean enabled) {
+ final TelephonyManager tele = TelephonyManager.from(mContext);
+
switch (template.getMatchRule()) {
case MATCH_MOBILE_3G_LOWER:
case MATCH_MOBILE_4G:
case MATCH_MOBILE_ALL:
// TODO: offer more granular control over radio states once
// 4965893 is available.
- if (Objects.equal(getActiveSubscriberId(), template.getSubscriberId())) {
+ if (tele.getSimState() == SIM_STATE_READY
+ && Objects.equal(tele.getSubscriberId(), template.getSubscriberId())) {
setPolicyDataEnable(TYPE_MOBILE, enabled);
setPolicyDataEnable(TYPE_WIMAX, enabled);
}
@@ -863,9 +875,15 @@
for (NetworkPolicy policy : mNetworkRules.keySet()) {
final String[] ifaces = mNetworkRules.get(policy);
- final long start = computeLastCycleBoundary(currentTime, policy);
- final long end = currentTime;
- final long totalBytes = getTotalBytes(policy.template, start, end);
+ final long start;
+ final long totalBytes;
+ if (policy.hasCycle()) {
+ start = computeLastCycleBoundary(currentTime, policy);
+ totalBytes = getTotalBytes(policy.template, start, currentTime);
+ } else {
+ start = Long.MAX_VALUE;
+ totalBytes = 0;
+ }
if (LOGD) {
Slog.d(TAG, "applying policy " + policy.toString() + " to ifaces "
@@ -923,9 +941,14 @@
if (LOGV) Slog.v(TAG, "ensureActiveMobilePolicyLocked()");
if (mSuppressDefaultPolicy) return;
- final String subscriberId = getActiveSubscriberId();
+ final TelephonyManager tele = TelephonyManager.from(mContext);
+
+ // avoid creating policy when SIM isn't ready
+ if (tele.getSimState() != SIM_STATE_READY) return;
+
+ final String subscriberId = tele.getSubscriberId();
final NetworkIdentity probeIdent = new NetworkIdentity(
- TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, false);
+ TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false);
// examine to see if any policy is defined for active mobile
boolean mobileDefined = false;
@@ -986,6 +1009,12 @@
} else if (TAG_NETWORK_POLICY.equals(tag)) {
final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE);
final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID);
+ final String networkId;
+ if (version >= VERSION_ADDED_NETWORK_ID) {
+ networkId = in.getAttributeValue(null, ATTR_NETWORK_ID);
+ } else {
+ networkId = null;
+ }
final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY);
final String cycleTimezone;
if (version >= VERSION_ADDED_TIMEZONE) {
@@ -1031,12 +1060,12 @@
}
final NetworkTemplate template = new NetworkTemplate(
- networkTemplate, subscriberId);
+ networkTemplate, subscriberId, networkId);
mNetworkPolicy.put(template, new NetworkPolicy(template, cycleDay,
cycleTimezone, warningBytes, limitBytes, lastWarningSnooze,
lastLimitSnooze, metered, inferred));
- } else if (TAG_UID_POLICY.equals(tag)) {
+ } else if (TAG_UID_POLICY.equals(tag) && version < VERSION_SWITCH_APP_ID) {
final int uid = readIntAttribute(in, ATTR_UID);
final int policy = readIntAttribute(in, ATTR_POLICY);
@@ -1046,7 +1075,7 @@
} else {
Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
}
- } else if (TAG_APP_POLICY.equals(tag)) {
+ } else if (TAG_APP_POLICY.equals(tag) && version >= VERSION_SWITCH_APP_ID) {
final int appId = readIntAttribute(in, ATTR_APP_ID);
final int policy = readIntAttribute(in, ATTR_POLICY);
@@ -1099,7 +1128,7 @@
out.startDocument(null, true);
out.startTag(null, TAG_POLICY_LIST);
- writeIntAttribute(out, ATTR_VERSION, VERSION_SWITCH_APP_ID);
+ writeIntAttribute(out, ATTR_VERSION, VERSION_LATEST);
writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground);
// write all known network policies
@@ -1112,6 +1141,10 @@
if (subscriberId != null) {
out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId);
}
+ final String networkId = template.getNetworkId();
+ if (networkId != null) {
+ out.attribute(null, ATTR_NETWORK_ID, networkId);
+ }
writeIntAttribute(out, ATTR_CYCLE_DAY, policy.cycleDay);
out.attribute(null, ATTR_CYCLE_TIMEZONE, policy.cycleTimezone);
writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes);
@@ -1318,7 +1351,7 @@
policy = findPolicyForNetworkLocked(ident);
}
- if (policy == null) {
+ if (policy == null || !policy.hasCycle()) {
// missing policy means we can't derive useful quota info
return null;
}
@@ -1340,9 +1373,11 @@
}
@Override
- protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
+ protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
mContext.enforceCallingOrSelfPermission(DUMP, TAG);
+ final IndentingPrintWriter fout = new IndentingPrintWriter(writer, " ");
+
final HashSet<String> argSet = new HashSet<String>();
for (String arg : args) {
argSet.add(arg);
@@ -1365,31 +1400,36 @@
fout.print("Restrict background: "); fout.println(mRestrictBackground);
fout.println("Network policies:");
+ fout.increaseIndent();
for (NetworkPolicy policy : mNetworkPolicy.values()) {
- fout.print(" "); fout.println(policy.toString());
+ fout.println(policy.toString());
}
+ fout.decreaseIndent();
fout.println("Policy for apps:");
+ fout.increaseIndent();
int size = mAppPolicy.size();
for (int i = 0; i < size; i++) {
final int appId = mAppPolicy.keyAt(i);
final int policy = mAppPolicy.valueAt(i);
- fout.print(" appId=");
+ fout.print("appId=");
fout.print(appId);
fout.print(" policy=");
dumpPolicy(fout, policy);
fout.println();
}
+ fout.decreaseIndent();
final SparseBooleanArray knownUids = new SparseBooleanArray();
collectKeys(mUidForeground, knownUids);
collectKeys(mUidRules, knownUids);
fout.println("Status for known UIDs:");
+ fout.increaseIndent();
size = knownUids.size();
for (int i = 0; i < size; i++) {
final int uid = knownUids.keyAt(i);
- fout.print(" UID=");
+ fout.print("UID=");
fout.print(uid);
fout.print(" foreground=");
@@ -1410,6 +1450,7 @@
fout.println();
}
+ fout.decreaseIndent();
}
}
@@ -1697,12 +1738,6 @@
}
}
- private String getActiveSubscriberId() {
- final TelephonyManager telephony = (TelephonyManager) mContext.getSystemService(
- Context.TELEPHONY_SERVICE);
- return telephony.getSubscriberId();
- }
-
private long getTotalBytes(NetworkTemplate template, long start, long end) {
try {
return mNetworkStats.getSummaryForNetwork(template, start, end).getTotalBytes();
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index 8796afc..b847673 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -34,7 +34,7 @@
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkTemplate.buildTemplateMobileAll;
-import static android.net.NetworkTemplate.buildTemplateWifi;
+import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
import static android.net.TrafficStats.MB_IN_BYTES;
import static android.provider.Settings.Secure.NETSTATS_DEV_BUCKET_DURATION;
import static android.provider.Settings.Secure.NETSTATS_DEV_DELETE_AGE;
@@ -836,7 +836,7 @@
trustedTime);
// collect wifi sample
- template = buildTemplateWifi();
+ template = buildTemplateWifiWildcard();
devTotal = mDevRecorder.getTotalSinceBootLocked(template);
xtTotal = new NetworkStats.Entry();
uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java
index 4bea5e4..1bd15f6 100644
--- a/services/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/java/com/android/server/usb/UsbDeviceManager.java
@@ -60,6 +60,7 @@
import java.util.List;
import java.util.HashMap;
import java.util.Map;
+import java.util.Scanner;
/**
* UsbDeviceManager manages USB state in device mode.
@@ -81,6 +82,8 @@
"/sys/class/android_usb/android0/f_mass_storage/lun/file";
private static final String RNDIS_ETH_ADDR_PATH =
"/sys/class/android_usb/android0/f_rndis/ethaddr";
+ private static final String AUDIO_SOURCE_PCM_PATH =
+ "/sys/class/android_usb/android0/f_audio_source/pcm";
private static final int MSG_UPDATE_STATE = 0;
private static final int MSG_ENABLE_ADB = 1;
@@ -105,6 +108,7 @@
private final boolean mHasUsbAccessory;
private boolean mUseUsbNotification;
private boolean mAdbEnabled;
+ private boolean mAudioSourceEnabled;
private Map<String, List<Pair<String, String>>> mOemModeMap;
private class AdbSettingsObserver extends ContentObserver {
@@ -291,6 +295,8 @@
String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
updateState(state);
mAdbEnabled = containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ADB);
+ mAudioSourceEnabled = containsFunction(mCurrentFunctions,
+ UsbManager.USB_FUNCTION_AUDIO_SOURCE);
// Upgrade step for previous versions that used persist.service.adb.enable
String value = SystemProperties.get("persist.service.adb.enable", "");
@@ -504,6 +510,28 @@
mContext.sendStickyBroadcast(intent);
}
+ private void updateAudioSourceFunction(boolean enabled) {
+ // send a sticky broadcast containing current USB state
+ Intent intent = new Intent(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG);
+ intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ intent.putExtra("state", (enabled ? 1 : 0));
+ if (enabled) {
+ try {
+ Scanner scanner = new Scanner(new File(AUDIO_SOURCE_PCM_PATH));
+ int card = scanner.nextInt();
+ int device = scanner.nextInt();
+ intent.putExtra("card", card);
+ intent.putExtra("device", device);
+ } catch (FileNotFoundException e) {
+ Slog.e(TAG, "could not open audio source PCM file", e);
+ }
+ }
+
+ mContext.sendStickyBroadcast(intent);
+ mAudioSourceEnabled = enabled;
+ }
+
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
@@ -523,6 +551,11 @@
}
if (mBootCompleted) {
updateUsbState();
+ boolean audioSourceEnabled = containsFunction(mCurrentFunctions,
+ UsbManager.USB_FUNCTION_AUDIO_SOURCE);
+ if (audioSourceEnabled != mAudioSourceEnabled) {
+ updateAudioSourceFunction(audioSourceEnabled);
+ }
}
break;
case MSG_ENABLE_ADB:
@@ -543,6 +576,7 @@
if (mCurrentAccessory != null) {
mSettingsManager.accessoryAttached(mCurrentAccessory);
}
+ updateAudioSourceFunction(mAudioSourceEnabled);
break;
}
}
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java
index e3d46d8..1f8348d 100644
--- a/services/java/com/android/server/wm/AppWindowToken.java
+++ b/services/java/com/android/server/wm/AppWindowToken.java
@@ -18,6 +18,7 @@
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import com.android.server.input.InputApplicationHandle;
import com.android.server.wm.WindowManagerService.H;
import android.content.pm.ActivityInfo;
@@ -285,4 +286,4 @@
}
return stringName;
}
-}
\ No newline at end of file
+}
diff --git a/services/java/com/android/server/wm/DragState.java b/services/java/com/android/server/wm/DragState.java
index a19035a..b2cf3e0c 100644
--- a/services/java/com/android/server/wm/DragState.java
+++ b/services/java/com/android/server/wm/DragState.java
@@ -16,6 +16,8 @@
package com.android.server.wm;
+import com.android.server.input.InputApplicationHandle;
+import com.android.server.input.InputWindowHandle;
import com.android.server.wm.WindowManagerService.DragInputEventReceiver;
import com.android.server.wm.WindowManagerService.H;
diff --git a/services/java/com/android/server/wm/FakeWindowImpl.java b/services/java/com/android/server/wm/FakeWindowImpl.java
index 121ce18..2527f46 100644
--- a/services/java/com/android/server/wm/FakeWindowImpl.java
+++ b/services/java/com/android/server/wm/FakeWindowImpl.java
@@ -16,6 +16,9 @@
package com.android.server.wm;
+import com.android.server.input.InputApplicationHandle;
+import com.android.server.input.InputWindowHandle;
+
import android.os.Looper;
import android.os.Process;
import android.util.Slog;
diff --git a/services/java/com/android/server/wm/InputManager.java b/services/java/com/android/server/wm/InputManager.java
deleted file mode 100644
index 56c3519..0000000
--- a/services/java/com/android/server/wm/InputManager.java
+++ /dev/null
@@ -1,683 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm;
-
-import com.android.internal.util.XmlUtils;
-import com.android.server.Watchdog;
-
-import org.xmlpull.v1.XmlPullParser;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.res.Configuration;
-import android.database.ContentObserver;
-import android.os.Environment;
-import android.os.Looper;
-import android.os.MessageQueue;
-import android.os.SystemProperties;
-import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
-import android.util.Slog;
-import android.util.Xml;
-import android.view.InputChannel;
-import android.view.InputDevice;
-import android.view.InputEvent;
-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 java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-
-/*
- * Wraps the C++ InputManager and provides its callbacks.
- */
-public class InputManager implements Watchdog.Monitor {
- static final String TAG = "InputManager";
-
- private static final boolean DEBUG = false;
-
- private final Callbacks mCallbacks;
- private final Context mContext;
- private final WindowManagerService mWindowManagerService;
-
- private static native void nativeInit(Context context,
- Callbacks callbacks, MessageQueue messageQueue);
- private static native void nativeStart();
- private static native void nativeSetDisplaySize(int displayId, int width, int height,
- int externalWidth, int externalHeight);
- private static native void nativeSetDisplayOrientation(int displayId, int rotation);
-
- private static native int nativeGetScanCodeState(int deviceId, int sourceMask,
- int scanCode);
- private static native int nativeGetKeyCodeState(int deviceId, int sourceMask,
- int keyCode);
- private static native int nativeGetSwitchState(int deviceId, int sourceMask,
- int sw);
- private static native boolean nativeHasKeys(int deviceId, int sourceMask,
- int[] keyCodes, boolean[] keyExists);
- private static native void nativeRegisterInputChannel(InputChannel inputChannel,
- InputWindowHandle inputWindowHandle, boolean monitor);
- private static native void nativeUnregisterInputChannel(InputChannel inputChannel);
- private static native void nativeSetInputFilterEnabled(boolean enable);
- private static native int nativeInjectInputEvent(InputEvent event,
- int injectorPid, int injectorUid, int syncMode, int timeoutMillis,
- int policyFlags);
- private static native void nativeSetInputWindows(InputWindowHandle[] windowHandles);
- private static native void nativeSetInputDispatchMode(boolean enabled, boolean frozen);
- private static native void nativeSetSystemUiVisibility(int visibility);
- private static native void nativeSetFocusedApplication(InputApplicationHandle application);
- private static native InputDevice nativeGetInputDevice(int deviceId);
- private static native void nativeGetInputConfiguration(Configuration configuration);
- private static native int[] nativeGetInputDeviceIds();
- private static native boolean nativeTransferTouchFocus(InputChannel fromChannel,
- InputChannel toChannel);
- private static native void nativeSetPointerSpeed(int speed);
- private static native void nativeSetShowTouches(boolean enabled);
- private static native String nativeDump();
- private static native void nativeMonitor();
-
- // Input event injection constants defined in InputDispatcher.h.
- static final int INPUT_EVENT_INJECTION_SUCCEEDED = 0;
- static final int INPUT_EVENT_INJECTION_PERMISSION_DENIED = 1;
- static final int INPUT_EVENT_INJECTION_FAILED = 2;
- static final int INPUT_EVENT_INJECTION_TIMED_OUT = 3;
-
- // Input event injection synchronization modes defined in InputDispatcher.h
- static final int INPUT_EVENT_INJECTION_SYNC_NONE = 0;
- static final int INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT = 1;
- static final int INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH = 2;
-
- // Key states (may be returned by queries about the current state of a
- // particular key code, scan code or switch).
-
- /** The key state is unknown or the requested key itself is not supported. */
- public static final int KEY_STATE_UNKNOWN = -1;
-
- /** The key is up. /*/
- public static final int KEY_STATE_UP = 0;
-
- /** The key is down. */
- public static final int KEY_STATE_DOWN = 1;
-
- /** 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;
-
- // State for the currently installed input filter.
- final Object mInputFilterLock = new Object();
- InputFilter mInputFilter;
- InputFilterHost mInputFilterHost;
-
- public InputManager(Context context, WindowManagerService windowManagerService) {
- this.mContext = context;
- this.mWindowManagerService = windowManagerService;
- this.mCallbacks = new Callbacks();
-
- Looper looper = windowManagerService.mH.getLooper();
-
- Slog.i(TAG, "Initializing input manager");
- nativeInit(mContext, mCallbacks, looper.getQueue());
-
- // Add ourself to the Watchdog monitors.
- Watchdog.getInstance().addMonitor(this);
- }
-
- public void start() {
- Slog.i(TAG, "Starting input manager");
- nativeStart();
-
- registerPointerSpeedSettingObserver();
- registerShowTouchesSettingObserver();
-
- updatePointerSpeedFromSettings();
- updateShowTouchesFromSettings();
- }
-
- public void setDisplaySize(int displayId, int width, int height,
- int externalWidth, int externalHeight) {
- if (width <= 0 || height <= 0 || externalWidth <= 0 || externalHeight <= 0) {
- throw new IllegalArgumentException("Invalid display id or dimensions.");
- }
-
- if (DEBUG) {
- Slog.d(TAG, "Setting display #" + displayId + " size to " + width + "x" + height
- + " external size " + externalWidth + "x" + externalHeight);
- }
- nativeSetDisplaySize(displayId, width, height, externalWidth, externalHeight);
- }
-
- public void setDisplayOrientation(int displayId, int rotation) {
- if (rotation < Surface.ROTATION_0 || rotation > Surface.ROTATION_270) {
- throw new IllegalArgumentException("Invalid rotation.");
- }
-
- if (DEBUG) {
- Slog.d(TAG, "Setting display #" + displayId + " orientation to " + rotation);
- }
- nativeSetDisplayOrientation(displayId, rotation);
- }
-
- public void getInputConfiguration(Configuration config) {
- if (config == null) {
- throw new IllegalArgumentException("config must not be null.");
- }
-
- nativeGetInputConfiguration(config);
- }
-
- /**
- * Gets the current state of a key or button by key code.
- * @param deviceId The input device id, or -1 to consult all devices.
- * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
- * consider all input sources. An input device is consulted if at least one of its
- * non-class input source bits matches the specified source mask.
- * @param keyCode The key code to check.
- * @return The key state.
- */
- public int getKeyCodeState(int deviceId, int sourceMask, int keyCode) {
- return nativeGetKeyCodeState(deviceId, sourceMask, keyCode);
- }
-
- /**
- * Gets the current state of a key or button by scan code.
- * @param deviceId The input device id, or -1 to consult all devices.
- * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
- * consider all input sources. An input device is consulted if at least one of its
- * non-class input source bits matches the specified source mask.
- * @param scanCode The scan code to check.
- * @return The key state.
- */
- public int getScanCodeState(int deviceId, int sourceMask, int scanCode) {
- return nativeGetScanCodeState(deviceId, sourceMask, scanCode);
- }
-
- /**
- * Gets the current state of a switch by switch code.
- * @param deviceId The input device id, or -1 to consult all devices.
- * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
- * consider all input sources. An input device is consulted if at least one of its
- * non-class input source bits matches the specified source mask.
- * @param switchCode The switch code to check.
- * @return The switch state.
- */
- public int getSwitchState(int deviceId, int sourceMask, int switchCode) {
- return nativeGetSwitchState(deviceId, sourceMask, switchCode);
- }
-
- /**
- * Determines whether the specified key codes are supported by a particular device.
- * @param deviceId The input device id, or -1 to consult all devices.
- * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
- * consider all input sources. An input device is consulted if at least one of its
- * non-class input source bits matches the specified source mask.
- * @param keyCodes The array of key codes to check.
- * @param keyExists An array at least as large as keyCodes whose entries will be set
- * to true or false based on the presence or absence of support for the corresponding
- * key codes.
- * @return True if the lookup was successful, false otherwise.
- */
- public boolean hasKeys(int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists) {
- if (keyCodes == null) {
- throw new IllegalArgumentException("keyCodes must not be null.");
- }
- if (keyExists == null || keyExists.length < keyCodes.length) {
- throw new IllegalArgumentException("keyExists must not be null and must be at "
- + "least as large as keyCodes.");
- }
-
- return nativeHasKeys(deviceId, sourceMask, keyCodes, keyExists);
- }
-
- /**
- * Creates an input channel that will receive all input from the input dispatcher.
- * @param inputChannelName The input channel name.
- * @return The input channel.
- */
- public InputChannel monitorInput(String inputChannelName) {
- if (inputChannelName == null) {
- throw new IllegalArgumentException("inputChannelName must not be null.");
- }
-
- InputChannel[] inputChannels = InputChannel.openInputChannelPair(inputChannelName);
- nativeRegisterInputChannel(inputChannels[0], null, true);
- inputChannels[0].dispose(); // don't need to retain the Java object reference
- return inputChannels[1];
- }
-
- /**
- * Registers an input channel so that it can be used as an input event target.
- * @param inputChannel The input channel to register.
- * @param inputWindowHandle The handle of the input window associated with the
- * input channel, or null if none.
- */
- public void registerInputChannel(InputChannel inputChannel,
- InputWindowHandle inputWindowHandle) {
- if (inputChannel == null) {
- throw new IllegalArgumentException("inputChannel must not be null.");
- }
-
- nativeRegisterInputChannel(inputChannel, inputWindowHandle, false);
- }
-
- /**
- * Unregisters an input channel.
- * @param inputChannel The input channel to unregister.
- */
- public void unregisterInputChannel(InputChannel inputChannel) {
- if (inputChannel == null) {
- throw new IllegalArgumentException("inputChannel must not be null.");
- }
-
- nativeUnregisterInputChannel(inputChannel);
- }
-
- /**
- * Sets an input filter that will receive all input events before they are dispatched.
- * The input filter may then reinterpret input events or inject new ones.
- *
- * To ensure consistency, the input dispatcher automatically drops all events
- * in progress whenever an input filter is installed or uninstalled. After an input
- * filter is uninstalled, it can no longer send input events unless it is reinstalled.
- * Any events it attempts to send after it has been uninstalled will be dropped.
- *
- * @param filter The input filter, or null to remove the current filter.
- */
- public void setInputFilter(InputFilter filter) {
- synchronized (mInputFilterLock) {
- final InputFilter oldFilter = mInputFilter;
- if (oldFilter == filter) {
- return; // nothing to do
- }
-
- if (oldFilter != null) {
- mInputFilter = null;
- mInputFilterHost.disconnectLocked();
- mInputFilterHost = null;
- oldFilter.uninstall();
- }
-
- if (filter != null) {
- mInputFilter = filter;
- mInputFilterHost = new InputFilterHost();
- filter.install(mInputFilterHost);
- }
-
- nativeSetInputFilterEnabled(filter != null);
- }
- }
-
- /**
- * Injects an input event into the event system on behalf of an application.
- * The synchronization mode determines whether the method blocks while waiting for
- * input injection to proceed.
- *
- * {@link #INPUT_EVENT_INJECTION_SYNC_NONE} never blocks. Injection is asynchronous and
- * is assumed always to be successful.
- *
- * {@link #INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT} waits for previous events to be
- * dispatched so that the input dispatcher can determine whether input event injection will
- * be permitted based on the current input focus. Does not wait for the input event to
- * finish processing.
- *
- * {@link #INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH} waits for the input event to
- * be completely processed.
- *
- * @param event The event to inject.
- * @param injectorPid The pid of the injecting application.
- * @param injectorUid The uid of the injecting application.
- * @param syncMode The synchronization mode.
- * @param timeoutMillis The injection timeout in milliseconds.
- * @return One of the INPUT_EVENT_INJECTION_XXX constants.
- */
- public int injectInputEvent(InputEvent event, int injectorPid, int injectorUid,
- int syncMode, int timeoutMillis) {
- if (event == null) {
- throw new IllegalArgumentException("event must not be null");
- }
- if (injectorPid < 0 || injectorUid < 0) {
- throw new IllegalArgumentException("injectorPid and injectorUid must not be negative.");
- }
- if (timeoutMillis <= 0) {
- throw new IllegalArgumentException("timeoutMillis must be positive");
- }
-
- return nativeInjectInputEvent(event, injectorPid, injectorUid, syncMode, timeoutMillis,
- WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT);
- }
-
- /**
- * Gets information about the input device with the specified id.
- * @param id The device id.
- * @return The input device or null if not found.
- */
- public InputDevice getInputDevice(int deviceId) {
- return nativeGetInputDevice(deviceId);
- }
-
- /**
- * Gets the ids of all input devices in the system.
- * @return The input device ids.
- */
- public int[] getInputDeviceIds() {
- return nativeGetInputDeviceIds();
- }
-
- public void setInputWindows(InputWindowHandle[] windowHandles) {
- nativeSetInputWindows(windowHandles);
- }
-
- public void setFocusedApplication(InputApplicationHandle application) {
- nativeSetFocusedApplication(application);
- }
-
- public void setInputDispatchMode(boolean enabled, boolean frozen) {
- nativeSetInputDispatchMode(enabled, frozen);
- }
-
- public void setSystemUiVisibility(int visibility) {
- nativeSetSystemUiVisibility(visibility);
- }
-
- /**
- * Atomically transfers touch focus from one window to another as identified by
- * their input channels. It is possible for multiple windows to have
- * touch focus if they support split touch dispatch
- * {@link android.view.WindowManager.LayoutParams#FLAG_SPLIT_TOUCH} but this
- * method only transfers touch focus of the specified window without affecting
- * other windows that may also have touch focus at the same time.
- * @param fromChannel The channel of a window that currently has touch focus.
- * @param toChannel The channel of the window that should receive touch focus in
- * place of the first.
- * @return True if the transfer was successful. False if the window with the
- * specified channel did not actually have touch focus at the time of the request.
- */
- public boolean transferTouchFocus(InputChannel fromChannel, InputChannel toChannel) {
- if (fromChannel == null) {
- throw new IllegalArgumentException("fromChannel must not be null.");
- }
- if (toChannel == null) {
- throw new IllegalArgumentException("toChannel must not be null.");
- }
- return nativeTransferTouchFocus(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.
- */
- public void setPointerSpeed(int speed) {
- speed = Math.min(Math.max(speed, -7), 7);
- nativeSetPointerSpeed(speed);
- }
-
- public void updatePointerSpeedFromSettings() {
- int speed = getPointerSpeedSetting(0);
- setPointerSpeed(speed);
- }
-
- private void registerPointerSpeedSettingObserver() {
- mContext.getContentResolver().registerContentObserver(
- Settings.System.getUriFor(Settings.System.POINTER_SPEED), true,
- new ContentObserver(mWindowManagerService.mH) {
- @Override
- public void onChange(boolean selfChange) {
- updatePointerSpeedFromSettings();
- }
- });
- }
-
- private int getPointerSpeedSetting(int defaultValue) {
- int speed = defaultValue;
- try {
- speed = Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.POINTER_SPEED);
- } catch (SettingNotFoundException snfe) {
- }
- return speed;
- }
-
- public void updateShowTouchesFromSettings() {
- int setting = getShowTouchesSetting(0);
- nativeSetShowTouches(setting != 0);
- }
-
- private void registerShowTouchesSettingObserver() {
- mContext.getContentResolver().registerContentObserver(
- Settings.System.getUriFor(Settings.System.SHOW_TOUCHES), true,
- new ContentObserver(mWindowManagerService.mH) {
- @Override
- public void onChange(boolean selfChange) {
- updateShowTouchesFromSettings();
- }
- });
- }
-
- private int getShowTouchesSetting(int defaultValue) {
- int result = defaultValue;
- try {
- result = Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.SHOW_TOUCHES);
- } catch (SettingNotFoundException snfe) {
- }
- return result;
- }
-
- public void dump(PrintWriter pw) {
- String dumpStr = nativeDump();
- if (dumpStr != null) {
- pw.println(dumpStr);
- }
- }
-
- // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
- public void monitor() {
- synchronized (mInputFilterLock) { }
- nativeMonitor();
- }
-
- private final class InputFilterHost implements InputFilter.Host {
- private boolean mDisconnected;
-
- public void disconnectLocked() {
- mDisconnected = true;
- }
-
- public void sendInputEvent(InputEvent event, int policyFlags) {
- if (event == null) {
- throw new IllegalArgumentException("event must not be null");
- }
-
- synchronized (mInputFilterLock) {
- if (!mDisconnected) {
- nativeInjectInputEvent(event, 0, 0, INPUT_EVENT_INJECTION_SYNC_NONE, 0,
- policyFlags | WindowManagerPolicy.FLAG_FILTERED);
- }
- }
- }
- }
-
- /*
- * Callbacks from native.
- */
- private final class Callbacks {
- static final String TAG = "InputManager-Callbacks";
-
- private static final boolean DEBUG_VIRTUAL_KEYS = false;
- private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml";
- private static final String CALIBRATION_DIR_PATH = "usr/idc/";
-
- @SuppressWarnings("unused")
- public void notifyConfigurationChanged(long whenNanos) {
- mWindowManagerService.mInputMonitor.notifyConfigurationChanged();
- }
-
- @SuppressWarnings("unused")
- public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
- mWindowManagerService.mInputMonitor.notifyLidSwitchChanged(whenNanos, lidOpen);
- }
-
- @SuppressWarnings("unused")
- public void notifyInputChannelBroken(InputWindowHandle inputWindowHandle) {
- mWindowManagerService.mInputMonitor.notifyInputChannelBroken(inputWindowHandle);
- }
-
- @SuppressWarnings("unused")
- public long notifyANR(InputApplicationHandle inputApplicationHandle,
- InputWindowHandle inputWindowHandle) {
- return mWindowManagerService.mInputMonitor.notifyANR(
- inputApplicationHandle, inputWindowHandle);
- }
-
- @SuppressWarnings("unused")
- final boolean filterInputEvent(InputEvent event, int policyFlags) {
- synchronized (mInputFilterLock) {
- if (mInputFilter != null) {
- mInputFilter.filterInputEvent(event, policyFlags);
- return false;
- }
- }
- event.recycle();
- return true;
- }
-
- @SuppressWarnings("unused")
- public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn) {
- return mWindowManagerService.mInputMonitor.interceptKeyBeforeQueueing(
- event, policyFlags, isScreenOn);
- }
-
- @SuppressWarnings("unused")
- public int interceptMotionBeforeQueueingWhenScreenOff(int policyFlags) {
- return mWindowManagerService.mInputMonitor.interceptMotionBeforeQueueingWhenScreenOff(
- policyFlags);
- }
-
- @SuppressWarnings("unused")
- public long interceptKeyBeforeDispatching(InputWindowHandle focus,
- KeyEvent event, int policyFlags) {
- return mWindowManagerService.mInputMonitor.interceptKeyBeforeDispatching(
- focus, event, policyFlags);
- }
-
- @SuppressWarnings("unused")
- public KeyEvent dispatchUnhandledKey(InputWindowHandle focus,
- KeyEvent event, int policyFlags) {
- return mWindowManagerService.mInputMonitor.dispatchUnhandledKey(
- focus, event, policyFlags);
- }
-
- @SuppressWarnings("unused")
- public boolean checkInjectEventsPermission(int injectorPid, int injectorUid) {
- return mContext.checkPermission(
- android.Manifest.permission.INJECT_EVENTS, injectorPid, injectorUid)
- == PackageManager.PERMISSION_GRANTED;
- }
-
- @SuppressWarnings("unused")
- public int getVirtualKeyQuietTimeMillis() {
- return mContext.getResources().getInteger(
- com.android.internal.R.integer.config_virtualKeyQuietTimeMillis);
- }
-
- @SuppressWarnings("unused")
- public String[] getExcludedDeviceNames() {
- ArrayList<String> names = new ArrayList<String>();
-
- // Read partner-provided list of excluded input devices
- XmlPullParser parser = null;
- // Environment.getRootDirectory() is a fancy way of saying ANDROID_ROOT or "/system".
- File confFile = new File(Environment.getRootDirectory(), EXCLUDED_DEVICES_PATH);
- FileReader confreader = null;
- try {
- confreader = new FileReader(confFile);
- parser = Xml.newPullParser();
- parser.setInput(confreader);
- XmlUtils.beginDocument(parser, "devices");
-
- while (true) {
- XmlUtils.nextElement(parser);
- if (!"device".equals(parser.getName())) {
- break;
- }
- String name = parser.getAttributeValue(null, "name");
- if (name != null) {
- names.add(name);
- }
- }
- } catch (FileNotFoundException e) {
- // It's ok if the file does not exist.
- } catch (Exception e) {
- Slog.e(TAG, "Exception while parsing '" + confFile.getAbsolutePath() + "'", e);
- } finally {
- try { if (confreader != null) confreader.close(); } catch (IOException e) { }
- }
-
- return names.toArray(new String[names.size()]);
- }
-
- @SuppressWarnings("unused")
- public int getKeyRepeatTimeout() {
- return ViewConfiguration.getKeyRepeatTimeout();
- }
-
- @SuppressWarnings("unused")
- public int getKeyRepeatDelay() {
- return ViewConfiguration.getKeyRepeatDelay();
- }
-
- @SuppressWarnings("unused")
- public int getHoverTapTimeout() {
- return ViewConfiguration.getHoverTapTimeout();
- }
-
- @SuppressWarnings("unused")
- public int getHoverTapSlop() {
- return ViewConfiguration.getHoverTapSlop();
- }
-
- @SuppressWarnings("unused")
- public int getDoubleTapTimeout() {
- return ViewConfiguration.getDoubleTapTimeout();
- }
-
- @SuppressWarnings("unused")
- public int getLongPressTimeout() {
- return ViewConfiguration.getLongPressTimeout();
- }
-
- @SuppressWarnings("unused")
- public int getPointerLayer() {
- return mWindowManagerService.mPolicy.windowTypeToLayerLw(
- WindowManager.LayoutParams.TYPE_POINTER)
- * WindowManagerService.TYPE_LAYER_MULTIPLIER
- + WindowManagerService.TYPE_LAYER_OFFSET;
- }
-
- @SuppressWarnings("unused")
- public PointerIcon getPointerIcon() {
- return PointerIcon.getDefaultIcon(mContext);
- }
- }
-}
diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java
index fb74d27..c28cfa2 100644
--- a/services/java/com/android/server/wm/InputMonitor.java
+++ b/services/java/com/android/server/wm/InputMonitor.java
@@ -16,6 +16,10 @@
package com.android.server.wm;
+import com.android.server.input.InputManagerService;
+import com.android.server.input.InputApplicationHandle;
+import com.android.server.input.InputWindowHandle;
+
import android.graphics.Rect;
import android.os.RemoteException;
import android.util.Log;
@@ -27,7 +31,7 @@
import java.util.ArrayList;
import java.util.Arrays;
-final class InputMonitor {
+final class InputMonitor implements InputManagerService.Callbacks {
private final WindowManagerService mService;
// Current window with input focus for keys and other non-touch events. May be null.
@@ -93,7 +97,7 @@
}
if (appWindowToken == null && inputApplicationHandle != null) {
- appWindowToken = inputApplicationHandle.appWindowToken;
+ appWindowToken = (AppWindowToken)inputApplicationHandle.appWindowToken;
if (appWindowToken != null) {
Slog.i(WindowManagerService.TAG,
"Input event dispatching timed out sending to application "
@@ -301,7 +305,14 @@
WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
return mService.mPolicy.dispatchUnhandledKey(windowState, event, policyFlags);
}
-
+
+ /* Callback to get pointer layer. */
+ public int getPointerLayer() {
+ return mService.mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_POINTER)
+ * WindowManagerService.TYPE_LAYER_MULTIPLIER
+ + WindowManagerService.TYPE_LAYER_OFFSET;
+ }
+
/* Called when the current input focus changes.
* Layer assignment is assumed to be complete by the time this is called.
*/
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index 77f94d9..67e057e 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -139,7 +139,7 @@
final int NEAT = mService.mExitingAppTokens.size();
for (i=0; i<NEAT; i++) {
- final AppWindowAnimator appAnimator = mService.mAppTokens.get(i).mAppAnimator;
+ final AppWindowAnimator appAnimator = mService.mExitingAppTokens.get(i).mAppAnimator;
final boolean wasAnimating = appAnimator.animation != null
&& appAnimator.animation != WindowManagerService.sDummyAnimation;
if (appAnimator.stepAnimationLocked(mCurrentTime, mInnerDw, mInnerDh)) {
@@ -440,9 +440,12 @@
w.mWinAnimator.prepareSurfaceLocked(true);
}
+ if (mDimParams != null) {
+ mDimAnimator.updateParameters(mContext.getResources(), mDimParams, mCurrentTime);
+ }
if (mDimAnimator != null && mDimAnimator.mDimShown) {
- mAnimating |= mDimAnimator.updateSurface(mService.mInnerFields.mDimming,
- mCurrentTime, !mService.okToDisplay());
+ mAnimating |= mDimAnimator.updateSurface(mDimParams != null, mCurrentTime,
+ !mService.okToDisplay());
}
if (mService.mBlackFrame != null) {
@@ -453,10 +456,6 @@
mService.mBlackFrame.clearMatrix();
}
}
-
- if (mDimParams != null) {
- mDimAnimator.updateParameters(mContext.getResources(), mDimParams, mCurrentTime);
- }
} catch (RuntimeException e) {
Log.wtf(TAG, "Unhandled exception in Window Manager", e);
} finally {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 7eca401..716b7b1 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -44,6 +44,8 @@
import com.android.server.PowerManagerService;
import com.android.server.Watchdog;
import com.android.server.am.BatteryStatsService;
+import com.android.server.input.InputFilter;
+import com.android.server.input.InputManagerService;
import android.Manifest;
import android.app.ActivityManagerNative;
@@ -243,10 +245,6 @@
*/
static final boolean CUSTOM_SCREEN_ROTATION = true;
- // Maximum number of milliseconds to wait for input event injection.
- // FIXME is this value reasonable?
- private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000;
-
// Maximum number of milliseconds to wait for input devices to be enumerated before
// proceding with safe mode detection.
private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
@@ -626,7 +624,7 @@
float mTransitionAnimationScale = 1.0f;
float mAnimatorDurationScale = 1.0f;
- final InputManager mInputManager;
+ final InputManagerService mInputManager;
// Who is holding the screen on.
Session mHoldingScreenOn;
@@ -894,7 +892,7 @@
"KEEP_SCREEN_ON_FLAG");
mHoldingScreenWakeLock.setReferenceCounted(false);
- mInputManager = new InputManager(context, this);
+ mInputManager = new InputManagerService(context, mInputMonitor);
mAnimator = new WindowAnimator(this, context, mPolicy);
PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
@@ -915,6 +913,10 @@
Watchdog.getInstance().addMonitor(this);
}
+ public InputManagerService getInputManagerService() {
+ return mInputManager;
+ }
+
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
@@ -4849,90 +4851,22 @@
mAnimatorDurationScale };
}
- public int getSwitchState(int sw) {
- if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
- "getSwitchState()")) {
- throw new SecurityException("Requires READ_INPUT_STATE permission");
+ // Called by window manager policy. Not exposed externally.
+ @Override
+ public int getLidState() {
+ final int SW_LID = 0x00;
+ int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, SW_LID);
+ if (sw > 0) {
+ return LID_OPEN;
+ } else if (sw == 0) {
+ return LID_CLOSED;
+ } else {
+ return LID_ABSENT;
}
- return mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, sw);
}
- public int getSwitchStateForDevice(int devid, int sw) {
- if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
- "getSwitchStateForDevice()")) {
- throw new SecurityException("Requires READ_INPUT_STATE permission");
- }
- return mInputManager.getSwitchState(devid, InputDevice.SOURCE_ANY, sw);
- }
-
- public int getScancodeState(int sw) {
- if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
- "getScancodeState()")) {
- throw new SecurityException("Requires READ_INPUT_STATE permission");
- }
- return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_ANY, sw);
- }
-
- public int getScancodeStateForDevice(int devid, int sw) {
- if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
- "getScancodeStateForDevice()")) {
- throw new SecurityException("Requires READ_INPUT_STATE permission");
- }
- return mInputManager.getScanCodeState(devid, InputDevice.SOURCE_ANY, sw);
- }
-
- public int getTrackballScancodeState(int sw) {
- if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
- "getTrackballScancodeState()")) {
- throw new SecurityException("Requires READ_INPUT_STATE permission");
- }
- return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
- }
-
- public int getDPadScancodeState(int sw) {
- if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
- "getDPadScancodeState()")) {
- throw new SecurityException("Requires READ_INPUT_STATE permission");
- }
- return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_DPAD, sw);
- }
-
- public int getKeycodeState(int sw) {
- if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
- "getKeycodeState()")) {
- throw new SecurityException("Requires READ_INPUT_STATE permission");
- }
- return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, sw);
- }
-
- public int getKeycodeStateForDevice(int devid, int sw) {
- if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
- "getKeycodeStateForDevice()")) {
- throw new SecurityException("Requires READ_INPUT_STATE permission");
- }
- return mInputManager.getKeyCodeState(devid, InputDevice.SOURCE_ANY, sw);
- }
-
- public int getTrackballKeycodeState(int sw) {
- if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
- "getTrackballKeycodeState()")) {
- throw new SecurityException("Requires READ_INPUT_STATE permission");
- }
- return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
- }
-
- public int getDPadKeycodeState(int sw) {
- if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
- "getDPadKeycodeState()")) {
- throw new SecurityException("Requires READ_INPUT_STATE permission");
- }
- return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD, sw);
- }
-
- public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
- return mInputManager.hasKeys(-1, InputDevice.SOURCE_ANY, keycodes, keyExists);
- }
-
+ // Called by window manager policy. Not exposed externally.
+ @Override
public InputChannel monitorInput(String inputChannelName) {
if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
"monitorInput()")) {
@@ -4945,14 +4879,6 @@
mInputManager.setInputFilter(filter);
}
- public InputDevice getInputDevice(int deviceId) {
- return mInputManager.getInputDevice(deviceId);
- }
-
- public int[] getInputDeviceIds() {
- return mInputManager.getInputDeviceIds();
- }
-
public void enableScreenAfterBoot() {
synchronized(mWindowMap) {
if (DEBUG_BOOT) {
@@ -5109,7 +5035,7 @@
mPolicy.enableScreenAfterBoot();
// Make sure the last requested orientation has been applied.
- updateRotationUnchecked(false);
+ updateRotationUnchecked(false, false);
}
public void showBootMessage(final CharSequence msg, final boolean always) {
@@ -5383,7 +5309,7 @@
mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED,
rotation == -1 ? mRotation : rotation);
- updateRotationUnchecked(false);
+ updateRotationUnchecked(false, false);
}
/**
@@ -5399,7 +5325,7 @@
if (DEBUG_ORIENTATION) Slog.v(TAG, "thawRotation: mRotation=" + mRotation);
mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 777); // rot not used
- updateRotationUnchecked(false);
+ updateRotationUnchecked(false, false);
}
/**
@@ -5409,8 +5335,8 @@
* such that the current rotation might need to be updated, such as when the
* device is docked or rotated into a new posture.
*/
- public void updateRotation(boolean alwaysSendConfiguration) {
- updateRotationUnchecked(alwaysSendConfiguration);
+ public void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
+ updateRotationUnchecked(alwaysSendConfiguration, forceRelayout);
}
/**
@@ -5440,8 +5366,7 @@
}
}
- public void updateRotationUnchecked(
- boolean alwaysSendConfiguration) {
+ public void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) {
if(DEBUG_ORIENTATION) Slog.v(TAG, "updateRotationUnchecked("
+ "alwaysSendConfiguration=" + alwaysSendConfiguration + ")");
@@ -5449,6 +5374,10 @@
boolean changed;
synchronized(mWindowMap) {
changed = updateRotationUncheckedLocked(false);
+ if (!changed || forceRelayout) {
+ mLayoutNeeded = true;
+ performLayoutAndPlaceSurfacesLocked();
+ }
}
if (changed || alwaysSendConfiguration) {
@@ -6435,164 +6364,6 @@
sendScreenStatusToClients();
}
- /**
- * Injects a keystroke event into the UI.
- * Even when sync is false, this method may block while waiting for current
- * input events to be dispatched.
- *
- * @param ev A motion event describing the keystroke action. (Be sure to use
- * {@link SystemClock#uptimeMillis()} as the timebase.)
- * @param sync If true, wait for the event to be completed before returning to the caller.
- * @return Returns true if event was dispatched, false if it was dropped for any reason
- */
- public boolean injectKeyEvent(KeyEvent ev, boolean sync) {
- long downTime = ev.getDownTime();
- long eventTime = ev.getEventTime();
-
- int action = ev.getAction();
- int code = ev.getKeyCode();
- int repeatCount = ev.getRepeatCount();
- int metaState = ev.getMetaState();
- int deviceId = ev.getDeviceId();
- int scancode = ev.getScanCode();
- int source = ev.getSource();
- int flags = ev.getFlags();
-
- if (source == InputDevice.SOURCE_UNKNOWN) {
- source = InputDevice.SOURCE_KEYBOARD;
- }
-
- if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
- if (downTime == 0) downTime = eventTime;
-
- KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
- deviceId, scancode, flags | KeyEvent.FLAG_FROM_SYSTEM, source);
-
- final int pid = Binder.getCallingPid();
- final int uid = Binder.getCallingUid();
- final long ident = Binder.clearCallingIdentity();
-
- final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
- sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
- : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
- INJECTION_TIMEOUT_MILLIS);
-
- Binder.restoreCallingIdentity(ident);
- return reportInjectionResult(result, pid);
- }
-
- /**
- * Inject a pointer (touch) event into the UI.
- * Even when sync is false, this method may block while waiting for current
- * input events to be dispatched.
- *
- * @param ev A motion event describing the pointer (touch) action. (As noted in
- * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
- * {@link SystemClock#uptimeMillis()} as the timebase.)
- * @param sync If true, wait for the event to be completed before returning to the caller.
- * @return Returns true if event was dispatched, false if it was dropped for any reason
- */
- public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
- final int pid = Binder.getCallingPid();
- final int uid = Binder.getCallingUid();
- final long ident = Binder.clearCallingIdentity();
-
- MotionEvent newEvent = MotionEvent.obtain(ev);
- if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
- newEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
- }
-
- final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
- sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
- : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
- INJECTION_TIMEOUT_MILLIS);
-
- Binder.restoreCallingIdentity(ident);
- return reportInjectionResult(result, pid);
- }
-
- /**
- * Inject a trackball (navigation device) event into the UI.
- * Even when sync is false, this method may block while waiting for current
- * input events to be dispatched.
- *
- * @param ev A motion event describing the trackball action. (As noted in
- * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
- * {@link SystemClock#uptimeMillis()} as the timebase.)
- * @param sync If true, wait for the event to be completed before returning to the caller.
- * @return Returns true if event was dispatched, false if it was dropped for any reason
- */
- public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
- final int pid = Binder.getCallingPid();
- final int uid = Binder.getCallingUid();
- final long ident = Binder.clearCallingIdentity();
-
- MotionEvent newEvent = MotionEvent.obtain(ev);
- if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) {
- newEvent.setSource(InputDevice.SOURCE_TRACKBALL);
- }
-
- final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
- sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
- : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
- INJECTION_TIMEOUT_MILLIS);
-
- Binder.restoreCallingIdentity(ident);
- return reportInjectionResult(result, pid);
- }
-
- /**
- * Inject an input event into the UI without waiting for dispatch to commence.
- * This variant is useful for fire-and-forget input event injection. It does not
- * block any longer than it takes to enqueue the input event.
- *
- * @param ev An input event. (Be sure to set the input source correctly.)
- * @return Returns true if event was dispatched, false if it was dropped for any reason
- */
- public boolean injectInputEventNoWait(InputEvent ev) {
- final int pid = Binder.getCallingPid();
- final int uid = Binder.getCallingUid();
- final long ident = Binder.clearCallingIdentity();
-
- final int result = mInputManager.injectInputEvent(ev, pid, uid,
- InputManager.INPUT_EVENT_INJECTION_SYNC_NONE,
- INJECTION_TIMEOUT_MILLIS);
-
- Binder.restoreCallingIdentity(ident);
- return reportInjectionResult(result, pid);
- }
-
- private boolean reportInjectionResult(int result, int pid) {
- switch (result) {
- case InputManager.INPUT_EVENT_INJECTION_PERMISSION_DENIED:
- Slog.w(TAG, "Input event injection from pid " + pid + " permission denied.");
- throw new SecurityException(
- "Injecting to another application requires INJECT_EVENTS permission");
- case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED:
- return true;
- case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT:
- Slog.w(TAG, "Input event injection from pid " + pid + " timed out.");
- return false;
- case InputManager.INPUT_EVENT_INJECTION_FAILED:
- default:
- Slog.w(TAG, "Input event injection from pid " + pid + " failed.");
- return false;
- }
- }
-
- /**
- * Temporarily set the pointer speed. Does not save the new setting.
- * Used by the settings application.
- */
- public void setPointerSpeed(int speed) {
- if (!checkCallingPermission(android.Manifest.permission.SET_POINTER_SPEED,
- "setPointerSpeed()")) {
- throw new SecurityException("Requires SET_POINTER_SPEED permission");
- }
-
- mInputManager.setPointerSpeed(speed);
- }
-
private WindowState getFocusedWindow() {
synchronized (mWindowMap) {
return getFocusedWindowLocked();
@@ -6607,11 +6378,29 @@
if (!mInputMonitor.waitForInputDevicesReady(
INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
Slog.w(TAG, "Devices still not ready after waiting "
- + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
- + " milliseconds before attempting to detect safe mode.");
+ + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
+ + " milliseconds before attempting to detect safe mode.");
}
- mSafeMode = mPolicy.detectSafeMode();
+ final int BTN_MOUSE = 0x110;
+ int menuState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
+ KeyEvent.KEYCODE_MENU);
+ int sState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, KeyEvent.KEYCODE_S);
+ int dpadState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD,
+ KeyEvent.KEYCODE_DPAD_CENTER);
+ int trackballState = mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL,
+ BTN_MOUSE);
+ int volumeDownState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
+ KeyEvent.KEYCODE_VOLUME_DOWN);
+ mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
+ || volumeDownState > 0;
+ if (mSafeMode) {
+ Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
+ + " dpad=" + dpadState + " trackball=" + trackballState + ")");
+ } else {
+ Log.i(TAG, "SAFE MODE not enabled");
+ }
+ mPolicy.setSafeMode(mSafeMode);
return mSafeMode;
}
@@ -6641,7 +6430,7 @@
mInputManager.setDisplaySize(Display.DEFAULT_DISPLAY,
mDisplay.getRawWidth(), mDisplay.getRawHeight(),
mDisplay.getRawExternalWidth(), mDisplay.getRawExternalHeight());
- mPolicy.setInitialDisplaySize(mInitialDisplayWidth, mInitialDisplayHeight);
+ mPolicy.setInitialDisplaySize(mDisplay, mInitialDisplayWidth, mInitialDisplayHeight);
}
try {
@@ -7361,7 +7150,7 @@
mBaseDisplayWidth = width;
mBaseDisplayHeight = height;
}
- mPolicy.setInitialDisplaySize(mBaseDisplayWidth, mBaseDisplayHeight);
+ mPolicy.setInitialDisplaySize(mDisplay, mBaseDisplayWidth, mBaseDisplayHeight);
mLayoutNeeded = true;
@@ -7393,8 +7182,8 @@
}
}
- public boolean canStatusBarHide() {
- return mPolicy.canStatusBarHide();
+ public boolean hasSystemNavBar() {
+ return mPolicy.hasSystemNavBar();
}
// -------------------------------------------------------------
@@ -8397,8 +8186,6 @@
final int N = mWindows.size();
for (i=N-1; i>=0; i--) {
WindowState w = mWindows.get(i);
- //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
- w.mContentChanged = false;
if (someoneLosingFocus && w == mCurrentFocus && w.isDisplayedLw()) {
focusDisplayed = true;
@@ -8419,7 +8206,7 @@
updateWallpaperVisibilityLocked();
}
}
- if (!mInnerFields.mDimming) {
+ if (!mInnerFields.mDimming && mAnimator.mDimParams != null) {
mAnimator.stopDimming();
}
} catch (RuntimeException e) {
@@ -8500,6 +8287,27 @@
for (i=N-1; i>=0; i--) {
final WindowState w = mWindows.get(i);
final WindowStateAnimator winAnimator = w.mWinAnimator;
+
+ // If the window has moved due to its containing
+ // content frame changing, then we'd like to animate
+ // it.
+ if (w.mHasSurface && w.shouldAnimateMove()) {
+ // Frame has moved, containing content frame
+ // has also moved, and we're not currently animating...
+ // let's do something.
+ Animation a = AnimationUtils.loadAnimation(mContext,
+ com.android.internal.R.anim.window_move_from_decor);
+ winAnimator.setAnimation(a);
+ winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
+ winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
+ } else {
+ winAnimator.mAnimDw = innerDw;
+ winAnimator.mAnimDh = innerDh;
+ }
+
+ //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
+ w.mContentChanged = false;
+
// TODO(cmautner): Can this move up to the loop at the end of try/catch above?
updateResizingWindows(w);
@@ -8519,24 +8327,6 @@
}
}
}
-
- // If the window has moved due to its containing
- // content frame changing, then we'd like to animate
- // it. The checks here are ordered by what is least
- // likely to be true first.
- if (w.shouldAnimateMove()) {
- // Frame has moved, containing content frame
- // has also moved, and we're not currently animating...
- // let's do something.
- Animation a = AnimationUtils.loadAnimation(mContext,
- com.android.internal.R.anim.window_move_from_decor);
- winAnimator.setAnimation(a);
- winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
- winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
- } else {
- winAnimator.mAnimDw = innerDw;
- winAnimator.mAnimDh = innerDh;
- }
}
}
@@ -9277,11 +9067,6 @@
mPolicy.lockNow();
}
- void dumpInput(FileDescriptor fd, PrintWriter pw, boolean dumpAll) {
- pw.println("WINDOW MANAGER INPUT (dumpsys window input)");
- mInputManager.dump(pw);
- }
-
void dumpPolicyLocked(FileDescriptor fd, PrintWriter pw, String[] args, boolean dumpAll) {
pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
mPolicy.dump(" ", fd, pw, args);
@@ -9671,7 +9456,6 @@
pw.println("Window manager dump options:");
pw.println(" [-a] [-h] [cmd] ...");
pw.println(" cmd may be one of:");
- pw.println(" i[input]: input subsystem state");
pw.println(" p[policy]: policy state");
pw.println(" s[essions]: active sessions");
pw.println(" t[okens]: token list");
@@ -9692,10 +9476,7 @@
if (opti < args.length) {
String cmd = args[opti];
opti++;
- if ("input".equals(cmd) || "i".equals(cmd)) {
- dumpInput(fd, pw, true);
- return;
- } else if ("policy".equals(cmd) || "p".equals(cmd)) {
+ if ("policy".equals(cmd) || "p".equals(cmd)) {
synchronized(mWindowMap) {
dumpPolicyLocked(fd, pw, args, true);
}
@@ -9730,8 +9511,6 @@
}
}
- dumpInput(fd, pw, dumpAll);
-
synchronized(mWindowMap) {
if (dumpAll) {
pw.println("-------------------------------------------------------------------------------");
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 05797a4..4de6425 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -23,6 +23,8 @@
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import com.android.server.input.InputWindowHandle;
+
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Matrix;
@@ -870,6 +872,7 @@
return true;
}
+ @Override
public boolean hideLw(boolean doAnimation) {
return hideLw(doAnimation, true);
}
@@ -912,6 +915,11 @@
return true;
}
+ @Override
+ public boolean isAlive() {
+ return mClient.asBinder().isBinderAlive();
+ }
+
private static void applyInsets(Region outRegion, Rect frame, Rect inset) {
outRegion.set(
frame.left + inset.left, frame.top + inset.top,
diff --git a/services/jni/Android.mk b/services/jni/Android.mk
index c02dd36..ac4fd15 100644
--- a/services/jni/Android.mk
+++ b/services/jni/Android.mk
@@ -4,9 +4,9 @@
LOCAL_SRC_FILES:= \
com_android_server_AlarmManagerService.cpp \
com_android_server_BatteryService.cpp \
- com_android_server_InputApplicationHandle.cpp \
- com_android_server_InputManager.cpp \
- com_android_server_InputWindowHandle.cpp \
+ com_android_server_input_InputApplicationHandle.cpp \
+ com_android_server_input_InputManagerService.cpp \
+ com_android_server_input_InputWindowHandle.cpp \
com_android_server_LightsService.cpp \
com_android_server_PowerManagerService.cpp \
com_android_server_SerialService.cpp \
diff --git a/services/jni/com_android_server_InputApplicationHandle.cpp b/services/jni/com_android_server_input_InputApplicationHandle.cpp
similarity index 96%
rename from services/jni/com_android_server_InputApplicationHandle.cpp
rename to services/jni/com_android_server_input_InputApplicationHandle.cpp
index c76ab53..0109430 100644
--- a/services/jni/com_android_server_InputApplicationHandle.cpp
+++ b/services/jni/com_android_server_input_InputApplicationHandle.cpp
@@ -21,7 +21,7 @@
#include <android_runtime/AndroidRuntime.h>
#include <utils/threads.h>
-#include "com_android_server_InputApplicationHandle.h"
+#include "com_android_server_input_InputApplicationHandle.h"
namespace android {
@@ -135,12 +135,12 @@
LOG_FATAL_IF(! var, "Unable to find field " fieldName);
int register_android_server_InputApplicationHandle(JNIEnv* env) {
- int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputApplicationHandle",
+ int res = jniRegisterNativeMethods(env, "com/android/server/input/InputApplicationHandle",
gInputApplicationHandleMethods, NELEM(gInputApplicationHandleMethods));
LOG_FATAL_IF(res < 0, "Unable to register native methods.");
jclass clazz;
- FIND_CLASS(clazz, "com/android/server/wm/InputApplicationHandle");
+ FIND_CLASS(clazz, "com/android/server/input/InputApplicationHandle");
GET_FIELD_ID(gInputApplicationHandleClassInfo.ptr, clazz,
"ptr", "I");
diff --git a/services/jni/com_android_server_InputApplicationHandle.h b/services/jni/com_android_server_input_InputApplicationHandle.h
similarity index 100%
rename from services/jni/com_android_server_InputApplicationHandle.h
rename to services/jni/com_android_server_input_InputApplicationHandle.h
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_input_InputManagerService.cpp
similarity index 73%
rename from services/jni/com_android_server_InputManager.cpp
rename to services/jni/com_android_server_input_InputManagerService.cpp
index 5c3e002..22795bf 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_input_InputManagerService.cpp
@@ -46,8 +46,8 @@
#include <android/graphics/GraphicsJNI.h>
#include "com_android_server_PowerManagerService.h"
-#include "com_android_server_InputApplicationHandle.h"
-#include "com_android_server_InputWindowHandle.h"
+#include "com_android_server_input_InputApplicationHandle.h"
+#include "com_android_server_input_InputWindowHandle.h"
namespace android {
@@ -77,7 +77,7 @@
jmethodID getLongPressTimeout;
jmethodID getPointerLayer;
jmethodID getPointerIcon;
-} gCallbacksClassInfo;
+} gServiceClassInfo;
static struct {
jclass clazz;
@@ -166,7 +166,7 @@
virtual ~NativeInputManager();
public:
- NativeInputManager(jobject contextObj, jobject callbacksObj, const sp<Looper>& looper);
+ NativeInputManager(jobject contextObj, jobject serviceObj, const sp<Looper>& looper);
inline sp<InputManager> getInputManager() const { return mInputManager; }
@@ -222,7 +222,7 @@
sp<InputManager> mInputManager;
jobject mContextObj;
- jobject mCallbacksObj;
+ jobject mServiceObj;
sp<Looper> mLooper;
Mutex mLock;
@@ -269,12 +269,12 @@
NativeInputManager::NativeInputManager(jobject contextObj,
- jobject callbacksObj, const sp<Looper>& looper) :
+ jobject serviceObj, const sp<Looper>& looper) :
mLooper(looper) {
JNIEnv* env = jniEnv();
mContextObj = env->NewGlobalRef(contextObj);
- mCallbacksObj = env->NewGlobalRef(callbacksObj);
+ mServiceObj = env->NewGlobalRef(serviceObj);
{
AutoMutex _l(mLock);
@@ -298,7 +298,7 @@
JNIEnv* env = jniEnv();
env->DeleteGlobalRef(mContextObj);
- env->DeleteGlobalRef(mCallbacksObj);
+ env->DeleteGlobalRef(mServiceObj);
}
void NativeInputManager::dump(String8& dump) {
@@ -387,15 +387,15 @@
void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outConfig) {
JNIEnv* env = jniEnv();
- jint virtualKeyQuietTime = env->CallIntMethod(mCallbacksObj,
- gCallbacksClassInfo.getVirtualKeyQuietTimeMillis);
+ jint virtualKeyQuietTime = env->CallIntMethod(mServiceObj,
+ gServiceClassInfo.getVirtualKeyQuietTimeMillis);
if (!checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
outConfig->virtualKeyQuietTime = milliseconds_to_nanoseconds(virtualKeyQuietTime);
}
outConfig->excludedDeviceNames.clear();
- jobjectArray excludedDeviceNames = jobjectArray(env->CallObjectMethod(mCallbacksObj,
- gCallbacksClassInfo.getExcludedDeviceNames));
+ jobjectArray excludedDeviceNames = jobjectArray(env->CallObjectMethod(mServiceObj,
+ gServiceClassInfo.getExcludedDeviceNames));
if (!checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && excludedDeviceNames) {
jsize length = env->GetArrayLength(excludedDeviceNames);
for (jsize i = 0; i < length; i++) {
@@ -408,14 +408,14 @@
env->DeleteLocalRef(excludedDeviceNames);
}
- jint hoverTapTimeout = env->CallIntMethod(mCallbacksObj,
- gCallbacksClassInfo.getHoverTapTimeout);
+ jint hoverTapTimeout = env->CallIntMethod(mServiceObj,
+ gServiceClassInfo.getHoverTapTimeout);
if (!checkAndClearExceptionFromCallback(env, "getHoverTapTimeout")) {
- jint doubleTapTimeout = env->CallIntMethod(mCallbacksObj,
- gCallbacksClassInfo.getDoubleTapTimeout);
+ jint doubleTapTimeout = env->CallIntMethod(mServiceObj,
+ gServiceClassInfo.getDoubleTapTimeout);
if (!checkAndClearExceptionFromCallback(env, "getDoubleTapTimeout")) {
- jint longPressTimeout = env->CallIntMethod(mCallbacksObj,
- gCallbacksClassInfo.getLongPressTimeout);
+ jint longPressTimeout = env->CallIntMethod(mServiceObj,
+ gServiceClassInfo.getLongPressTimeout);
if (!checkAndClearExceptionFromCallback(env, "getLongPressTimeout")) {
outConfig->pointerGestureTapInterval = milliseconds_to_nanoseconds(hoverTapTimeout);
@@ -430,8 +430,8 @@
}
}
- jint hoverTapSlop = env->CallIntMethod(mCallbacksObj,
- gCallbacksClassInfo.getHoverTapSlop);
+ jint hoverTapSlop = env->CallIntMethod(mServiceObj,
+ gServiceClassInfo.getHoverTapSlop);
if (!checkAndClearExceptionFromCallback(env, "getHoverTapSlop")) {
outConfig->pointerGestureTapSlop = hoverTapSlop;
}
@@ -467,8 +467,8 @@
controller->setDisplayOrientation(mLocked.displayOrientation);
JNIEnv* env = jniEnv();
- jobject pointerIconObj = env->CallObjectMethod(mCallbacksObj,
- gCallbacksClassInfo.getPointerIcon);
+ jobject pointerIconObj = env->CallObjectMethod(mServiceObj,
+ gServiceClassInfo.getPointerIcon);
if (!checkAndClearExceptionFromCallback(env, "getPointerIcon")) {
PointerIcon pointerIcon;
status_t status = android_view_PointerIcon_load(env, pointerIconObj,
@@ -490,7 +490,7 @@
void NativeInputManager::ensureSpriteControllerLocked() {
if (mLocked.spriteController == NULL) {
JNIEnv* env = jniEnv();
- jint layer = env->CallIntMethod(mCallbacksObj, gCallbacksClassInfo.getPointerLayer);
+ jint layer = env->CallIntMethod(mServiceObj, gServiceClassInfo.getPointerLayer);
if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
layer = -1;
}
@@ -509,7 +509,7 @@
switch (switchCode) {
case SW_LID:
- env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
+ env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyLidSwitchChanged,
when, switchValue == 0);
checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
break;
@@ -523,7 +523,7 @@
JNIEnv* env = jniEnv();
- env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
+ env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyConfigurationChanged, when);
checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
}
@@ -540,8 +540,8 @@
jobject inputWindowHandleObj =
getInputWindowHandleObjLocalRef(env, inputWindowHandle);
- jlong newTimeout = env->CallLongMethod(mCallbacksObj,
- gCallbacksClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
+ jlong newTimeout = env->CallLongMethod(mServiceObj,
+ gServiceClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
newTimeout = 0; // abort dispatch
} else {
@@ -563,7 +563,7 @@
jobject inputWindowHandleObj =
getInputWindowHandleObjLocalRef(env, inputWindowHandle);
if (inputWindowHandleObj) {
- env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
+ env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyInputChannelBroken,
inputWindowHandleObj);
checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
@@ -574,14 +574,14 @@
void NativeInputManager::getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
JNIEnv* env = jniEnv();
- jint keyRepeatTimeout = env->CallIntMethod(mCallbacksObj,
- gCallbacksClassInfo.getKeyRepeatTimeout);
+ jint keyRepeatTimeout = env->CallIntMethod(mServiceObj,
+ gServiceClassInfo.getKeyRepeatTimeout);
if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) {
outConfig->keyRepeatTimeout = milliseconds_to_nanoseconds(keyRepeatTimeout);
}
- jint keyRepeatDelay = env->CallIntMethod(mCallbacksObj,
- gCallbacksClassInfo.getKeyRepeatDelay);
+ jint keyRepeatDelay = env->CallIntMethod(mServiceObj,
+ gServiceClassInfo.getKeyRepeatDelay);
if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) {
outConfig->keyRepeatDelay = milliseconds_to_nanoseconds(keyRepeatDelay);
}
@@ -734,7 +734,7 @@
}
// The callee is responsible for recycling the event.
- jboolean pass = env->CallBooleanMethod(mCallbacksObj, gCallbacksClassInfo.filterInputEvent,
+ jboolean pass = env->CallBooleanMethod(mServiceObj, gServiceClassInfo.filterInputEvent,
inputEventObj, policyFlags);
if (checkAndClearExceptionFromCallback(env, "filterInputEvent")) {
pass = true;
@@ -758,8 +758,8 @@
jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
jint wmActions;
if (keyEventObj) {
- wmActions = env->CallIntMethod(mCallbacksObj,
- gCallbacksClassInfo.interceptKeyBeforeQueueing,
+ wmActions = env->CallIntMethod(mServiceObj,
+ gServiceClassInfo.interceptKeyBeforeQueueing,
keyEventObj, policyFlags, isScreenOn);
if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
wmActions = 0;
@@ -802,8 +802,8 @@
}
} else {
JNIEnv* env = jniEnv();
- jint wmActions = env->CallIntMethod(mCallbacksObj,
- gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
+ jint wmActions = env->CallIntMethod(mServiceObj,
+ gServiceClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
policyFlags);
if (checkAndClearExceptionFromCallback(env,
"interceptMotionBeforeQueueingWhenScreenOff")) {
@@ -858,8 +858,8 @@
jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
if (keyEventObj) {
- jlong delayMillis = env->CallLongMethod(mCallbacksObj,
- gCallbacksClassInfo.interceptKeyBeforeDispatching,
+ jlong delayMillis = env->CallLongMethod(mServiceObj,
+ gServiceClassInfo.interceptKeyBeforeDispatching,
inputWindowHandleObj, keyEventObj, policyFlags);
bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
android_view_KeyEvent_recycle(env, keyEventObj);
@@ -891,8 +891,8 @@
jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
if (keyEventObj) {
- jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj,
- gCallbacksClassInfo.dispatchUnhandledKey,
+ jobject fallbackKeyEventObj = env->CallObjectMethod(mServiceObj,
+ gServiceClassInfo.dispatchUnhandledKey,
inputWindowHandleObj, keyEventObj, policyFlags);
if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) {
fallbackKeyEventObj = NULL;
@@ -925,8 +925,8 @@
bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
int32_t injectorPid, int32_t injectorUid) {
JNIEnv* env = jniEnv();
- jboolean result = env->CallBooleanMethod(mCallbacksObj,
- gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
+ jboolean result = env->CallBooleanMethod(mServiceObj,
+ gServiceClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
if (checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission")) {
result = false;
}
@@ -947,103 +947,75 @@
// ----------------------------------------------------------------------------
-static sp<NativeInputManager> gNativeInputManager;
-
-static bool checkInputManagerUnitialized(JNIEnv* env) {
- if (gNativeInputManager == NULL) {
- ALOGE("Input manager not initialized.");
- jniThrowRuntimeException(env, "Input manager not initialized.");
- return true;
- }
- return false;
+static jint nativeInit(JNIEnv* env, jclass clazz,
+ jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
+ sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
+ NativeInputManager* im = new NativeInputManager(contextObj, serviceObj, looper);
+ im->incStrong(serviceObj);
+ return reinterpret_cast<jint>(im);
}
-static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
- jobject contextObj, jobject callbacksObj, jobject messageQueueObj) {
- if (gNativeInputManager == NULL) {
- sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
- gNativeInputManager = new NativeInputManager(contextObj, callbacksObj, looper);
- } else {
- ALOGE("Input manager already initialized.");
- jniThrowRuntimeException(env, "Input manager already initialized.");
- }
-}
+static void nativeStart(JNIEnv* env, jclass clazz, jint ptr) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
-static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
- if (checkInputManagerUnitialized(env)) {
- return;
- }
-
- status_t result = gNativeInputManager->getInputManager()->start();
+ status_t result = im->getInputManager()->start();
if (result) {
jniThrowRuntimeException(env, "Input manager could not be started.");
}
}
-static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
+static void nativeSetDisplaySize(JNIEnv* env, jclass clazz, jint ptr,
jint displayId, jint width, jint height, jint externalWidth, jint externalHeight) {
- if (checkInputManagerUnitialized(env)) {
- return;
- }
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
// XXX we could get this from the SurfaceFlinger directly instead of requiring it
// to be passed in like this, not sure which is better but leaving it like this
// keeps the window manager in direct control of when display transitions propagate down
// to the input dispatcher
- gNativeInputManager->setDisplaySize(displayId, width, height, externalWidth, externalHeight);
+ im->setDisplaySize(displayId, width, height, externalWidth, externalHeight);
}
-static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
- jint displayId, jint orientation) {
- if (checkInputManagerUnitialized(env)) {
- return;
- }
+static void nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
+ jint ptr, jint displayId, jint orientation) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
- gNativeInputManager->setDisplayOrientation(displayId, orientation);
+ im->setDisplayOrientation(displayId, orientation);
}
-static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
- jint deviceId, jint sourceMask, jint scanCode) {
- if (checkInputManagerUnitialized(env)) {
- return AKEY_STATE_UNKNOWN;
- }
+static jint nativeGetScanCodeState(JNIEnv* env, jclass clazz,
+ jint ptr, jint deviceId, jint sourceMask, jint scanCode) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
- return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
+ return im->getInputManager()->getReader()->getScanCodeState(
deviceId, uint32_t(sourceMask), scanCode);
}
-static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
- jint deviceId, jint sourceMask, jint keyCode) {
- if (checkInputManagerUnitialized(env)) {
- return AKEY_STATE_UNKNOWN;
- }
+static jint nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
+ jint ptr, jint deviceId, jint sourceMask, jint keyCode) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
- return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
+ return im->getInputManager()->getReader()->getKeyCodeState(
deviceId, uint32_t(sourceMask), keyCode);
}
-static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
- jint deviceId, jint sourceMask, jint sw) {
- if (checkInputManagerUnitialized(env)) {
- return AKEY_STATE_UNKNOWN;
- }
+static jint nativeGetSwitchState(JNIEnv* env, jclass clazz,
+ jint ptr, jint deviceId, jint sourceMask, jint sw) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
- return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
+ return im->getInputManager()->getReader()->getSwitchState(
deviceId, uint32_t(sourceMask), sw);
}
-static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
- jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
- if (checkInputManagerUnitialized(env)) {
- return JNI_FALSE;
- }
+static jboolean nativeHasKeys(JNIEnv* env, jclass clazz,
+ jint ptr, jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
jsize numCodes = env->GetArrayLength(keyCodes);
jboolean result;
if (numCodes == env->GetArrayLength(keyCodes)) {
- result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
+ result = im->getInputManager()->getReader()->hasKeys(
deviceId, uint32_t(sourceMask), numCodes, codes, flags);
} else {
result = JNI_FALSE;
@@ -1059,21 +1031,18 @@
"inputChannel is not initialized");
}
-static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
+static void handleInputChannelDisposed(JNIEnv* env,
jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
+ NativeInputManager* im = static_cast<NativeInputManager*>(data);
+
ALOGW("Input channel object '%s' was disposed without first being unregistered with "
"the input manager!", inputChannel->getName().string());
-
- if (gNativeInputManager != NULL) {
- gNativeInputManager->unregisterInputChannel(env, inputChannel);
- }
+ im->unregisterInputChannel(env, inputChannel);
}
-static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
- jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {
- if (checkInputManagerUnitialized(env)) {
- return;
- }
+static void nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
+ jint ptr, jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
inputChannelObj);
@@ -1085,7 +1054,7 @@
sp<InputWindowHandle> inputWindowHandle =
android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);
- status_t status = gNativeInputManager->registerInputChannel(
+ status_t status = im->registerInputChannel(
env, inputChannel, inputWindowHandle, monitor);
if (status) {
String8 message;
@@ -1096,15 +1065,13 @@
if (! monitor) {
android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
- android_server_InputManager_handleInputChannelDisposed, NULL);
+ handleInputChannelDisposed, im);
}
}
-static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
- jobject inputChannelObj) {
- if (checkInputManagerUnitialized(env)) {
- return;
- }
+static void nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
+ jint ptr, jobject inputChannelObj) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
inputChannelObj);
@@ -1115,7 +1082,7 @@
android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
- status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
+ status_t status = im->unregisterInputChannel(env, inputChannel);
if (status && status != BAD_VALUE) { // ignore already unregistered channel
String8 message;
message.appendFormat("Failed to unregister input channel. status=%d", status);
@@ -1123,21 +1090,17 @@
}
}
-static void android_server_InputManager_nativeSetInputFilterEnabled(JNIEnv* env, jclass clazz,
- jboolean enabled) {
- if (checkInputManagerUnitialized(env)) {
- return;
- }
+static void nativeSetInputFilterEnabled(JNIEnv* env, jclass clazz,
+ jint ptr, jboolean enabled) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
- gNativeInputManager->getInputManager()->getDispatcher()->setInputFilterEnabled(enabled);
+ im->getInputManager()->getDispatcher()->setInputFilterEnabled(enabled);
}
-static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
- jobject inputEventObj, jint injectorPid, jint injectorUid,
+static jint nativeInjectInputEvent(JNIEnv* env, jclass clazz,
+ jint ptr, jobject inputEventObj, jint injectorPid, jint injectorUid,
jint syncMode, jint timeoutMillis, jint policyFlags) {
- if (checkInputManagerUnitialized(env)) {
- return INPUT_EVENT_INJECTION_FAILED;
- }
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
KeyEvent keyEvent;
@@ -1147,7 +1110,7 @@
return INPUT_EVENT_INJECTION_FAILED;
}
- return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
+ return im->getInputManager()->getDispatcher()->injectInputEvent(
& keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
uint32_t(policyFlags));
} else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
@@ -1157,7 +1120,7 @@
return INPUT_EVENT_INJECTION_FAILED;
}
- return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
+ return im->getInputManager()->getDispatcher()->injectInputEvent(
motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
uint32_t(policyFlags));
} else {
@@ -1166,50 +1129,40 @@
}
}
-static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
- jobjectArray windowHandleObjArray) {
- if (checkInputManagerUnitialized(env)) {
- return;
- }
+static void nativeSetInputWindows(JNIEnv* env, jclass clazz,
+ jint ptr, jobjectArray windowHandleObjArray) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
- gNativeInputManager->setInputWindows(env, windowHandleObjArray);
+ im->setInputWindows(env, windowHandleObjArray);
}
-static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
- jobject applicationHandleObj) {
- if (checkInputManagerUnitialized(env)) {
- return;
- }
+static void nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
+ jint ptr, jobject applicationHandleObj) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
- gNativeInputManager->setFocusedApplication(env, applicationHandleObj);
+ im->setFocusedApplication(env, applicationHandleObj);
}
-static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
- jclass clazz, jboolean enabled, jboolean frozen) {
- if (checkInputManagerUnitialized(env)) {
- return;
- }
+static void nativeSetInputDispatchMode(JNIEnv* env,
+ jclass clazz, jint ptr, jboolean enabled, jboolean frozen) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
- gNativeInputManager->setInputDispatchMode(enabled, frozen);
+ im->setInputDispatchMode(enabled, frozen);
}
-static void android_server_InputManager_nativeSetSystemUiVisibility(JNIEnv* env,
- jclass clazz, jint visibility) {
- if (checkInputManagerUnitialized(env)) {
- return;
- }
+static void nativeSetSystemUiVisibility(JNIEnv* env,
+ jclass clazz, jint ptr, jint visibility) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
- gNativeInputManager->setSystemUiVisibility(visibility);
+ im->setSystemUiVisibility(visibility);
}
-static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
- jclass clazz, jint deviceId) {
- if (checkInputManagerUnitialized(env)) {
- return NULL;
- }
+static jobject nativeGetInputDevice(JNIEnv* env,
+ jclass clazz, jint ptr, jint deviceId) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
InputDeviceInfo deviceInfo;
- status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
+ status_t status = im->getInputManager()->getReader()->getInputDeviceInfo(
deviceId, & deviceInfo);
if (status) {
return NULL;
@@ -1249,14 +1202,12 @@
return deviceObj;
}
-static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
- jclass clazz) {
- if (checkInputManagerUnitialized(env)) {
- return NULL;
- }
+static jintArray nativeGetInputDeviceIds(JNIEnv* env,
+ jclass clazz, jint ptr) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
Vector<int> deviceIds;
- gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
+ im->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
if (! deviceIdsObj) {
@@ -1267,25 +1218,21 @@
return deviceIdsObj;
}
-static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
- jclass clazz, jobject configObj) {
- if (checkInputManagerUnitialized(env)) {
- return;
- }
+static void nativeGetInputConfiguration(JNIEnv* env,
+ jclass clazz, jint ptr, jobject configObj) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
InputConfiguration config;
- gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
+ im->getInputManager()->getReader()->getInputConfiguration(& config);
env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
}
-static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
- jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
- if (checkInputManagerUnitialized(env)) {
- return false;
- }
+static jboolean nativeTransferTouchFocus(JNIEnv* env,
+ jclass clazz, jint ptr, jobject fromChannelObj, jobject toChannelObj) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
sp<InputChannel> fromChannel =
android_view_InputChannel_getInputChannel(env, fromChannelObj);
@@ -1296,101 +1243,93 @@
return false;
}
- return gNativeInputManager->getInputManager()->getDispatcher()->
+ return im->getInputManager()->getDispatcher()->
transferTouchFocus(fromChannel, toChannel);
}
-static void android_server_InputManager_nativeSetPointerSpeed(JNIEnv* env,
- jclass clazz, jint speed) {
- if (checkInputManagerUnitialized(env)) {
- return;
- }
+static void nativeSetPointerSpeed(JNIEnv* env,
+ jclass clazz, jint ptr, jint speed) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
- gNativeInputManager->setPointerSpeed(speed);
+ im->setPointerSpeed(speed);
}
-static void android_server_InputManager_nativeSetShowTouches(JNIEnv* env,
- jclass clazz, jboolean enabled) {
- if (checkInputManagerUnitialized(env)) {
- return;
- }
+static void nativeSetShowTouches(JNIEnv* env,
+ jclass clazz, jint ptr, jboolean enabled) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
- gNativeInputManager->setShowTouches(enabled);
+ im->setShowTouches(enabled);
}
-static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
- if (checkInputManagerUnitialized(env)) {
- return NULL;
- }
+static jstring nativeDump(JNIEnv* env, jclass clazz, jint ptr) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
String8 dump;
- gNativeInputManager->dump(dump);
+ im->dump(dump);
return env->NewStringUTF(dump.string());
}
-static void android_server_InputManager_nativeMonitor(JNIEnv* env, jclass clazz) {
- if (checkInputManagerUnitialized(env)) {
- return;
- }
+static void nativeMonitor(JNIEnv* env, jclass clazz, jint ptr) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
- gNativeInputManager->getInputManager()->getReader()->monitor();
- gNativeInputManager->getInputManager()->getDispatcher()->monitor();
+ im->getInputManager()->getReader()->monitor();
+ im->getInputManager()->getDispatcher()->monitor();
}
// ----------------------------------------------------------------------------
static JNINativeMethod gInputManagerMethods[] = {
/* name, signature, funcPtr */
- { "nativeInit", "(Landroid/content/Context;"
- "Lcom/android/server/wm/InputManager$Callbacks;Landroid/os/MessageQueue;)V",
- (void*) android_server_InputManager_nativeInit },
- { "nativeStart", "()V",
- (void*) android_server_InputManager_nativeStart },
- { "nativeSetDisplaySize", "(IIIII)V",
- (void*) android_server_InputManager_nativeSetDisplaySize },
- { "nativeSetDisplayOrientation", "(II)V",
- (void*) android_server_InputManager_nativeSetDisplayOrientation },
- { "nativeGetScanCodeState", "(III)I",
- (void*) android_server_InputManager_nativeGetScanCodeState },
- { "nativeGetKeyCodeState", "(III)I",
- (void*) android_server_InputManager_nativeGetKeyCodeState },
- { "nativeGetSwitchState", "(III)I",
- (void*) android_server_InputManager_nativeGetSwitchState },
- { "nativeHasKeys", "(II[I[Z)Z",
- (void*) android_server_InputManager_nativeHasKeys },
+ { "nativeInit",
+ "(Lcom/android/server/input/InputManagerService;Landroid/content/Context;Landroid/os/MessageQueue;)I",
+ (void*) nativeInit },
+ { "nativeStart", "(I)V",
+ (void*) nativeStart },
+ { "nativeSetDisplaySize", "(IIIIII)V",
+ (void*) nativeSetDisplaySize },
+ { "nativeSetDisplayOrientation", "(III)V",
+ (void*) nativeSetDisplayOrientation },
+ { "nativeGetScanCodeState", "(IIII)I",
+ (void*) nativeGetScanCodeState },
+ { "nativeGetKeyCodeState", "(IIII)I",
+ (void*) nativeGetKeyCodeState },
+ { "nativeGetSwitchState", "(IIII)I",
+ (void*) nativeGetSwitchState },
+ { "nativeHasKeys", "(III[I[Z)Z",
+ (void*) nativeHasKeys },
{ "nativeRegisterInputChannel",
- "(Landroid/view/InputChannel;Lcom/android/server/wm/InputWindowHandle;Z)V",
- (void*) android_server_InputManager_nativeRegisterInputChannel },
- { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
- (void*) android_server_InputManager_nativeUnregisterInputChannel },
- { "nativeSetInputFilterEnabled", "(Z)V",
- (void*) android_server_InputManager_nativeSetInputFilterEnabled },
- { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIIII)I",
- (void*) android_server_InputManager_nativeInjectInputEvent },
- { "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindowHandle;)V",
- (void*) android_server_InputManager_nativeSetInputWindows },
- { "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplicationHandle;)V",
- (void*) android_server_InputManager_nativeSetFocusedApplication },
- { "nativeSetInputDispatchMode", "(ZZ)V",
- (void*) android_server_InputManager_nativeSetInputDispatchMode },
- { "nativeSetSystemUiVisibility", "(I)V",
- (void*) android_server_InputManager_nativeSetSystemUiVisibility },
- { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
- (void*) android_server_InputManager_nativeGetInputDevice },
- { "nativeGetInputDeviceIds", "()[I",
- (void*) android_server_InputManager_nativeGetInputDeviceIds },
- { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
- (void*) android_server_InputManager_nativeGetInputConfiguration },
- { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
- (void*) android_server_InputManager_nativeTransferTouchFocus },
- { "nativeSetPointerSpeed", "(I)V",
- (void*) android_server_InputManager_nativeSetPointerSpeed },
- { "nativeSetShowTouches", "(Z)V",
- (void*) android_server_InputManager_nativeSetShowTouches },
- { "nativeDump", "()Ljava/lang/String;",
- (void*) android_server_InputManager_nativeDump },
- { "nativeMonitor", "()V",
- (void*) android_server_InputManager_nativeMonitor },
+ "(ILandroid/view/InputChannel;Lcom/android/server/input/InputWindowHandle;Z)V",
+ (void*) nativeRegisterInputChannel },
+ { "nativeUnregisterInputChannel", "(ILandroid/view/InputChannel;)V",
+ (void*) nativeUnregisterInputChannel },
+ { "nativeSetInputFilterEnabled", "(IZ)V",
+ (void*) nativeSetInputFilterEnabled },
+ { "nativeInjectInputEvent", "(ILandroid/view/InputEvent;IIIII)I",
+ (void*) nativeInjectInputEvent },
+ { "nativeSetInputWindows", "(I[Lcom/android/server/input/InputWindowHandle;)V",
+ (void*) nativeSetInputWindows },
+ { "nativeSetFocusedApplication", "(ILcom/android/server/input/InputApplicationHandle;)V",
+ (void*) nativeSetFocusedApplication },
+ { "nativeSetInputDispatchMode", "(IZZ)V",
+ (void*) nativeSetInputDispatchMode },
+ { "nativeSetSystemUiVisibility", "(II)V",
+ (void*) nativeSetSystemUiVisibility },
+ { "nativeGetInputDevice", "(II)Landroid/view/InputDevice;",
+ (void*) nativeGetInputDevice },
+ { "nativeGetInputDeviceIds", "(I)[I",
+ (void*) nativeGetInputDeviceIds },
+ { "nativeGetInputConfiguration", "(ILandroid/content/res/Configuration;)V",
+ (void*) nativeGetInputConfiguration },
+ { "nativeTransferTouchFocus", "(ILandroid/view/InputChannel;Landroid/view/InputChannel;)Z",
+ (void*) nativeTransferTouchFocus },
+ { "nativeSetPointerSpeed", "(II)V",
+ (void*) nativeSetPointerSpeed },
+ { "nativeSetShowTouches", "(IZ)V",
+ (void*) nativeSetShowTouches },
+ { "nativeDump", "(I)Ljava/lang/String;",
+ (void*) nativeDump },
+ { "nativeMonitor", "(I)V",
+ (void*) nativeMonitor },
};
#define FIND_CLASS(var, className) \
@@ -1406,77 +1345,77 @@
LOG_FATAL_IF(! var, "Unable to find field " fieldName);
int register_android_server_InputManager(JNIEnv* env) {
- int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputManager",
+ int res = jniRegisterNativeMethods(env, "com/android/server/input/InputManagerService",
gInputManagerMethods, NELEM(gInputManagerMethods));
LOG_FATAL_IF(res < 0, "Unable to register native methods.");
// Callbacks
jclass clazz;
- FIND_CLASS(clazz, "com/android/server/wm/InputManager$Callbacks");
+ FIND_CLASS(clazz, "com/android/server/input/InputManagerService");
- GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, clazz,
+ GET_METHOD_ID(gServiceClassInfo.notifyConfigurationChanged, clazz,
"notifyConfigurationChanged", "(J)V");
- GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, clazz,
+ GET_METHOD_ID(gServiceClassInfo.notifyLidSwitchChanged, clazz,
"notifyLidSwitchChanged", "(JZ)V");
- GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, clazz,
- "notifyInputChannelBroken", "(Lcom/android/server/wm/InputWindowHandle;)V");
+ GET_METHOD_ID(gServiceClassInfo.notifyInputChannelBroken, clazz,
+ "notifyInputChannelBroken", "(Lcom/android/server/input/InputWindowHandle;)V");
- GET_METHOD_ID(gCallbacksClassInfo.notifyANR, clazz,
+ GET_METHOD_ID(gServiceClassInfo.notifyANR, clazz,
"notifyANR",
- "(Lcom/android/server/wm/InputApplicationHandle;Lcom/android/server/wm/InputWindowHandle;)J");
+ "(Lcom/android/server/input/InputApplicationHandle;Lcom/android/server/input/InputWindowHandle;)J");
- GET_METHOD_ID(gCallbacksClassInfo.filterInputEvent, clazz,
+ GET_METHOD_ID(gServiceClassInfo.filterInputEvent, clazz,
"filterInputEvent", "(Landroid/view/InputEvent;I)Z");
- GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, clazz,
+ GET_METHOD_ID(gServiceClassInfo.interceptKeyBeforeQueueing, clazz,
"interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
- GET_METHOD_ID(gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
+ GET_METHOD_ID(gServiceClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
clazz,
"interceptMotionBeforeQueueingWhenScreenOff", "(I)I");
- GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, clazz,
+ GET_METHOD_ID(gServiceClassInfo.interceptKeyBeforeDispatching, clazz,
"interceptKeyBeforeDispatching",
- "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)J");
+ "(Lcom/android/server/input/InputWindowHandle;Landroid/view/KeyEvent;I)J");
- GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, clazz,
+ GET_METHOD_ID(gServiceClassInfo.dispatchUnhandledKey, clazz,
"dispatchUnhandledKey",
- "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
+ "(Lcom/android/server/input/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
- GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, clazz,
+ GET_METHOD_ID(gServiceClassInfo.checkInjectEventsPermission, clazz,
"checkInjectEventsPermission", "(II)Z");
- GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, clazz,
+ GET_METHOD_ID(gServiceClassInfo.getVirtualKeyQuietTimeMillis, clazz,
"getVirtualKeyQuietTimeMillis", "()I");
- GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, clazz,
+ GET_METHOD_ID(gServiceClassInfo.getExcludedDeviceNames, clazz,
"getExcludedDeviceNames", "()[Ljava/lang/String;");
- GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatTimeout, clazz,
+ GET_METHOD_ID(gServiceClassInfo.getKeyRepeatTimeout, clazz,
"getKeyRepeatTimeout", "()I");
- GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatDelay, clazz,
+ GET_METHOD_ID(gServiceClassInfo.getKeyRepeatDelay, clazz,
"getKeyRepeatDelay", "()I");
- GET_METHOD_ID(gCallbacksClassInfo.getHoverTapTimeout, clazz,
+ GET_METHOD_ID(gServiceClassInfo.getHoverTapTimeout, clazz,
"getHoverTapTimeout", "()I");
- GET_METHOD_ID(gCallbacksClassInfo.getHoverTapSlop, clazz,
+ GET_METHOD_ID(gServiceClassInfo.getHoverTapSlop, clazz,
"getHoverTapSlop", "()I");
- GET_METHOD_ID(gCallbacksClassInfo.getDoubleTapTimeout, clazz,
+ GET_METHOD_ID(gServiceClassInfo.getDoubleTapTimeout, clazz,
"getDoubleTapTimeout", "()I");
- GET_METHOD_ID(gCallbacksClassInfo.getLongPressTimeout, clazz,
+ GET_METHOD_ID(gServiceClassInfo.getLongPressTimeout, clazz,
"getLongPressTimeout", "()I");
- GET_METHOD_ID(gCallbacksClassInfo.getPointerLayer, clazz,
+ GET_METHOD_ID(gServiceClassInfo.getPointerLayer, clazz,
"getPointerLayer", "()I");
- GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, clazz,
+ GET_METHOD_ID(gServiceClassInfo.getPointerIcon, clazz,
"getPointerIcon", "()Landroid/view/PointerIcon;");
// KeyEvent
@@ -1484,7 +1423,6 @@
FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz));
-
// MotionEvent
FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
diff --git a/services/jni/com_android_server_InputWindowHandle.cpp b/services/jni/com_android_server_input_InputWindowHandle.cpp
similarity index 96%
rename from services/jni/com_android_server_InputWindowHandle.cpp
rename to services/jni/com_android_server_input_InputWindowHandle.cpp
index 0607eee..01fb781 100644
--- a/services/jni/com_android_server_InputWindowHandle.cpp
+++ b/services/jni/com_android_server_input_InputWindowHandle.cpp
@@ -24,8 +24,8 @@
#include <android_view_InputChannel.h>
#include <android/graphics/Region.h>
-#include "com_android_server_InputWindowHandle.h"
-#include "com_android_server_InputApplicationHandle.h"
+#include "com_android_server_input_InputWindowHandle.h"
+#include "com_android_server_input_InputApplicationHandle.h"
namespace android {
@@ -218,19 +218,19 @@
LOG_FATAL_IF(! var, "Unable to find field " fieldName);
int register_android_server_InputWindowHandle(JNIEnv* env) {
- int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputWindowHandle",
+ int res = jniRegisterNativeMethods(env, "com/android/server/input/InputWindowHandle",
gInputWindowHandleMethods, NELEM(gInputWindowHandleMethods));
LOG_FATAL_IF(res < 0, "Unable to register native methods.");
jclass clazz;
- FIND_CLASS(clazz, "com/android/server/wm/InputWindowHandle");
+ FIND_CLASS(clazz, "com/android/server/input/InputWindowHandle");
GET_FIELD_ID(gInputWindowHandleClassInfo.ptr, clazz,
"ptr", "I");
GET_FIELD_ID(gInputWindowHandleClassInfo.inputApplicationHandle,
clazz,
- "inputApplicationHandle", "Lcom/android/server/wm/InputApplicationHandle;");
+ "inputApplicationHandle", "Lcom/android/server/input/InputApplicationHandle;");
GET_FIELD_ID(gInputWindowHandleClassInfo.inputChannel, clazz,
"inputChannel", "Landroid/view/InputChannel;");
diff --git a/services/jni/com_android_server_InputWindowHandle.h b/services/jni/com_android_server_input_InputWindowHandle.h
similarity index 100%
rename from services/jni/com_android_server_InputWindowHandle.h
rename to services/jni/com_android_server_input_InputWindowHandle.h
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 60be35a..cc3c328 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -32,6 +32,7 @@
<uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
<uses-permission android:name="android.permission.MODIFY_NETWORK_ACCOUNTING" />
<uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application>
<uses-library android:name="android.test.runner" />
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 88ee867..1773e33 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -70,6 +70,7 @@
import android.os.INetworkManagementService;
import android.os.IPowerManager;
import android.os.MessageQueue.IdleHandler;
+import android.os.SystemClock;
import android.os.UserId;
import android.test.AndroidTestCase;
import android.test.mock.MockPackageManager;
diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
index daf20183..103d8e1 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
@@ -84,7 +84,7 @@
*/
@LargeTest
public class NetworkStatsServiceTest extends AndroidTestCase {
- private static final String TAG = "NetworkStatsServiceTest";
+ private static final String TAG = "NetworkStatsServiceTest";
private static final String TEST_IFACE = "test0";
private static final String TEST_IFACE2 = "test1";
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java
index 7f05f56..e40f166 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java
@@ -20,8 +20,6 @@
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
import android.content.res.Resources;
-import android.net.ConnectivityManager;
-import android.net.NetworkIdentity;
import android.net.NetworkStats;
import android.net.NetworkTemplate;
import android.test.AndroidTestCase;
@@ -145,12 +143,6 @@
}
}
- public static NetworkIdentitySet buildWifiIdent() {
- final NetworkIdentitySet set = new NetworkIdentitySet();
- set.add(new NetworkIdentity(ConnectivityManager.TYPE_WIFI, 0, null, false));
- return set;
- }
-
private static void assertSummaryTotal(NetworkStatsCollection collection,
NetworkTemplate template, long rxBytes, long rxPackets, long txBytes, long txPackets) {
final NetworkStats.Entry entry = collection.getSummary(
diff --git a/telephony/java/android/telephony/CdmaCellIdentity.java b/telephony/java/android/telephony/CdmaCellIdentity.java
new file mode 100644
index 0000000..5b8454f
--- /dev/null
+++ b/telephony/java/android/telephony/CdmaCellIdentity.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * CellIdentity is to represent a unique CDMA cell
+ *
+ * @hide pending API review
+ */
+public final class CdmaCellIdentity extends CellIdentity implements Parcelable {
+ // Network Id 0..65535
+ private final int mNetworkId;
+ // CDMA System Id 0..32767
+ private final int mSystemId;
+ // Base Station Id 0..65535
+ private final int mBasestationId;
+ /**
+ * Longitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
+ * It is represented in units of 0.25 seconds and ranges from -2592000
+ * to 2592000, both values inclusive (corresponding to a range of -180
+ * to +180 degrees).
+ */
+ private final int mLongitude;
+ /**
+ * Latitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
+ * It is represented in units of 0.25 seconds and ranges from -1296000
+ * to 1296000, both values inclusive (corresponding to a range of -90
+ * to +90 degrees).
+ */
+ private final int mLatitude;
+
+ /**
+ * public constructor
+ * @param nid Network Id 0..65535
+ * @param sid CDMA System Id 0..32767
+ * @param bid Base Station Id 0..65535
+ * @param lon Longitude is a decimal number ranges from -2592000
+ * to 2592000
+ * @param lat Latitude is a decimal number ranges from -1296000
+ * to 1296000
+ * @param attr is comma separated “key=value” attribute pairs.
+ */
+ public CdmaCellIdentity (int nid, int sid,
+ int bid, int lon, int lat, String attr) {
+ super(CELLID_TYPE_CDMA, attr);
+ mNetworkId = nid;
+ mSystemId = sid;
+ mBasestationId = bid;
+ mLongitude = lon;
+ mLatitude = lat;
+ }
+
+ private CdmaCellIdentity(Parcel in) {
+ super(in);
+ mNetworkId = in.readInt();
+ mSystemId = in.readInt();
+ mBasestationId = in.readInt();
+ mLongitude = in.readInt();
+ mLatitude = in.readInt();
+ }
+
+ CdmaCellIdentity(CdmaCellIdentity cid) {
+ super(cid);
+ mNetworkId = cid.mNetworkId;
+ mSystemId = cid.mSystemId;
+ mBasestationId = cid.mBasestationId;
+ mLongitude = cid.mLongitude;
+ mLatitude = cid.mLatitude;
+ }
+
+ /**
+ * @return Network Id 0..65535
+ */
+ public int getNetworkId() {
+ return mNetworkId;
+ }
+
+ /**
+ * @return System Id 0..32767
+ */
+ public int getSystemId() {
+ return mSystemId;
+ }
+
+ /**
+ * @return Base Station Id 0..65535
+ */
+ public int getBasestationId() {
+ return mBasestationId;
+ }
+
+ /**
+ * @return Base station longitude, which is a decimal number as
+ * specified in 3GPP2 C.S0005-A v6.0. It is represented in units
+ * of 0.25 seconds and ranges from -2592000 to 2592000, both
+ * values inclusive (corresponding to a range of -180
+ * to +180 degrees).
+ */
+ public int getLongitude() {
+ return mLongitude;
+ }
+
+ /**
+ * @return Base station
+ */
+ /**
+ * @return Base station latitude, which is a decimal number as
+ * specified in 3GPP2 C.S0005-A v6.0. It is represented in units
+ * of 0.25 seconds and ranges from -1296000 to 1296000, both
+ * values inclusive (corresponding to a range of -90
+ * to +90 degrees).
+ */
+ public int getLatitude() {
+ return mLatitude;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeInt(mNetworkId);
+ dest.writeInt(mSystemId);
+ dest.writeInt(mBasestationId);
+ dest.writeInt(mLongitude);
+ dest.writeInt(mLatitude);
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public static final Creator<CdmaCellIdentity> CREATOR =
+ new Creator<CdmaCellIdentity>() {
+ @Override
+ public CdmaCellIdentity createFromParcel(Parcel in) {
+ return new CdmaCellIdentity(in);
+ }
+
+ @Override
+ public CdmaCellIdentity[] newArray(int size) {
+ return new CdmaCellIdentity[size];
+ }
+ };
+}
diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java
new file mode 100644
index 0000000..65c220f
--- /dev/null
+++ b/telephony/java/android/telephony/CellIdentity.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * CellIdentity is to represent ONE unique cell in the world
+ * it contains all levels of info to identity country, carrier, etc.
+ *
+ * @hide pending API review
+ */
+public abstract class CellIdentity implements Parcelable {
+
+ // Cell is a GSM Cell {@link GsmCellIdentity}
+ public static final int CELLID_TYPE_GSM = 1;
+ // Cell is a CMDA Cell {@link CdmaCellIdentity}
+ public static final int CELLID_TYPE_CDMA = 2;
+ // Cell is a LTE Cell {@link LteCellIdentity}
+ public static final int CELLID_TYPE_LTE = 3;
+
+ private int mCellIdType;
+ private String mCellIdAttributes;
+
+ protected CellIdentity(int type, String attr) {
+ this.mCellIdType = type;
+ this.mCellIdAttributes = new String(attr);
+ }
+
+ protected CellIdentity(Parcel in) {
+ this.mCellIdType = in.readInt();
+ this.mCellIdAttributes = new String(in.readString());
+ }
+
+ protected CellIdentity(CellIdentity cid) {
+ this.mCellIdType = cid.mCellIdType;
+ this.mCellIdAttributes = new String(cid.mCellIdAttributes);
+ }
+
+ /**
+ * @return Cell Identity type as one of CELLID_TYPE_XXXX
+ */
+ public int getCellIdType() {
+ return mCellIdType;
+ }
+
+
+ /**
+ * @return Cell identity attribute pairs
+ * Comma separated “key=value” pairs.
+ * key := must must an single alpha-numeric word
+ * value := “quoted value string”
+ *
+ * Current list of keys and values:
+ * type = fixed | mobile
+ */
+ public String getCellIdAttributes() {
+ return mCellIdAttributes;
+ }
+
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mCellIdType);
+ dest.writeString(mCellIdAttributes);
+ }
+}
diff --git a/telephony/java/android/telephony/CellInfo.aidl b/telephony/java/android/telephony/CellInfo.aidl
new file mode 100644
index 0000000..8bbb0b4
--- /dev/null
+++ b/telephony/java/android/telephony/CellInfo.aidl
@@ -0,0 +1,20 @@
+/*
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.telephony;
+
+parcelable CellInfo;
\ No newline at end of file
diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java
new file mode 100644
index 0000000..9bea30c
--- /dev/null
+++ b/telephony/java/android/telephony/CellInfo.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Represent one snapshot observation of one cell info
+ * which contains the time of observation.
+ *
+ * @hide Pending API review
+ */
+public final class CellInfo implements Parcelable {
+ // Type to distinguish where time stamp gets recorded.
+ public static final int CELL_INFO_TIMESTAMP_TYPE_UNKNOWN = 0;
+ public static final int CELL_INFO_TIMESTAMP_TYPE_ANTENNA = 1;
+ public static final int CELL_INFO_TIMESTAMP_TYPE_MODEM = 2;
+ public static final int CELL_INFO_TIMESTAMP_TYPE_OEM_RIL = 3;
+ public static final int CELL_INFO_TIMESTAMP_TYPE_JAVA_RIL = 4;
+
+ // Observation time stamped as type in nanoseconds since boot
+ private final long mTimeStamp;
+ // Where time stamp gets recorded.
+ // Value of CELL_INFO_TIMESTAMP_TYPE_XXXX
+ private final int mTimeStampType;
+
+ private final boolean mRegistered;
+
+ private final SignalStrength mStrength;
+ private final long mTimingAdvance;
+
+ private final int mCellIdentityType;
+ private final CellIdentity mCellIdentity;
+
+ /**
+ * Public constructor
+ * @param timeStampType is one of CELL_INFO_TIMESTAMP_TYPE_XXXX
+ * @param timeStamp is observation time in nanoseconds since boot
+ * @param timingAdv is observed timing advance
+ * @param registered is true when register to this cellIdentity
+ * @param strength is observed signal strength
+ * @param cellIdentity is observed mobile cell
+ */
+ public CellInfo(int timeStampType, long timeStamp, long timingAdv,
+ boolean registered, SignalStrength strength,
+ CellIdentity cellIdentity) {
+
+ if (timeStampType < CELL_INFO_TIMESTAMP_TYPE_UNKNOWN ||
+ timeStampType > CELL_INFO_TIMESTAMP_TYPE_JAVA_RIL) {
+ mTimeStampType = CELL_INFO_TIMESTAMP_TYPE_UNKNOWN;
+ } else {
+ mTimeStampType = timeStampType;
+ }
+
+ mRegistered = registered;
+ mTimeStamp = timeStamp;
+ mTimingAdvance = timingAdv;
+ mStrength = new SignalStrength(strength);
+
+ mCellIdentityType = cellIdentity.getCellIdType();
+ // TODO: make defense copy
+ mCellIdentity = cellIdentity;
+ }
+
+ public CellInfo(CellInfo ci) {
+ this.mTimeStampType = ci.mTimeStampType;
+ this.mRegistered = ci.mRegistered;
+ this.mTimeStamp = ci.mTimeStamp;
+ this.mTimingAdvance = ci.mTimingAdvance;
+ this.mCellIdentityType = ci.mCellIdentityType;
+ this.mStrength = new SignalStrength(ci.mStrength);
+ switch(mCellIdentityType) {
+ case CellIdentity.CELLID_TYPE_GSM:
+ mCellIdentity = new GsmCellIdentity((GsmCellIdentity)ci.mCellIdentity);
+ break;
+ default:
+ mCellIdentity = null;
+ }
+ }
+
+ private CellInfo(Parcel in) {
+ mTimeStampType = in.readInt();
+ mRegistered = (in.readInt() == 1) ? true : false;
+ mTimeStamp = in.readLong();
+ mTimingAdvance = in.readLong();
+ mCellIdentityType = in.readInt();
+ mStrength = SignalStrength.CREATOR.createFromParcel(in);
+ switch(mCellIdentityType) {
+ case CellIdentity.CELLID_TYPE_GSM:
+ mCellIdentity = GsmCellIdentity.CREATOR.createFromParcel(in);
+ break;
+ default:
+ mCellIdentity = null;
+ }
+ }
+
+ /**
+ * @return the observation time in nanoseconds since boot
+ */
+ public long getTimeStamp() {
+ return mTimeStamp;
+ }
+
+ /**
+ * @return Where time stamp gets recorded.
+ * one of CELL_INFO_TIMESTAMP_TYPE_XXXX
+ */
+ public int getTimeStampType() {
+ return mTimeStampType;
+ }
+
+ /**
+ * @return true when register to this cellIdentity
+ */
+ public boolean isRegistered() {
+ return mRegistered;
+ }
+
+ /**
+ * @return observed timing advance
+ */
+ public long getTimingAdvance() {
+ return mTimingAdvance;
+ }
+
+ /**
+ * @return observed signal strength
+ */
+ public SignalStrength getSignalStrength() {
+ // make a defense copy
+ return new SignalStrength(mStrength);
+ }
+
+ /**
+ * @return observed cell identity
+ */
+ public CellIdentity getCellIdentity() {
+ // TODO: make a defense copy
+ return mCellIdentity;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append("TimeStampType: ");
+ switch(mTimeStampType) {
+ case 1:
+ sb.append("antenna");
+ break;
+ case 2:
+ sb.append("modem");
+ break;
+ case 3:
+ sb.append("oem_ril");
+ break;
+ case 4:
+ sb.append("java_ril");
+ break;
+ default:
+ sb.append("unknown");
+ }
+ sb.append(", TimeStamp: ").append(mTimeStamp).append(" ns");
+ sb.append(", Registered: ").append(mRegistered ? "YES" : "NO");
+ sb.append(", TimingAdvance: ").append(mTimingAdvance);
+ sb.append(", Strength : " + mStrength);
+ sb.append(", Cell Iden: " + mCellIdentity);
+
+ return sb.toString();
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mTimeStampType);
+ dest.writeInt(mRegistered ? 1 : 0);
+ dest.writeLong(mTimeStamp);
+ dest.writeLong(mTimingAdvance);
+ dest.writeInt(mCellIdentityType);
+ mStrength.writeToParcel(dest, flags);
+ mCellIdentity.writeToParcel(dest, flags);
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public static final Creator<CellInfo> CREATOR =
+ new Creator<CellInfo>() {
+ @Override
+ public CellInfo createFromParcel(Parcel in) {
+ return new CellInfo(in);
+ }
+
+ @Override
+ public CellInfo[] newArray(int size) {
+ return new CellInfo[size];
+ }
+ };
+}
diff --git a/telephony/java/android/telephony/GsmCellIdentity.java b/telephony/java/android/telephony/GsmCellIdentity.java
new file mode 100644
index 0000000..159cb52
--- /dev/null
+++ b/telephony/java/android/telephony/GsmCellIdentity.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * CellIdentity to represent a unique GSM or UMTS cell
+ *
+ * @hide pending API review
+ */
+public final class GsmCellIdentity extends CellIdentity implements Parcelable {
+
+ // 3-digit Mobile Country Code, 0..999
+ private final int mMcc;
+ // 2 or 3-digit Mobile Network Code, 0..999
+ private final int mMnc;
+ // 16-bit Location Area Code, 0..65535
+ private final int mLac;
+ // 16-bit GSM Cell Identity described in TS 27.007, 0..65535
+ // 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455
+ private final int mCid;
+ // 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511
+ private final int mPsc;
+
+ /**
+ * public constructor
+ * @param mcc 3-digit Mobile Country Code, 0..999
+ * @param mnc 2 or 3-digit Mobile Network Code, 0..999
+ * @param lac 16-bit Location Area Code, 0..65535
+ * @param cid 16-bit GSM Cell Identity or 28-bit UMTS Cell Identity
+ * @param psc 9-bit UMTS Primary Scrambling Code
+ * @param attr is comma separated “key=value” attribute pairs.
+ */
+ public GsmCellIdentity (int mcc, int mnc,
+ int lac, int cid, int psc, String attr) {
+ super(CELLID_TYPE_GSM, attr);
+ mMcc = mcc;
+ mMnc = mnc;
+ mLac = lac;
+ mCid = cid;
+ mPsc = psc;
+ }
+
+ private GsmCellIdentity(Parcel in) {
+ super(in);
+ mMcc = in.readInt();
+ mMnc = in.readInt();
+ mLac = in.readInt();
+ mCid = in.readInt();
+ mPsc = in.readInt();
+ }
+
+ GsmCellIdentity(GsmCellIdentity cid) {
+ super(cid);
+ mMcc = cid.mMcc;
+ mMnc = cid.mMnc;
+ mLac = cid.mLac;
+ mCid = cid.mCid;
+ mPsc = cid.mPsc;
+ }
+
+ /**
+ * @return 3-digit Mobile Country Code, 0..999
+ */
+ public int getMcc() {
+ return mMcc;
+ }
+
+ /**
+ * @return 2 or 3-digit Mobile Network Code, 0..999
+ */
+ public int getMnc() {
+ return mMnc;
+ }
+
+ /**
+ * @return 16-bit Location Area Code, 0..65535
+ */
+ public int getLac() {
+ return mLac;
+ }
+
+ /**
+ * @return CID
+ * Either 16-bit GSM Cell Identity described
+ * in TS 27.007, 0..65535
+ * or 28-bit UMTS Cell Identity described
+ * in TS 25.331, 0..268435455
+ */
+ public int getCid() {
+ return mCid;
+ }
+
+ /**
+ * @return 9-bit UMTS Primary Scrambling Code described in
+ * TS 25.331, 0..511
+ */
+ public int getPsc() {
+ return mPsc;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeInt(mMcc);
+ dest.writeInt(mMnc);
+ dest.writeInt(mLac);
+ dest.writeInt(mCid);
+ dest.writeInt(mPsc);
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public static final Creator<GsmCellIdentity> CREATOR =
+ new Creator<GsmCellIdentity>() {
+ @Override
+ public GsmCellIdentity createFromParcel(Parcel in) {
+ return new GsmCellIdentity(in);
+ }
+
+ @Override
+ public GsmCellIdentity[] newArray(int size) {
+ return new GsmCellIdentity[size];
+ }
+ };
+}
diff --git a/telephony/java/android/telephony/LteCellIdentity.java b/telephony/java/android/telephony/LteCellIdentity.java
new file mode 100644
index 0000000..396922e
--- /dev/null
+++ b/telephony/java/android/telephony/LteCellIdentity.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * CellIdentity is to represent a unique LTE cell
+ *
+ * @hide pending API review
+ */
+public final class LteCellIdentity extends CellIdentity implements Parcelable {
+
+ // 3-digit Mobile Country Code, 0..999
+ private final int mMcc;
+ // 2 or 3-digit Mobile Network Code, 0..999
+ private final int mMnc;
+ // 28-bit cell identity
+ private final int mCi;
+ // physical cell id 0..503
+ private final int mPci;
+ // 16-bit tracking area code
+ private final int mTac;
+
+ /**
+ *
+ * @param mcc 3-digit Mobile Country Code, 0..999
+ * @param mnc 2 or 3-digit Mobile Network Code, 0..999
+ * @param ci 28-bit Cell Identity
+ * @param pci Physical Cell Id 0..503
+ * @param tac 16-bit Tracking Area Code
+ * @param attr is comma separated “key=value” attribute pairs.
+ */
+ public LteCellIdentity (int mcc, int mnc,
+ int ci, int pci, int tac, String attr) {
+ super(CELLID_TYPE_CDMA, attr);
+ mMcc = mcc;
+ mMnc = mnc;
+ mCi = ci;
+ mPci = pci;
+ mTac = tac;
+ }
+
+ private LteCellIdentity(Parcel in) {
+ super(in);
+ mMcc = in.readInt();
+ mMnc = in.readInt();
+ mCi = in.readInt();
+ mPci = in.readInt();
+ mTac = in.readInt();
+ }
+
+ LteCellIdentity(LteCellIdentity cid) {
+ super(cid);
+ mMcc = cid.mMcc;
+ mMnc = cid.mMnc;
+ mCi = cid.mCi;
+ mPci = cid.mPci;
+ mTac = cid.mTac;
+ }
+
+ /**
+ * @return 3-digit Mobile Country Code, 0..999
+ */
+ public int getMcc() {
+ return mMcc;
+ }
+
+ /**
+ * @return 2 or 3-digit Mobile Network Code, 0..999
+ */
+ public int getMnc() {
+ return mMnc;
+ }
+
+ /**
+ * @return 28-bit Cell Identity
+ */
+ public int getCi() {
+ return mCi;
+ }
+
+ /**
+ * @return Physical Cell Id 0..503
+ */
+ public int getPci() {
+ return mPci;
+ }
+
+ /**
+ * @return 16-bit Tracking Area Code
+ */
+ public int getTac() {
+ return mTac;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeInt(mMcc);
+ dest.writeInt(mMnc);
+ dest.writeInt(mCi);
+ dest.writeInt(mPci);
+ dest.writeInt(mTac);
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public static final Creator<LteCellIdentity> CREATOR =
+ new Creator<LteCellIdentity>() {
+ @Override
+ public LteCellIdentity createFromParcel(Parcel in) {
+ return new LteCellIdentity(in);
+ }
+
+ @Override
+ public LteCellIdentity[] newArray(int size) {
+ return new LteCellIdentity[size];
+ }
+ };
+}
diff --git a/telephony/java/android/telephony/NeighboringCellInfo.aidl b/telephony/java/android/telephony/NeighboringCellInfo.aidl
index c464332..8588970 100644
--- a/telephony/java/android/telephony/NeighboringCellInfo.aidl
+++ b/telephony/java/android/telephony/NeighboringCellInfo.aidl
@@ -1,4 +1,4 @@
-/* //device/java/android/android/content/Intent.aidl
+/*
**
** Copyright 2007, The Android Open Source Project
**
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index eda9b71..698206c 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -22,6 +22,7 @@
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.CellLocation;
+import android.telephony.CellInfo;
import android.util.Log;
import com.android.internal.telephony.IPhoneStateListener;
@@ -156,6 +157,14 @@
*/
public static final int LISTEN_OTASP_CHANGED = 0x00000200;
+ /**
+ * Listen for changes to observed cell info.
+ *
+ * @see #onCellInfoChanged
+ * @hide pending API review
+ */
+ public static final int LISTEN_CELL_INFO = 0x00000400;
+
public PhoneStateListener() {
}
@@ -276,6 +285,20 @@
}
/**
+ * Callback invoked when a observed cell info gets changed.
+ *
+ * A notification should be sent when:
+ * 1. a cell is newly-observed.
+ * 2. a observed cell is not visible.
+ * 3. any of the cell info of a observed cell has changed.
+ *
+ * @hide pending API review
+ */
+ public void onCellInfoChanged(CellInfo cellInfo) {
+ // default implementation empty
+ }
+
+ /**
* The callback methods need to be called on the handler thread where
* this object was created. If the binder did that for us it'd be nice.
*/
@@ -323,6 +346,10 @@
public void onOtaspChanged(int otaspMode) {
Message.obtain(mHandler, LISTEN_OTASP_CHANGED, otaspMode, 0).sendToTarget();
}
+
+ public void onCellInfoChanged(CellInfo cellInfo) {
+ Message.obtain(mHandler, LISTEN_CELL_INFO, 0, 0).sendToTarget();
+ }
};
Handler mHandler = new Handler() {
@@ -360,6 +387,8 @@
case LISTEN_OTASP_CHANGED:
PhoneStateListener.this.onOtaspChanged(msg.arg1);
break;
+ case LISTEN_CELL_INFO:
+ PhoneStateListener.this.onCellInfoChanged((CellInfo)msg.obj);
}
}
};
diff --git a/telephony/java/android/telephony/ServiceState.aidl b/telephony/java/android/telephony/ServiceState.aidl
index 8522889..830e2cbf 100644
--- a/telephony/java/android/telephony/ServiceState.aidl
+++ b/telephony/java/android/telephony/ServiceState.aidl
@@ -1,4 +1,4 @@
-/* //device/java/android/android/content/Intent.aidl
+/*
**
** Copyright 2007, The Android Open Source Project
**
diff --git a/telephony/java/android/telephony/SignalStrength.aidl b/telephony/java/android/telephony/SignalStrength.aidl
index c25411e..e988c5f 100644
--- a/telephony/java/android/telephony/SignalStrength.aidl
+++ b/telephony/java/android/telephony/SignalStrength.aidl
@@ -1,4 +1,4 @@
-/* //device/java/android/android/content/Intent.aidl
+/*
**
** Copyright (C) 2009 Qualcomm Innovation Center, Inc. All Rights Reserved.
** Copyright (C) 2009 The Android Open Source Project
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index db78e2e..bc50906 100755
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -23,7 +23,6 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
-import android.util.Log;
import com.android.internal.telephony.IPhoneSubInfo;
import com.android.internal.telephony.ITelephony;
@@ -85,6 +84,10 @@
return sInstance;
}
+ /** {@hide} */
+ public static TelephonyManager from(Context context) {
+ return (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+ }
//
// Broadcast Intent actions
@@ -1138,4 +1141,24 @@
return sContext.getResources().getBoolean(
com.android.internal.R.bool.config_sms_capable);
}
+
+ /**
+ * Returns all observed cell information of the device.
+ *
+ * @return List of CellInfo or null if info unavailable.
+ *
+ * <p>Requires Permission:
+ * (@link android.Manifest.permission#ACCESS_COARSE_UPDATES}
+ *
+ * @hide pending API review
+ */
+ public List<CellInfo> getAllCellInfo() {
+ try {
+ return getITelephony().getAllCellInfo();
+ } catch (RemoteException ex) {
+ return null;
+ } catch (NullPointerException ex) {
+ return null;
+ }
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
index f769157..eb78a53e 100644
--- a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
+++ b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
@@ -21,6 +21,7 @@
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.telephony.CellInfo;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.util.Log;
@@ -156,6 +157,14 @@
}
}
+ public void notifyCellInfo(Phone sender, CellInfo cellInfo) {
+ try {
+ mRegistry.notifyCellInfo(cellInfo);
+ } catch (RemoteException ex) {
+
+ }
+ }
+
public void notifyOtaspChanged(Phone sender, int otaspMode) {
try {
mRegistry.notifyOtaspChanged(otaspMode);
diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
index 082c097..d6a1edd 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -19,6 +19,7 @@
import android.os.Bundle;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
+import android.telephony.CellInfo;
oneway interface IPhoneStateListener {
void onServiceStateChanged(in ServiceState serviceState);
@@ -33,5 +34,6 @@
void onDataActivity(int direction);
void onSignalStrengthsChanged(in SignalStrength signalStrength);
void onOtaspChanged(in int otaspMode);
+ void onCellInfoChanged(in CellInfo cellInfo);
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 19441cd..12a7286 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -19,6 +19,7 @@
import android.os.Bundle;
import java.util.List;
import android.telephony.NeighboringCellInfo;
+import android.telephony.CellInfo;
/**
* Interface used to interact with the phone. Mostly this is used by the
@@ -278,5 +279,10 @@
* or {@link PHone#LTE_ON_CDMA_TRUE}
*/
int getLteOnCdmaMode();
+
+ /**
+ * Returns the all observed cell information of the device.
+ */
+ List<CellInfo> getAllCellInfo();
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 1f19282..3c9a99b 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -22,6 +22,7 @@
import android.os.Bundle;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
+import android.telephony.CellInfo;
import com.android.internal.telephony.IPhoneStateListener;
interface ITelephonyRegistry {
@@ -39,4 +40,5 @@
void notifyDataConnectionFailed(String reason, String apnType);
void notifyCellLocation(in Bundle cellLocation);
void notifyOtaspChanged(in int otaspMode);
+ void notifyCellInfo(in CellInfo cellInfo);
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneNotifier.java b/telephony/java/com/android/internal/telephony/PhoneNotifier.java
index 28a8d22..1076870 100644
--- a/telephony/java/com/android/internal/telephony/PhoneNotifier.java
+++ b/telephony/java/com/android/internal/telephony/PhoneNotifier.java
@@ -16,6 +16,8 @@
package com.android.internal.telephony;
+import android.telephony.CellInfo;
+
/**
* {@hide}
*/
@@ -42,4 +44,7 @@
public void notifyDataActivity(Phone sender);
public void notifyOtaspChanged(Phone sender, int otaspMode);
+
+ // TODO - trigger notifyCellInfo from ServiceStateTracker
+ public void notifyCellInfo(Phone sender, CellInfo cellInfo);
}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java
index 7bbe696..cb67a93 100644
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java
@@ -17,6 +17,7 @@
package com.android.internal.telephony;
import com.android.internal.telephony.Phone;
+import android.telephony.CellInfo;
/**
* Stub class used for unit tests
@@ -59,4 +60,7 @@
public void notifyOtaspChanged(Phone sender, int otaspMode) {
}
+
+ public void notifyCellInfo(Phone sender, CellInfo cellInfo) {
+ }
}
diff --git a/tests/DataIdleTest/src/com/android/tests/dataidle/DataIdleTest.java b/tests/DataIdleTest/src/com/android/tests/dataidle/DataIdleTest.java
index a13c0c9..b7e80d4 100644
--- a/tests/DataIdleTest/src/com/android/tests/dataidle/DataIdleTest.java
+++ b/tests/DataIdleTest/src/com/android/tests/dataidle/DataIdleTest.java
@@ -52,7 +52,7 @@
* Test that dumps all the data usage metrics for wifi to instrumentation out.
*/
public void testWifiIdle() {
- NetworkTemplate template = NetworkTemplate.buildTemplateWifi();
+ NetworkTemplate template = NetworkTemplate.buildTemplateWifiWildcard();
fetchStats(template);
}
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index c3ac22c..1f6279c 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -255,41 +255,6 @@
}
@SmallTest
- public void testINJECT_EVENTS() {
- try {
- mWm.injectKeyEvent(new KeyEvent(0, 0), false);
- fail("IWindowManager.injectKeyEvent did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
- mWm.injectPointerEvent(MotionEvent.obtain(0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0), false);
- fail("IWindowManager.injectPointerEvent did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
- mWm.injectTrackballEvent(MotionEvent.obtain(0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0), false);
- fail("IWindowManager.injectTrackballEvent did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
- }
-
- @SmallTest
public void testDISABLE_KEYGUARD() {
Binder token = new Binder();
try {
@@ -347,73 +312,9 @@
}
@SmallTest
- public void testREAD_INPUT_STATE() {
- try {
- mWm.getSwitchState(0);
- fail("IWindowManager.getSwitchState did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
- mWm.getSwitchStateForDevice(0, 0);
- fail("IWindowManager.getSwitchStateForDevice did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
- mWm.getScancodeState(0);
- fail("IWindowManager.getScancodeState did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
- mWm.getScancodeStateForDevice(0, 0);
- fail("IWindowManager.getScancodeStateForDevice did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
- mWm.getKeycodeState(0);
- fail("IWindowManager.getKeycodeState did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
- mWm.getKeycodeStateForDevice(0, 0);
- fail("IWindowManager.getKeycodeStateForDevice did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
- }
-
- @SmallTest
public void testSET_ORIENTATION() {
try {
- mWm.updateRotation(true);
- mWm.getSwitchState(0);
+ mWm.updateRotation(true, false);
fail("IWindowManager.updateRotation did not throw SecurityException as"
+ " expected");
} catch (SecurityException e) {
@@ -424,7 +325,6 @@
try {
mWm.freezeRotation(-1);
- mWm.getSwitchState(0);
fail("IWindowManager.freezeRotation did not throw SecurityException as"
+ " expected");
} catch (SecurityException e) {
@@ -435,7 +335,6 @@
try {
mWm.thawRotation();
- mWm.getSwitchState(0);
fail("IWindowManager.thawRotation did not throw SecurityException as"
+ " expected");
} catch (SecurityException e) {
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 198fce4..689aa8e 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -639,6 +639,12 @@
// If an app requests write storage, they will also get read storage.
bool hasReadExternalStoragePermission = false;
+ // Implement transition to read and write call log.
+ bool hasReadContactsPermission = false;
+ bool hasWriteContactsPermission = false;
+ bool hasReadCallLogPermission = false;
+ bool hasWriteCallLogPermission = false;
+
// This next group of variables is used to implement a group of
// backward-compatibility heuristics necessitated by the addition of
// some new uses-feature constants in 2.1 and 2.2. In most cases, the
@@ -1006,6 +1012,14 @@
hasReadExternalStoragePermission = true;
} else if (name == "android.permission.READ_PHONE_STATE") {
hasReadPhoneStatePermission = true;
+ } else if (name == "android.permission.READ_CONTACTS") {
+ hasReadContactsPermission = true;
+ } else if (name == "android.permission.WRITE_CONTACTS") {
+ hasWriteContactsPermission = true;
+ } else if (name == "android.permission.READ_CALL_LOG") {
+ hasReadCallLogPermission = true;
+ } else if (name == "android.permission.WRITE_CALL_LOG") {
+ hasWriteCallLogPermission = true;
}
printf("uses-permission:'%s'\n", name.string());
} else {
@@ -1181,6 +1195,16 @@
printf("uses-permission:'android.permission.READ_EXTERNAL_STORAGE'\n");
}
+ // Pre-JellyBean call log permission compatibility.
+ if (targetSdk < 16) {
+ if (!hasReadCallLogPermission && hasReadContactsPermission) {
+ printf("uses-permission:'android.permission.READ_CALL_LOG'\n");
+ }
+ if (!hasWriteCallLogPermission && hasWriteContactsPermission) {
+ printf("uses-permission:'android.permission.WRITE_CALL_LOG'\n");
+ }
+ }
+
/* The following blocks handle printing "inferred" uses-features, based
* on whether related features or permissions are used by the app.
* Note that the various spec*Feature variables denote whether the
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
index 8b1d41a..e6c9351 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
@@ -88,7 +88,7 @@
// ---- unused implementation of IWindowManager ----
@Override
- public boolean canStatusBarHide() throws RemoteException {
+ public boolean hasSystemNavBar() throws RemoteException {
// TODO Auto-generated method stub
return false;
}
@@ -161,92 +161,11 @@
}
@Override
- public int getDPadKeycodeState(int arg0) throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public int getDPadScancodeState(int arg0) throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-
-
- @Override
- public InputDevice getInputDevice(int arg0) throws RemoteException {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public int[] getInputDeviceIds() throws RemoteException {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public int getKeycodeState(int arg0) throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public int getKeycodeStateForDevice(int arg0, int arg1) throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-
-
- @Override
public int getPendingAppTransition() throws RemoteException {
// TODO Auto-generated method stub
return 0;
}
-
- @Override
- public int getScancodeState(int arg0) throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public int getScancodeStateForDevice(int arg0, int arg1) throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public int getSwitchState(int arg0) throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public int getSwitchStateForDevice(int arg0, int arg1) throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public int getTrackballKeycodeState(int arg0) throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public int getTrackballScancodeState(int arg0) throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public boolean hasKeys(int[] arg0, boolean[] arg1) throws RemoteException {
- // TODO Auto-generated method stub
- return false;
- }
-
@Override
public boolean inKeyguardRestrictedInputMode() throws RemoteException {
// TODO Auto-generated method stub
@@ -254,30 +173,6 @@
}
@Override
- public boolean injectInputEventNoWait(InputEvent arg0) throws RemoteException {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public boolean injectKeyEvent(KeyEvent arg0, boolean arg1) throws RemoteException {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public boolean injectPointerEvent(MotionEvent arg0, boolean arg1) throws RemoteException {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public boolean injectTrackballEvent(MotionEvent arg0, boolean arg1) throws RemoteException {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
public boolean inputMethodClientHasFocus(IInputMethodClient arg0) throws RemoteException {
// TODO Auto-generated method stub
return false;
@@ -302,12 +197,6 @@
}
@Override
- public InputChannel monitorInput(String arg0) throws RemoteException {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
public void moveAppToken(int arg0, IBinder arg1) throws RemoteException {
// TODO Auto-generated method stub
@@ -462,15 +351,8 @@
}
@Override
- public void setPointerSpeed(int arg0) throws RemoteException {
+ public void updateRotation(boolean arg0, boolean arg1) throws RemoteException {
// TODO Auto-generated method stub
-
- }
-
- @Override
- public void updateRotation(boolean arg0) throws RemoteException {
- // TODO Auto-generated method stub
-
}
@Override