summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-02-13 12:57:50 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-02-13 12:57:50 -0800
commitda996f390e17e16f2dfa60e972e7ebc4f868f37e (patch)
tree00a0f15270d4c7b619fd34d8383257e1761082f4 /core
parentd24b8183b93e781080b2c16c487e60d51c12da31 (diff)
downloadframeworks_base-da996f390e17e16f2dfa60e972e7ebc4f868f37e.zip
frameworks_base-da996f390e17e16f2dfa60e972e7ebc4f868f37e.tar.gz
frameworks_base-da996f390e17e16f2dfa60e972e7ebc4f868f37e.tar.bz2
auto import from //branches/cupcake/...@131421
Diffstat (limited to 'core')
-rw-r--r--core/java/android/app/LauncherActivity.java17
-rw-r--r--core/java/android/app/SearchDialog.java8
-rw-r--r--core/java/android/content/Intent.java2
-rw-r--r--core/java/android/gadget/GadgetHost.java24
-rw-r--r--core/java/android/gadget/GadgetHostView.java206
-rw-r--r--core/java/android/gadget/GadgetManager.java170
-rwxr-xr-xcore/java/android/gadget/GadgetProvider.java53
-rw-r--r--core/java/android/gadget/GadgetProviderInfo.aidl (renamed from core/java/android/gadget/GadgetInfo.aidl)2
-rw-r--r--core/java/android/gadget/GadgetProviderInfo.java (renamed from core/java/android/gadget/GadgetInfo.java)58
-rw-r--r--core/java/android/gadget/package.html123
-rw-r--r--core/java/android/hardware/Camera.java17
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java85
-rwxr-xr-xcore/java/android/inputmethodservice/KeyboardView.java4
-rw-r--r--core/java/android/net/UrlQuerySanitizer.java126
-rw-r--r--core/java/android/pim/RecurrenceSet.java1
-rw-r--r--core/java/android/preference/PreferenceGroupAdapter.java3
-rw-r--r--core/java/android/provider/Settings.java22
-rw-r--r--core/java/android/server/BluetoothDeviceService.java61
-rw-r--r--core/java/android/server/BluetoothEventLoop.java83
-rw-r--r--core/java/android/text/method/ArrowKeyMovementMethod.java9
-rw-r--r--core/java/android/text/method/MetaKeyKeyListener.java8
-rw-r--r--core/java/android/text/method/PasswordTransformationMethod.java6
-rw-r--r--core/java/android/view/HapticFeedbackConstants.java45
-rw-r--r--core/java/android/view/IWindowSession.aidl3
-rw-r--r--core/java/android/view/View.java105
-rw-r--r--core/java/android/view/ViewRoot.java15
-rw-r--r--core/java/android/view/WindowManager.java2
-rw-r--r--core/java/android/view/WindowManagerPolicy.java11
-rw-r--r--core/java/android/view/inputmethod/BaseInputConnection.java30
-rw-r--r--core/java/android/view/inputmethod/InputConnection.java26
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java33
-rw-r--r--core/java/android/webkit/CookieManager.java9
-rw-r--r--core/java/android/webkit/WebView.java126
-rw-r--r--core/java/android/webkit/WebViewCore.java6
-rw-r--r--core/java/android/webkit/WebViewDatabase.java47
-rw-r--r--core/java/android/widget/AbsListView.java4
-rw-r--r--core/java/android/widget/CursorFilter.java5
-rw-r--r--core/java/android/widget/DatePicker.java27
-rw-r--r--core/java/android/widget/Filter.java6
-rw-r--r--core/java/android/widget/Gallery.java6
-rw-r--r--core/java/android/widget/ImageView.java1
-rw-r--r--core/java/android/widget/RemoteViews.java69
-rw-r--r--core/java/android/widget/TextView.java2
-rw-r--r--core/java/android/widget/ViewAnimator.java3
-rw-r--r--core/java/android/widget/ViewFlipper.java4
-rw-r--r--core/java/android/widget/ZoomButton.java2
-rw-r--r--core/java/android/widget/ZoomRing.java271
-rw-r--r--core/java/android/widget/ZoomRingController.java64
-rw-r--r--core/java/com/android/internal/gadget/IGadgetHost.aidl3
-rw-r--r--core/java/com/android/internal/gadget/IGadgetService.aidl6
-rw-r--r--core/java/com/android/internal/view/IInputConnectionWrapper.java24
-rw-r--r--core/java/com/android/internal/view/IInputContext.aidl6
-rw-r--r--core/java/com/android/internal/view/IInputMethodManager.aidl2
-rw-r--r--core/java/com/android/internal/view/InputConnectionWrapper.java13
-rw-r--r--core/java/com/android/internal/widget/NumberPicker.java62
-rw-r--r--core/jni/android_media_AudioRecord.cpp37
-rw-r--r--core/jni/android_media_AudioSystem.cpp16
-rw-r--r--core/jni/android_media_AudioTrack.cpp33
-rw-r--r--core/jni/android_server_BluetoothEventLoop.cpp4
-rw-r--r--core/jni/android_util_EventLog.cpp2
-rw-r--r--core/res/res/drawable/presence_away.pngbin3500 -> 810 bytes
-rw-r--r--core/res/res/drawable/presence_busy.pngbin3529 -> 811 bytes
-rw-r--r--core/res/res/drawable/presence_invisible.pngbin1084 -> 693 bytes
-rw-r--r--core/res/res/drawable/presence_offline.pngbin3577 -> 767 bytes
-rw-r--r--core/res/res/drawable/presence_online.pngbin3528 -> 812 bytes
-rw-r--r--core/res/res/drawable/zoom_ring_trail.xml37
-rw-r--r--core/res/res/layout/date_picker.xml1
-rw-r--r--core/res/res/layout/date_picker_dialog.xml14
-rw-r--r--core/res/res/layout/number_picker.xml30
-rw-r--r--core/res/res/layout/number_picker_edit.xml1
-rw-r--r--core/res/res/layout/time_picker.xml2
-rw-r--r--core/res/res/layout/time_picker_dialog.xml14
-rw-r--r--core/res/res/layout/time_picker_text.xml27
-rw-r--r--core/res/res/values-cs-rCZ/strings.xml1112
-rw-r--r--core/res/res/values-cs/strings.xml1
-rw-r--r--core/res/res/values-de/strings.xml1
-rw-r--r--core/res/res/values-en-rGB/strings.xml762
-rw-r--r--core/res/res/values-es/strings.xml1
-rw-r--r--core/res/res/values-fr/strings.xml1
-rw-r--r--core/res/res/values-it/strings.xml1
-rw-r--r--core/res/res/values-ja/strings.xml16
-rw-r--r--core/res/res/values-ko/strings.xml1
-rw-r--r--core/res/res/values-nb/strings.xml162
-rw-r--r--core/res/res/values-nl/strings.xml1
-rw-r--r--core/res/res/values-pl/strings.xml1
-rw-r--r--core/res/res/values-ru/strings.xml1
-rw-r--r--core/res/res/values-zh-rCN/strings.xml1
-rw-r--r--core/res/res/values-zh-rTW/strings.xml1
-rw-r--r--core/res/res/values/attrs.xml14
-rw-r--r--core/res/res/values/public.xml3
-rw-r--r--core/res/res/values/strings.xml3
91 files changed, 1645 insertions, 2782 deletions
diff --git a/core/java/android/app/LauncherActivity.java b/core/java/android/app/LauncherActivity.java
index c363f04..d6fcbb1 100644
--- a/core/java/android/app/LauncherActivity.java
+++ b/core/java/android/app/LauncherActivity.java
@@ -18,7 +18,6 @@ package android.app;
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.res.Resources;
@@ -31,9 +30,7 @@ import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.PaintDrawable;
-import android.os.AsyncTask;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -145,17 +142,6 @@ public abstract class LauncherActivity extends ListActivity {
return view;
}
- private char getCandidateLetter(ResolveInfo info) {
- PackageManager pm = LauncherActivity.this.getPackageManager();
- CharSequence label = info.loadLabel(pm);
-
- if (label == null) {
- label = info.activityInfo.name;
- }
-
- return Character.toLowerCase(label.charAt(0));
- }
-
private void bindView(View view, ListItem item) {
TextView text = (TextView) view;
text.setText(item.label);
@@ -191,7 +177,6 @@ public abstract class LauncherActivity extends ListActivity {
results.count = list.size();
}
} else {
- final PackageManager pm = LauncherActivity.this.getPackageManager();
final String prefixString = prefix.toString().toLowerCase();
ArrayList<ListItem> values = mOriginalValues;
@@ -243,8 +228,6 @@ public abstract class LauncherActivity extends ListActivity {
private int mIconWidth = -1;
private int mIconHeight = -1;
- private final Paint mPaint = new Paint();
- private final Rect mBounds = new Rect();
private final Rect mOldBounds = new Rect();
private Canvas mCanvas = new Canvas();
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 64f1ba2..5744ddc 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -835,9 +835,6 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
// also guard against possible race conditions (late arrival after dismiss)
if (mSearchable != null) {
handled = doSuggestionsKey(v, keyCode, event);
- if (!handled) {
- handled = refocusingKeyListener(v, keyCode, event);
- }
}
return handled;
}
@@ -1024,6 +1021,11 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
* @param jamQuery True means to set the query, false means to reset it to the user's choice
*/
private void jamSuggestionQuery(boolean jamQuery, AdapterView<?> parent, int position) {
+ // quick check against race conditions
+ if (mSearchable == null) {
+ return;
+ }
+
mSuggestionsAdapter.setNonUserQuery(true); // disables any suggestions processing
if (jamQuery) {
CursorAdapter ca = getSuggestionsAdapter(parent);
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 52aae0d..c4d3f9d 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1112,6 +1112,8 @@ public class Intent implements Parcelable {
* <p>My include the following extras:
* <ul>
* <li> {@link #EXTRA_UID} containing the integer uid assigned to the new package.
+ * <li> {@link #EXTRA_REPLACING} is set to true if this is following
+ * an {@link #ACTION_PACKAGE_REMOVED} broadcast for the same package.
* </ul>
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
diff --git a/core/java/android/gadget/GadgetHost.java b/core/java/android/gadget/GadgetHost.java
index 9176d18..31aed32 100644
--- a/core/java/android/gadget/GadgetHost.java
+++ b/core/java/android/gadget/GadgetHost.java
@@ -38,6 +38,7 @@ import com.android.internal.gadget.IGadgetService;
public class GadgetHost {
static final int HANDLE_UPDATE = 1;
+ static final int HANDLE_PROVIDER_CHANGED = 2;
static Object sServiceLock = new Object();
static IGadgetService sService;
@@ -52,6 +53,13 @@ public class GadgetHost {
msg.obj = views;
msg.sendToTarget();
}
+
+ public void providerChanged(int gadgetId, GadgetProviderInfo info) {
+ Message msg = mHandler.obtainMessage(HANDLE_PROVIDER_CHANGED);
+ msg.arg1 = gadgetId;
+ msg.obj = info;
+ msg.sendToTarget();
+ }
}
Handler mHandler = new Handler() {
@@ -61,6 +69,10 @@ public class GadgetHost {
updateGadgetView(msg.arg1, (RemoteViews)msg.obj);
break;
}
+ case HANDLE_PROVIDER_CHANGED: {
+ onProviderChanged(msg.arg1, (GadgetProviderInfo)msg.obj);
+ break;
+ }
}
}
};
@@ -183,7 +195,8 @@ public class GadgetHost {
}
}
- public final GadgetHostView createView(Context context, int gadgetId, GadgetInfo gadget) {
+ public final GadgetHostView createView(Context context, int gadgetId,
+ GadgetProviderInfo gadget) {
GadgetHostView view = onCreateView(context, gadgetId, gadget);
view.setGadget(gadgetId, gadget);
synchronized (mViews) {
@@ -203,9 +216,16 @@ public class GadgetHost {
* Called to create the GadgetHostView. Override to return a custom subclass if you
* need it. {@more}
*/
- protected GadgetHostView onCreateView(Context context, int gadgetId, GadgetInfo gadget) {
+ protected GadgetHostView onCreateView(Context context, int gadgetId,
+ GadgetProviderInfo gadget) {
return new GadgetHostView(context);
}
+
+ /**
+ * Called when the gadget provider for a gadget has been upgraded to a new apk.
+ */
+ protected void onProviderChanged(int gadgetId, GadgetProviderInfo gadget) {
+ }
void updateGadgetView(int gadgetId, RemoteViews views) {
GadgetHostView v;
diff --git a/core/java/android/gadget/GadgetHostView.java b/core/java/android/gadget/GadgetHostView.java
index d92c123..a985bd4 100644
--- a/core/java/android/gadget/GadgetHostView.java
+++ b/core/java/android/gadget/GadgetHostView.java
@@ -18,7 +18,6 @@ package android.gadget;
import android.content.Context;
import android.content.pm.PackageManager;
-import android.gadget.GadgetInfo;
import android.graphics.Color;
import android.util.Config;
import android.util.Log;
@@ -26,12 +25,18 @@ import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.animation.Animation;
import android.widget.FrameLayout;
import android.widget.RemoteViews;
import android.widget.TextView;
import android.widget.ViewAnimator;
-public class GadgetHostView extends ViewAnimator {
+/**
+ * Provides the glue to show gadget views. This class offers automatic animation
+ * between updates, and will try recycling old views for each incoming
+ * {@link RemoteViews}.
+ */
+public class GadgetHostView extends ViewAnimator implements Animation.AnimationListener {
static final String TAG = "GadgetHostView";
static final boolean LOGD = Config.LOGD || true;
@@ -42,57 +47,93 @@ public class GadgetHostView extends ViewAnimator {
return clazz.isAnnotationPresent(RemoteViews.RemoteView.class);
}
};
-
+
+ Context mLocalContext;
+
int mGadgetId;
- GadgetInfo mInfo;
- View mActiveView;
- View mStaleView;
+ GadgetProviderInfo mInfo;
- protected int mDefaultGravity = Gravity.CENTER;
-
+ View mActiveView = null;
+ View mStaleView = null;
+
+ int mActiveLayoutId = -1;
+ int mStaleLayoutId = -1;
+
+ /**
+ * Last set of {@link RemoteViews} applied to {@link #mActiveView}
+ */
+ RemoteViews mActiveActions = null;
+
+ /**
+ * Flag indicating that {@link #mActiveActions} has been applied to
+ * {@link #mStaleView}, meaning it's readyto recycle.
+ */
+ boolean mStalePrepared = false;
+
+ /**
+ * Create a host view. Uses default fade animations.
+ */
public GadgetHostView(Context context) {
- super(context);
+ this(context, android.R.anim.fade_in, android.R.anim.fade_out);
}
- public void setGadget(int gadgetId, GadgetInfo info) {
- if (LOGD) Log.d(TAG, "setGadget is incoming with info=" + info);
+ /**
+ * Create a host view. Uses specified animations when pushing
+ * {@link #updateGadget(RemoteViews)}.
+ *
+ * @param animationIn Resource ID of in animation to use
+ * @param animationOut Resource ID of out animation to use
+ */
+ public GadgetHostView(Context context, int animationIn, int animationOut) {
+ super(context);
+ mLocalContext = context;
+
+ // Prepare our default transition animations
+ setAnimateFirstView(true);
+ setInAnimation(context, animationIn);
+ setOutAnimation(context, animationOut);
+
+ // Watch for animation events to prepare recycling
+ Animation inAnimation = getInAnimation();
+ if (inAnimation != null) {
+ inAnimation.setAnimationListener(this);
+ }
+ }
+
+ /**
+ * Set the gadget that will be displayed by this view.
+ */
+ public void setGadget(int gadgetId, GadgetProviderInfo info) {
if (mInfo != null) {
// TODO: remove the old view, or whatever
}
mGadgetId = gadgetId;
mInfo = info;
-
- View defaultView = getDefaultView();
- flipUpdate(defaultView);
}
- /**
- * Trigger actual animation between current and new content in the
- * {@link ViewAnimator}.
- */
- protected void flipUpdate(View newContent) {
- if (LOGD) Log.d(TAG, "pushing an update to surface");
-
- // Take requested dimensions from parent, but apply default gravity.
- ViewGroup.LayoutParams requested = newContent.getLayoutParams();
- if (requested == null) {
- requested = new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT,
- LayoutParams.FILL_PARENT);
+ public int getGadgetId() {
+ return mGadgetId;
+ }
+
+ public GadgetProviderInfo getGadgetInfo() {
+ return mInfo;
+ }
+
+ public void onAnimationEnd(Animation animation) {
+ // When our transition animation finishes, we should try bringing our
+ // newly-stale view up to the current view.
+ if (mActiveActions != null &&
+ mStaleLayoutId == mActiveActions.getLayoutId()) {
+ if (LOGD) Log.d(TAG, "after animation, layoutId matched so we're recycling old view");
+ mActiveActions.reapply(mLocalContext, mStaleView);
+ mStalePrepared = true;
}
-
- FrameLayout.LayoutParams params =
- new FrameLayout.LayoutParams(requested.width, requested.height);
- params.gravity = mDefaultGravity;
- newContent.setLayoutParams(params);
-
- // Add new content and animate to it
- addView(newContent);
- showNext();
-
- // Dispose old stale view
- removeView(mStaleView);
- mStaleView = mActiveView;
- mActiveView = newContent;
+ }
+
+ public void onAnimationRepeat(Animation animation) {
+ }
+
+ public void onAnimationStart(Animation animation) {
}
/**
@@ -100,26 +141,42 @@ public class GadgetHostView extends ViewAnimator {
* gadget provider. Will animate into these new views as needed.
*/
public void updateGadget(RemoteViews remoteViews) {
- if (LOGD) Log.d(TAG, "updateGadget() with remoteViews = " + remoteViews);
+ if (LOGD) Log.d(TAG, "updateGadget called");
+ boolean recycled = false;
View newContent = null;
Exception exception = null;
- try {
- if (remoteViews == null) {
- // there is no remoteViews (yet), so use the initial layout
- newContent = getDefaultView();
- } else {
- // use the RemoteViews
- // TODO: try applying RemoteViews to existing staleView if available
- newContent = remoteViews.apply(mContext, this);
+ if (remoteViews == null) {
+ newContent = getDefaultView();
+ }
+
+ // If our stale view has been prepared to match active, and the new
+ // layout matches, try recycling it
+ if (newContent == null && mStalePrepared &&
+ remoteViews.getLayoutId() == mStaleLayoutId) {
+ try {
+ remoteViews.reapply(mLocalContext, mStaleView);
+ newContent = mStaleView;
+ recycled = true;
+ if (LOGD) Log.d(TAG, "was able to recycled existing layout");
+ } catch (RuntimeException e) {
+ exception = e;
+ }
+ }
+
+ // Try normal RemoteView inflation
+ if (newContent == null) {
+ try {
+ newContent = remoteViews.apply(mLocalContext, this);
+ if (LOGD) Log.d(TAG, "had to inflate new layout");
+ } catch (RuntimeException e) {
+ exception = e;
}
- } catch (RuntimeException e) {
- exception = e;
}
if (exception != null && LOGD) {
- Log.w(TAG, "Error inflating gadget " + mInfo, exception);
+ Log.w(TAG, "Error inflating gadget " + getGadgetInfo(), exception);
}
if (newContent == null) {
@@ -128,8 +185,44 @@ public class GadgetHostView extends ViewAnimator {
if (LOGD) Log.d(TAG, "updateGadget couldn't find any view, so inflating error");
newContent = getErrorView();
}
-
- flipUpdate(newContent);
+
+ if (!recycled) {
+ prepareView(newContent);
+ addView(newContent);
+ }
+
+ showNext();
+
+ if (!recycled) {
+ removeView(mStaleView);
+ }
+
+ mStalePrepared = false;
+ mActiveActions = remoteViews;
+
+ mStaleView = mActiveView;
+ mActiveView = newContent;
+
+ mStaleLayoutId = mActiveLayoutId;
+ mActiveLayoutId = (remoteViews == null) ? -1 : remoteViews.getLayoutId();
+ }
+
+ /**
+ * Prepare the given view to be shown. This might include adjusting
+ * {@link FrameLayout.LayoutParams} before inserting.
+ */
+ protected void prepareView(View view) {
+ // Take requested dimensions from parent, but apply default gravity.
+ ViewGroup.LayoutParams requested = view.getLayoutParams();
+ if (requested == null) {
+ requested = new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT,
+ LayoutParams.FILL_PARENT);
+ }
+
+ FrameLayout.LayoutParams params =
+ new FrameLayout.LayoutParams(requested.width, requested.height);
+ params.gravity = Gravity.CENTER;
+ view.setLayoutParams(params);
}
/**
@@ -141,7 +234,7 @@ public class GadgetHostView extends ViewAnimator {
try {
if (mInfo != null) {
- Context theirContext = mContext.createPackageContext(
+ Context theirContext = mLocalContext.createPackageContext(
mInfo.provider.getPackageName(), 0 /* no flags */);
LayoutInflater inflater = (LayoutInflater)
theirContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -173,11 +266,10 @@ public class GadgetHostView extends ViewAnimator {
* Inflate and return a view that represents an error state.
*/
protected View getErrorView() {
- TextView tv = new TextView(mContext);
+ TextView tv = new TextView(mLocalContext);
// TODO: move this error string and background color into resources
tv.setText("Error inflating gadget");
tv.setBackgroundColor(Color.argb(127, 0, 0, 0));
return tv;
}
}
-
diff --git a/core/java/android/gadget/GadgetManager.java b/core/java/android/gadget/GadgetManager.java
index 20f4014..a9a2c80 100644
--- a/core/java/android/gadget/GadgetManager.java
+++ b/core/java/android/gadget/GadgetManager.java
@@ -38,68 +38,142 @@ public class GadgetManager {
static final String TAG = "GadgetManager";
/**
- * Send this when you want to pick a gadget to display.
+ * Send this from your gadget host activity when you want to pick a gadget to display.
+ * The gadget picker activity will be launched.
+ * <p>
+ * You must supply the following extras:
+ * <table>
+ * <tr>
+ * <td>{@link #EXTRA_GADGET_ID}</td>
+ * <td>A newly allocated gadgetId, which will be bound to the gadget provider
+ * once the user has selected one.</td>
+ * </tr>
+ * </table>
*
* <p>
* The system will respond with an onActivityResult call with the following extras in
* the intent:
- * <ul>
- * <li><b>gadgetIds</b></li>
- * <li><b>hostId</b></li>
- * </ul>
- * TODO: Add constants for these.
- * TODO: Where does this go?
+ * <table>
+ * <tr>
+ * <td>{@link #EXTRA_GADGET_ID}</td>
+ * <td>The gadgetId that you supplied in the original intent.</td>
+ * </tr>
+ * </table>
+ * <p>
+ * When you receive the result from the gadget pick activity, if the resultCode is
+ * {@link android.app.Activity#RESULT_OK}, a gadget has been selected. You should then
+ * check the GadgetProviderInfo for the returned gadget, and if it has one, launch its configuration
+ * activity. If {@link android.app.Activity#RESULT_CANCELED} is returned, you should delete
+ * the gadgetId.
+ *
+ * @see #ACTION_GADGET_CONFIGURE
+ */
+ public static final String ACTION_GADGET_PICK = "android.gadget.action.GADGET_PICK";
+
+ /**
+ * Sent when it is time to configure your gadget while it is being added to a host.
+ * This action is not sent as a broadcast to the gadget provider, but as a startActivity
+ * to the activity specified in the {@link GadgetProviderInfo GadgetProviderInfo meta-data}.
+ *
+ * <p>
+ * The intent will contain the following extras:
+ * <table>
+ * <tr>
+ * <td>{@link #EXTRA_GADGET_ID}</td>
+ * <td>The gadgetId to configure.</td>
+ * </tr>
+ * </table>
+ *
+ * <p>If you return {@link android.app.Activity#RESULT_OK} using
+ * {@link android.app.Activity#setResult Activity.setResult()}, the gadget will be added,
+ * and you will receive an {@link #ACTION_GADGET_UPDATE} broadcast for this gadget.
+ * If you return {@link android.app.Activity#RESULT_CANCELED}, the host will cancel the add
+ * and not display this gadget, and you will receive a {@link #ACTION_GADGET_DELETED} broadcast.
*/
- public static final String GADGET_PICK_ACTION = "android.gadget.action.PICK_GADGET";
+ public static final String ACTION_GADGET_CONFIGURE = "android.gadget.action.GADGET_CONFIGURE";
+ /**
+ * An intent extra that contains one gadgetId.
+ * <p>
+ * The value will be an int that can be retrieved like this:
+ * {@sample frameworks/base/tests/gadgets/GadgetHostTest/src/com/android/tests/gadgethost/GadgetHostActivity.java getExtra_EXTRA_GADGET_ID}
+ */
public static final String EXTRA_GADGET_ID = "gadgetId";
+
+ /**
+ * An intent extra that contains multiple gadgetIds.
+ * <p>
+ * The value will be an int array that can be retrieved like this:
+ * {@sample frameworks/base/tests/gadgets/GadgetHostTest/src/com/android/tests/gadgethost/TestGadgetProvider.java getExtra_EXTRA_GADGET_IDS}
+ */
public static final String EXTRA_GADGET_IDS = "gadgetIds";
- public static final String EXTRA_HOST_ID = "hostId";
+
+ /**
+ * A sentiel value that the gadget manager will never return as a gadgetId.
+ */
+ public static final int INVALID_GADGET_ID = 0;
/**
* Sent when it is time to update your gadget.
*
* <p>This may be sent in response to a new instance for this gadget provider having
- * been instantiated, the requested {@link GadgetInfo#updatePeriodMillis update interval}
+ * been instantiated, the requested {@link GadgetProviderInfo#updatePeriodMillis update interval}
* having lapsed, or the system booting.
- */
- public static final String GADGET_UPDATE_ACTION = "android.gadget.action.GADGET_UPDATE";
-
- /**
- * Sent when it is time to configure your gadget. This action is not sent as a broadcast
- * to the gadget provider, but as a startActivity to the activity specified in the
- * {@link GadgetInfo GadgetInfo meta-data}.
*
- * <p>The {@link #EXTRA_GADGET_ID} extra contains the gadget ID.
+ * <p>
+ * The intent will contain the following extras:
+ * <table>
+ * <tr>
+ * <td>{@link #EXTRA_GADGET_IDS}</td>
+ * <td>The gadgetIds to update. This may be all of the gadgets created for this
+ * provider, or just a subset. The system tries to send updates for as few gadget
+ * instances as possible.</td>
+ * </tr>
+ * </table>
+ *
+ * @see GadgetProvider#onUpdate GadgetProvider.onUpdate(Context context, GadgetManager gadgetManager, int[] gadgetIds)
*/
- public static final String GADGET_CONFIGURE_ACTION = "android.gadget.action.GADGET_CONFIGURE";
+ public static final String ACTION_GADGET_UPDATE = "android.gadget.action.GADGET_UPDATE";
/**
- * Sent when the gadget is added to a host for the first time. This broadcast is sent at
- * boot time if there is a gadget host installed with an instance for this provider.
+ * Sent when an instance of a gadget is deleted from its host.
+ *
+ * @see GadgetProvider#onDeleted GadgetProvider.onDeleted(Context context, int[] gadgetIds)
*/
- public static final String GADGET_ENABLED_ACTION = "android.gadget.action.GADGET_ENABLED";
+ public static final String ACTION_GADGET_DELETED = "android.gadget.action.GADGET_DELETED";
/**
- * Sent when an instances of a gadget is deleted from the host.
+ * Sent when an instance of a gadget is removed from the last host.
+ *
+ * @see GadgetProvider#onEnabled GadgetProvider.onEnabled(Context context)
*/
- public static final String GADGET_DELETED_ACTION = "android.gadget.action.GADGET_DELETED";
+ public static final String ACTION_GADGET_DISABLED = "android.gadget.action.GADGET_DISABLED";
/**
- * Sent when the gadget is removed from the last host.
+ * Sent when an instance of a gadget is added to a host for the first time.
+ * This broadcast is sent at boot time if there is a gadget host installed with
+ * an instance for this provider.
+ *
+ * @see GadgetProvider#onEnabled GadgetProvider.onEnabled(Context context)
*/
- public static final String GADGET_DISABLED_ACTION = "android.gadget.action.GADGET_DISABLED";
+ public static final String ACTION_GADGET_ENABLED = "android.gadget.action.GADGET_ENABLED";
/**
* Field for the manifest meta-data tag.
+ *
+ * @see GadgetProviderInfo
*/
- public static final String GADGET_PROVIDER_META_DATA = "android.gadget.provider";
+ public static final String META_DATA_GADGET_PROVIDER = "android.gadget.provider";
static WeakHashMap<Context, WeakReference<GadgetManager>> sManagerCache = new WeakHashMap();
static IGadgetService sService;
Context mContext;
+ /**
+ * Get the GadgetManager instance to use for the supplied {@link android.content.Context
+ * Context} object.
+ */
public static GadgetManager getInstance(Context context) {
synchronized (sManagerCache) {
if (sService == null) {
@@ -125,9 +199,11 @@ public class GadgetManager {
}
/**
- * Call this with the new RemoteViews for your gadget whenever you need to.
+ * Set the RemoteViews to use for the specified gadgetIds.
*
* <p>
+ * It is okay to call this method both inside an {@link #ACTION_GADGET_UPDATE} broadcast,
+ * and outside of the handler.
* This method will only work when called from the uid that owns the gadget provider.
*
* @param gadgetIds The gadget instances for which to set the RemoteViews.
@@ -143,9 +219,26 @@ public class GadgetManager {
}
/**
- * Call this with the new RemoteViews for your gadget whenever you need to.
+ * Set the RemoteViews to use for the specified gadgetId.
*
* <p>
+ * It is okay to call this method both inside an {@link #ACTION_GADGET_UPDATE} broadcast,
+ * and outside of the handler.
+ * This method will only work when called from the uid that owns the gadget provider.
+ *
+ * @param gadgetId The gadget instance for which to set the RemoteViews.
+ * @param views The RemoteViews object to show.
+ */
+ public void updateGadget(int gadgetId, RemoteViews views) {
+ updateGadget(new int[] { gadgetId }, views);
+ }
+
+ /**
+ * Set the RemoteViews to use for all gadget instances for the supplied gadget provider.
+ *
+ * <p>
+ * It is okay to call this method both inside an {@link #ACTION_GADGET_UPDATE} broadcast,
+ * and outside of the handler.
* This method will only work when called from the uid that owns the gadget provider.
*
* @param provider The {@link ComponentName} for the {@link
@@ -165,7 +258,7 @@ public class GadgetManager {
/**
* Return a list of the gadget providers that are currently installed.
*/
- public List<GadgetInfo> getInstalledProviders() {
+ public List<GadgetProviderInfo> getInstalledProviders() {
try {
return sService.getInstalledProviders();
}
@@ -175,12 +268,12 @@ public class GadgetManager {
}
/**
- * Get the available info about the gadget. If the gadgetId has not been bound yet,
- * this method will return null.
+ * Get the available info about the gadget.
*
- * TODO: throws GadgetNotFoundException ??? if not valid
+ * @return A gadgetId. If the gadgetId has not been bound to a provider yet, or
+ * you don't have access to that gadgetId, null is returned.
*/
- public GadgetInfo getGadgetInfo(int gadgetId) {
+ public GadgetProviderInfo getGadgetInfo(int gadgetId) {
try {
return sService.getGadgetInfo(gadgetId);
}
@@ -190,7 +283,14 @@ public class GadgetManager {
}
/**
- * Set the component for a given gadgetId. You need the GADGET_LIST permission.
+ * Set the component for a given gadgetId.
+ *
+ * <p class="note">You need the GADGET_LIST permission. This method is to be used by the
+ * gadget picker.
+ *
+ * @param gadgetId The gadget instance for which to set the RemoteViews.
+ * @param provider The {@link android.content.BroadcastReceiver} that will be the gadget
+ * provider for this gadget.
*/
public void bindGadgetId(int gadgetId, ComponentName provider) {
try {
diff --git a/core/java/android/gadget/GadgetProvider.java b/core/java/android/gadget/GadgetProvider.java
index 1ddfe3f..7e10e78 100755
--- a/core/java/android/gadget/GadgetProvider.java
+++ b/core/java/android/gadget/GadgetProvider.java
@@ -55,7 +55,7 @@ public class GadgetProvider extends BroadcastReceiver {
// Protect against rogue update broadcasts (not really a security issue,
// just filter bad broacasts out so subclasses are less likely to crash).
String action = intent.getAction();
- if (GadgetManager.GADGET_UPDATE_ACTION.equals(action)) {
+ if (GadgetManager.ACTION_GADGET_UPDATE.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null) {
int[] gadgetIds = extras.getIntArray(GadgetManager.EXTRA_GADGET_IDS);
@@ -64,7 +64,7 @@ public class GadgetProvider extends BroadcastReceiver {
}
}
}
- else if (GadgetManager.GADGET_DELETED_ACTION.equals(action)) {
+ else if (GadgetManager.ACTION_GADGET_DELETED.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null) {
int[] gadgetIds = extras.getIntArray(GadgetManager.EXTRA_GADGET_IDS);
@@ -73,102 +73,81 @@ public class GadgetProvider extends BroadcastReceiver {
}
}
}
- else if (GadgetManager.GADGET_ENABLED_ACTION.equals(action)) {
+ else if (GadgetManager.ACTION_GADGET_ENABLED.equals(action)) {
this.onEnabled(context);
}
- else if (GadgetManager.GADGET_DISABLED_ACTION.equals(action)) {
+ else if (GadgetManager.ACTION_GADGET_DISABLED.equals(action)) {
this.onDisabled(context);
}
}
// END_INCLUDE(onReceive)
/**
- * Called in response to the {@link GadgetManager#GADGET_UPDATE_ACTION} broadcast when
+ * Called in response to the {@link GadgetManager#ACTION_GADGET_UPDATE} broadcast when
* this gadget provider is being asked to provide {@link android.widget.RemoteViews RemoteViews}
* for a set of gadgets. Override this method to implement your own gadget functionality.
*
* {@more}
- * <p class="note">If you want this method called, you must declare in an intent-filter in
- * your AndroidManifest.xml file that you accept the GADGET_UPDATE_ACTION intent action.
- * For example:
- * <font color=red>TODO: SAMPLE CODE GOES HERE</font>
- * </p>
*
* @param context The {@link android.content.Context Context} in which this receiver is
* running.
* @param gadgetManager A {@link GadgetManager} object you can call {@link
- * GadgetManager#updateGadgets} on.
+ * GadgetManager#updateGadget} on.
* @param gadgetIds The gadgetsIds for which an update is needed. Note that this
* may be all of the gadget instances for this provider, or just
* a subset of them.
*
- * @see GadgetManager#GADGET_UPDATE_ACTION
+ * @see GadgetManager#ACTION_GADGET_UPDATE
*/
public void onUpdate(Context context, GadgetManager gadgetManager, int[] gadgetIds) {
}
/**
- * Called in response to the {@link GadgetManager#GADGET_DELETED_ACTION} broadcast when
+ * Called in response to the {@link GadgetManager#ACTION_GADGET_DELETED} broadcast when
* one or more gadget instances have been deleted. Override this method to implement
* your own gadget functionality.
*
* {@more}
- * <p class="note">If you want this method called, you must declare in an intent-filter in
- * your AndroidManifest.xml file that you accept the GADGET_DELETED_ACTION intent action.
- * For example:
- * <font color=red>TODO: SAMPLE CODE GOES HERE</font>
- * </p>
*
* @param context The {@link android.content.Context Context} in which this receiver is
* running.
* @param gadgetIds The gadgetsIds that have been deleted from their host.
*
- * @see GadgetManager#GADGET_DELETED_ACTION
+ * @see GadgetManager#ACTION_GADGET_DELETED
*/
public void onDeleted(Context context, int[] gadgetIds) {
}
/**
- * Called in response to the {@link GadgetManager#GADGET_ENABLED_ACTION} broadcast when
+ * Called in response to the {@link GadgetManager#ACTION_GADGET_ENABLED} broadcast when
* the a gadget for this provider is instantiated. Override this method to implement your
* own gadget functionality.
*
* {@more}
* When the last gadget for this provider is deleted,
- * {@link GadgetManager#GADGET_DISABLED_ACTION} is sent and {@link #onDisabled}
- * is called. If after that, a gadget for this provider is created again, onEnabled() will
- * be called again.
+ * {@link GadgetManager#ACTION_GADGET_DISABLED} is sent by the gadget manager, and
+ * {@link #onDisabled} is called. If after that, a gadget for this provider is created
+ * again, onEnabled() will be called again.
*
- * <p class="note">If you want this method called, you must declare in an intent-filter in
- * your AndroidManifest.xml file that you accept the GADGET_ENABLED_ACTION intent action.
- * For example:
- * <font color=red>TODO: SAMPLE CODE GOES HERE</font>
- * </p>
- *
* @param context The {@link android.content.Context Context} in which this receiver is
* running.
*
- * @see GadgetManager#GADGET_ENABLED_ACTION
+ * @see GadgetManager#ACTION_GADGET_ENABLED
*/
public void onEnabled(Context context) {
}
/**
- * Called in response to the {@link GadgetManager#GADGET_DISABLED_ACTION} broadcast, which
+ * Called in response to the {@link GadgetManager#ACTION_GADGET_DISABLED} broadcast, which
* is sent when the last gadget instance for this provider is deleted. Override this method
* to implement your own gadget functionality.
*
* {@more}
- * <p class="note">If you want this method called, you must declare in an intent-filter in
- * your AndroidManifest.xml file that you accept the GADGET_DISABLED_ACTION intent action.
- * For example:
- * <font color=red>TODO: SAMPLE CODE GOES HERE</font>
- * </p>
*
* @param context The {@link android.content.Context Context} in which this receiver is
* running.
*
- * @see GadgetManager#GADGET_DISABLED_ACTION
+ * @see GadgetManager#ACTION_GADGET_DISABLED
*/
public void onDisabled(Context context) {
}
diff --git a/core/java/android/gadget/GadgetInfo.aidl b/core/java/android/gadget/GadgetProviderInfo.aidl
index 7231545..589f886 100644
--- a/core/java/android/gadget/GadgetInfo.aidl
+++ b/core/java/android/gadget/GadgetProviderInfo.aidl
@@ -16,4 +16,4 @@
package android.gadget;
-parcelable GadgetInfo;
+parcelable GadgetProviderInfo;
diff --git a/core/java/android/gadget/GadgetInfo.java b/core/java/android/gadget/GadgetProviderInfo.java
index 5ac3da9..95c0432 100644
--- a/core/java/android/gadget/GadgetInfo.java
+++ b/core/java/android/gadget/GadgetProviderInfo.java
@@ -21,60 +21,88 @@ import android.os.Parcelable;
import android.content.ComponentName;
/**
- * Describes the meta data for an installed gadget.
+ * Describes the meta data for an installed gadget provider. The fields in this class
+ * correspond to the fields in the <code>&lt;gadget-provider&gt;</code> xml tag.
*/
-public class GadgetInfo implements Parcelable {
+public class GadgetProviderInfo implements Parcelable {
/**
* Identity of this gadget component. This component should be a {@link
* android.content.BroadcastReceiver}, and it will be sent the Gadget intents
* {@link android.gadget as described in the gadget package documentation}.
+ *
+ * <p>This field corresponds to the <code>android:name</code> attribute in
+ * the <code>&lt;receiver&gt;</code> element in the AndroidManifest.xml file.
*/
public ComponentName provider;
/**
* Minimum width of the gadget, in dp.
+ *
+ * <p>This field corresponds to the <code>android:minWidth</code> attribute in
+ * the gadget meta-data file.
*/
public int minWidth;
/**
* Minimum height of the gadget, in dp.
+ *
+ * <p>This field corresponds to the <code>android:minHeight</code> attribute in
+ * the gadget meta-data file.
*/
public int minHeight;
/**
* How often, in milliseconds, that this gadget wants to be updated.
* The gadget manager may place a limit on how often a gadget is updated.
+ *
+ * <p>This field corresponds to the <code>android:updatePeriodMillis</code> attribute in
+ * the gadget meta-data file.
*/
public int updatePeriodMillis;
/**
* The resource id of the initial layout for this gadget. This should be
* displayed until the RemoteViews for the gadget is available.
+ *
+ * <p>This field corresponds to the <code>android:initialLayout</code> attribute in
+ * the gadget meta-data file.
*/
public int initialLayout;
/**
* The activity to launch that will configure the gadget.
+ *
+ * <p>This class name of field corresponds to the <code>android:configure</code> attribute in
+ * the gadget meta-data file. The package name always corresponds to the package containing
+ * the gadget provider.
*/
public ComponentName configure;
/**
- * The label to display to the user.
+ * The label to display to the user in the gadget picker. If not supplied in the
+ * xml, the application label will be used.
+ *
+ * <p>This field corresponds to the <code>android:label</code> attribute in
+ * the <code>&lt;receiver&gt;</code> element in the AndroidManifest.xml file.
*/
public String label;
/**
- * The icon to display for this gadget in the picker list.
+ * The icon to display for this gadget in the gadget picker. If not supplied in the
+ * xml, the application icon will be used.
+ *
+ * <p>This field corresponds to the <code>android:icon</code> attribute in
+ * the <code>&lt;receiver&gt;</code> element in the AndroidManifest.xml file.
*/
public int icon;
- public GadgetInfo() {
+ public GadgetProviderInfo() {
}
/**
- * Unflatten the GadgetInfo from a parcel.
+ * Unflatten the GadgetProviderInfo from a parcel.
*/
- public GadgetInfo(Parcel in) {
+ public GadgetProviderInfo(Parcel in) {
if (0 != in.readInt()) {
this.provider = new ComponentName(in);
}
@@ -116,24 +144,24 @@ public class GadgetInfo implements Parcelable {
}
/**
- * Parcelable.Creator that instantiates GadgetInfo objects
+ * Parcelable.Creator that instantiates GadgetProviderInfo objects
*/
- public static final Parcelable.Creator<GadgetInfo> CREATOR
- = new Parcelable.Creator<GadgetInfo>()
+ public static final Parcelable.Creator<GadgetProviderInfo> CREATOR
+ = new Parcelable.Creator<GadgetProviderInfo>()
{
- public GadgetInfo createFromParcel(Parcel parcel)
+ public GadgetProviderInfo createFromParcel(Parcel parcel)
{
- return new GadgetInfo(parcel);
+ return new GadgetProviderInfo(parcel);
}
- public GadgetInfo[] newArray(int size)
+ public GadgetProviderInfo[] newArray(int size)
{
- return new GadgetInfo[size];
+ return new GadgetProviderInfo[size];
}
};
public String toString() {
- return "GadgetInfo(provider=" + this.provider + ")";
+ return "GadgetProviderInfo(provider=" + this.provider + ")";
}
}
diff --git a/core/java/android/gadget/package.html b/core/java/android/gadget/package.html
index 4b8b9d9..4c04396 100644
--- a/core/java/android/gadget/package.html
+++ b/core/java/android/gadget/package.html
@@ -1,41 +1,126 @@
<body>
-{@hide}
<p>Android allows applications to publish views to be embedded in other applications. These
views are called gadgets, and are published by "gadget providers." The component that can
-contain gadgets is called a "gadget host." See the links below for more information.
+contain gadgets is called a "gadget host."
</p>
-<h3><a href="{@toroot}reference/android/gadget/package-descr.html#providers">Gadget Providers</a></h3>
+<h3><a href="package-descr.html#providers">Gadget Providers</a></h3>
<ul>
- <li><a href="{@toroot}reference/android/gadget/package-descr.html#provider_manifest">Declaring a gadget in the AndroidManifest</a></li>
- <li><a href="{@toroot}reference/android/gadget/package-descr.html#provider_meta_data">Adding the {@link android.gadget.GadgetInfo GadgetInfo} meta-data</a></li>
- <li><a href="{@toroot}reference/android/gadget/package-descr.html#provider_GadgetProvider">Using the {@link android.gadget.GadgetProvider GadgetProvider} class</a></li>
- <li><a href="{@toroot}reference/android/gadget/package-descr.html#provider_configuration">Gadget Configuration UI</a></li>
- <li><a href="{@toroot}reference/android/gadget/package-descr.html#provider_broadcasts">Gadget Broadcast Intents</a></li>
-</ul>
-<h3><a href="{@toroot}reference/android/gadget/package-descr.html#">Gadget Hosts</a></h3>
-<ul>
- <li><a href="{@toroot}reference/android/gadget/package-descr.html#">asdf</a></li>
+ <li><a href="package-descr.html#provider_manifest">Declaring a gadget in the AndroidManifest</a></li>
+ <li><a href="package-descr.html#provider_meta_data">Adding the GadgetProviderInfo meta-data</a></li>
+ <li><a href="package-descr.html#provider_GadgetProvider">Using the GadgetProvider class</a></li>
+ <li><a href="package-descr.html#provider_configuration">Gadget Configuration UI</a></li>
+ <li><a href="package-descr.html#provider_broadcasts">Gadget Broadcast Intents</a></li>
</ul>
+<h3><a href="package-descr.html#">Gadget Hosts</a></h3>
+
+
{@more}
+
+
<h2><a name="providers"></a>Gadget Providers</h2>
-<p>Any application can publish gadgets. All an application needs to do to publish a gadget is
+<p>
+Any application can publish gadgets. All an application needs to do to publish a gadget is
to have a {@link android.content.BroadcastReceiver} that receives the {@link
-android.gadget.GadgetManager#GADGET_UPDATE_ACTION GadgetManager.GADGET_UPDATE_ACTION} intent,
-and provide some meta-data about the gadget.
+android.gadget.GadgetManager#ACTION_GADGET_UPDATE GadgetManager.ACTION_GADGET_UPDATE} intent,
+and provide some meta-data about the gadget. Android provides the
+{@link android.gadget.GadgetProvider} class, which extends BroadcastReceiver, as a convenience
+class to aid in handling the broadcasts.
<h3><a name="provider_manifest"></a>Declaring a gadget in the AndroidManifest</h3>
-<h3><a name="provider_meta_data"></a>Adding the {@link android.gadget.GadgetInfo GadgetInfo} meta-data</h3>
+<p>
+First, declare the {@link android.content.BroadcastReceiver} in your application's
+<code>AndroidManifest.xml</code> file.
+
+{@sample frameworks/base/tests/gadgets/GadgetHostTest/AndroidManifest.xml GadgetProvider}
+
+<p>
+The <b><code>&lt;receiver&gt;</b> element has the following attributes:
+<ul>
+ <li><b><code>android:name</code> -</b> which specifies the
+ {@link android.content.BroadcastReceiver} or {@link android.gadget.GadgetProvider}
+ class.</li>
+ <li><b><code>android:label</code> -</b> which specifies the string resource that
+ will be shown by the gadget picker as the label.</li>
+ <li><b><code>android:icon</code> -</b> which specifies the drawable resource that
+ will be shown by the gadget picker as the icon.</li>
+</ul>
+
+<p>
+The <b><code>&lt;intent-filter&gt;</b> element tells the {@link android.content.pm.PackageManager}
+that this {@link android.content.BroadcastReceiver} receives the {@link
+android.gadget.GadgetManager#ACTION_GADGET_UPDATE GadgetManager.ACTION_GADGET_UPDATE} broadcast.
+The gadget manager will send other broadcasts directly to your gadget provider as required.
+It is only necessary to explicitly declare that you accept the {@link
+android.gadget.GadgetManager#ACTION_GADGET_UPDATE GadgetManager.ACTION_GADGET_UPDATE} broadcast.
+
+<p>
+The <b><code>&lt;meta-data&gt;</code></b> element tells the gadget manager which xml resource to
+read to find the {@link android.gadget.GadgetProviderInfo} for your gadget provider. It has the following
+attributes:
+<ul>
+ <li><b><code>android:name="android.gadget.provider"</code> -</b> identifies this meta-data
+ as the {@link android.gadget.GadgetProviderInfo} descriptor.</li>
+ <li><b><code>android:resource</code> -</b> is the xml resource to use as that descriptor.</li>
+</ul>
+
+
+<h3><a name="provider_meta_data"></a>Adding the {@link android.gadget.GadgetProviderInfo GadgetProviderInfo} meta-data</h3>
+
+<p>
+For a gadget, the values in the {@link android.gadget.GadgetProviderInfo} structure are supplied
+in an XML resource. In the example above, the xml resource is referenced with
+<code>android:resource="@xml/gadget_info"</code>. That XML file would go in your application's
+directory at <code>res/xml/gadget_info.xml</code>. Here is a simple example.
+
+{@sample frameworks/base/tests/gadgets/GadgetHostTest/res/xml/gadget_info.xml GadgetProviderInfo}
+
+<p>
+The attributes are as documented in the {@link android.gadget.GadgetProviderInfo GagetInfo} class. (86400000 milliseconds means once per day)
+
<h3><a name="provider_GadgetProvider"></a>Using the {@link android.gadget.GadgetProvider GadgetProvider} class</h3>
+<p>The GadgetProvider class is the easiest way to handle the gadget provider intent broadcasts.
+See the <code>src/com/example/android/apis/gadget/ExampleGadgetProvider.java</code>
+sample class in ApiDemos for an example.
+
+<p class="note">Keep in mind that since the the GadgetProvider is a BroadcastReceiver,
+your process is not guaranteed to keep running after the callback methods return. See
+<a href="../../../guide/topics/fundamentals.html#broadlife">Application Fundamentals &gt;
+Broadcast Receiver Lifecycle</a> for more information.
+
+
+
<h3><a name="provider_configuration"></a>Gadget Configuration UI</h3>
+<p>
+Gadget hosts have the ability to start a configuration activity when a gadget is instantiated.
+The activity should be declared as normal in AndroidManifest.xml, and it should be listed in
+the GadgetProviderInfo XML file in the <code>android:configure</code> attribute.
+
+<p>The activity you specified will be launched with the {@link
+android.gadget.GadgetManager#ACTION_GADGET_CONFIGURE} action. See the documentation for that
+action for more info.
+
+<p>See the <code>src/com/example/android/apis/gadget/ExampleGadgetConfigure.java</code>
+sample class in ApiDemos for an example.
+
+
+
<h3><a name="providers_broadcasts"></a>Gadget Broadcast Intents</h3>
-<p>{@link GadgetProvider} is just a convenience class. If you would like to receive the
-gadget broadcasts directly, you can. By way of example, the implementation of
-{@link GadgetProvider.onReceive} is quite simple:</p>
+<p>{@link android.gadget.GadgetProvider} is just a convenience class. If you would like
+to receive the gadget broadcasts directly, you can. The four intents you need to care about are:
+<ul>
+ <li>{@link android.gadget.GadgetManager#ACTION_GADGET_UPDATE}</li>
+ <li>{@link android.gadget.GadgetManager#ACTION_GADGET_DELETED}</li>
+ <li>{@link android.gadget.GadgetManager#ACTION_GADGET_ENABLED}</li>
+ <li>{@link android.gadget.GadgetManager#ACTION_GADGET_DISABLED}</li>
+</ul>
+
+<p>By way of example, the implementation of
+{@link android.gadget.GadgetProvider#onReceive} is quite simple:</p>
{@sample frameworks/base/core/java/android/gadget/GadgetProvider.java onReceive}
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index c09567c..40a5b47 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -18,6 +18,7 @@ package android.hardware;
import java.lang.ref.WeakReference;
import java.util.HashMap;
+import java.util.StringTokenizer;
import java.io.IOException;
import android.util.Log;
@@ -494,11 +495,17 @@ public class Camera {
*/
public void unflatten(String flattened) {
mMap.clear();
- String[] pairs = flattened.split(";");
- for (String p : pairs) {
- String[] kv = p.split("=");
- if (kv.length == 2)
- mMap.put(kv[0], kv[1]);
+
+ StringTokenizer tokenizer = new StringTokenizer(flattened, ";");
+ while (tokenizer.hasMoreElements()) {
+ String kv = tokenizer.nextToken();
+ int pos = kv.indexOf('=');
+ if (pos == -1) {
+ continue;
+ }
+ String k = kv.substring(0, pos);
+ String v = kv.substring(pos + 1);
+ mMap.put(k, v);
}
}
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index ea5f741..c884120 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -206,6 +206,8 @@ public class InputMethodService extends AbstractInputMethodService {
static final String TAG = "InputMethodService";
static final boolean DEBUG = false;
+ InputMethodManager mImm;
+
LayoutInflater mInflater;
View mRootView;
SoftInputWindow mWindow;
@@ -293,6 +295,8 @@ public class InputMethodService extends AbstractInputMethodService {
mInputConnection = binding.getConnection();
if (DEBUG) Log.v(TAG, "bindInput(): binding=" + binding
+ " ic=" + mInputConnection);
+ InputConnection ic = getCurrentInputConnection();
+ if (ic != null) ic.reportFullscreenMode(mIsFullscreen);
initialize();
onBindInput();
}
@@ -423,7 +427,7 @@ public class InputMethodService extends AbstractInputMethodService {
* of the application behind. This value is relative to the top edge
* of the input method window.
*/
- int contentTopInsets;
+ public int contentTopInsets;
/**
* This is the top part of the UI that is visibly covering the
@@ -436,7 +440,7 @@ public class InputMethodService extends AbstractInputMethodService {
* needed to make the focus visible. This value is relative to the top edge
* of the input method window.
*/
- int visibleTopInsets;
+ public int visibleTopInsets;
/**
* Option for {@link #touchableInsets}: the entire window frame
@@ -469,6 +473,7 @@ public class InputMethodService extends AbstractInputMethodService {
@Override public void onCreate() {
super.onCreate();
+ mImm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
mInflater = (LayoutInflater)getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
mWindow = new SoftInputWindow(this);
@@ -554,7 +559,6 @@ public class InputMethodService extends AbstractInputMethodService {
boolean visible = mWindowVisible;
boolean showingInput = mShowInputRequested;
boolean showingForced = mShowInputForced;
- boolean showingCandidates = mCandidatesVisibility == View.VISIBLE;
initViews();
mInputViewStarted = false;
mCandidatesViewStarted = false;
@@ -577,9 +581,6 @@ public class InputMethodService extends AbstractInputMethodService {
// Otherwise just put it back for its candidates.
showWindow(false);
}
- if (showingCandidates) {
- setCandidatesViewShown(true);
- }
}
}
@@ -670,6 +671,8 @@ public class InputMethodService extends AbstractInputMethodService {
if (mIsFullscreen != isFullscreen || !mFullscreenApplied) {
changed = true;
mIsFullscreen = isFullscreen;
+ InputConnection ic = getCurrentInputConnection();
+ if (ic != null) ic.reportFullscreenMode(isFullscreen);
mFullscreenApplied = true;
initialize();
Drawable bg = onCreateBackgroundDrawable();
@@ -860,12 +863,14 @@ public class InputMethodService extends AbstractInputMethodService {
return isFullscreenMode() ? View.GONE : View.INVISIBLE;
}
- public void setStatusIcon(int iconResId) {
+ public void showStatusIcon(int iconResId) {
mStatusIcon = iconResId;
- InputConnection ic = getCurrentInputConnection();
- if (ic != null && mWindowVisible) {
- ic.showStatusIcon(getPackageName(), iconResId);
- }
+ mImm.showStatusIcon(mToken, getPackageName(), iconResId);
+ }
+
+ public void hideStatusIcon() {
+ mStatusIcon = 0;
+ mImm.hideStatusIcon(mToken);
}
/**
@@ -876,8 +881,7 @@ public class InputMethodService extends AbstractInputMethodService {
* @param id Unique identifier of the new input method ot start.
*/
public void switchInputMethod(String id) {
- ((InputMethodManager)getSystemService(INPUT_METHOD_SERVICE))
- .setInputMethod(mToken, id);
+ mImm.setInputMethod(mToken, id);
}
public void setExtractView(View view) {
@@ -1149,15 +1153,9 @@ public class InputMethodService extends AbstractInputMethodService {
if (!wasVisible) {
if (DEBUG) Log.v(TAG, "showWindow: showing!");
+ onWindowShown();
mWindow.show();
}
-
- if (!wasVisible || !wasCreated) {
- InputConnection ic = getCurrentInputConnection();
- if (ic != null) {
- ic.showStatusIcon(getPackageName(), mStatusIcon);
- }
- }
}
public void hideWindow() {
@@ -1173,14 +1171,26 @@ public class InputMethodService extends AbstractInputMethodService {
if (mWindowVisible) {
mWindow.hide();
mWindowVisible = false;
- InputConnection ic = getCurrentInputConnection();
- if (ic != null) {
- ic.hideStatusIcon();
- }
+ onWindowHidden();
}
}
/**
+ * Called when the input method window has been shown to the user, after
+ * previously not being visible. This is done after all of the UI setup
+ * for the window has occurred (creating its views etc).
+ */
+ public void onWindowShown() {
+ }
+
+ /**
+ * Called when the input method window has been hidden from the user,
+ * after previously being visible.
+ */
+ public void onWindowHidden() {
+ }
+
+ /**
* Called when a new client has bound to the input method. This
* may be followed by a series of {@link #onStartInput(EditorInfo, boolean)}
* and {@link #onFinishInput()} calls as the user navigates through its
@@ -1341,8 +1351,7 @@ public class InputMethodService extends AbstractInputMethodService {
* InputMethodManager.HIDE_IMPLICIT_ONLY} bit set.
*/
public void dismissSoftInput(int flags) {
- ((InputMethodManager)getSystemService(INPUT_METHOD_SERVICE))
- .hideSoftInputFromInputMethod(mToken, flags);
+ mImm.hideSoftInputFromInputMethod(mToken, flags);
}
/**
@@ -1447,17 +1456,19 @@ public class InputMethodService extends AbstractInputMethodService {
return true;
}
} else {
- KeyEvent down = new KeyEvent(event, KeyEvent.ACTION_DOWN);
- if (movement.onKeyDown(eet,
- (Spannable)eet.getText(), keyCode, down)) {
- KeyEvent up = new KeyEvent(event, KeyEvent.ACTION_UP);
- movement.onKeyUp(eet,
- (Spannable)eet.getText(), keyCode, up);
- while (--count > 0) {
- movement.onKeyDown(eet,
- (Spannable)eet.getText(), keyCode, down);
+ if (!movement.onKeyOther(eet, (Spannable)eet.getText(), event)) {
+ KeyEvent down = new KeyEvent(event, KeyEvent.ACTION_DOWN);
+ if (movement.onKeyDown(eet,
+ (Spannable)eet.getText(), keyCode, down)) {
+ KeyEvent up = new KeyEvent(event, KeyEvent.ACTION_UP);
movement.onKeyUp(eet,
(Spannable)eet.getText(), keyCode, up);
+ while (--count > 0) {
+ movement.onKeyDown(eet,
+ (Spannable)eet.getText(), keyCode, down);
+ movement.onKeyUp(eet,
+ (Spannable)eet.getText(), keyCode, up);
+ }
}
}
}
@@ -1593,5 +1604,9 @@ public class InputMethodService extends AbstractInputMethodService {
p.println(" mExtractedToken=" + mExtractedToken);
p.println(" mIsInputViewShown=" + mIsInputViewShown
+ " mStatusIcon=" + mStatusIcon);
+ p.println("Last computed insets:");
+ p.println(" contentTopInsets=" + mTmpInsets.contentTopInsets
+ + " visibleTopInsets=" + mTmpInsets.visibleTopInsets
+ + " touchableInsets=" + mTmpInsets.touchableInsets);
}
}
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index b2c74f2..b8bd10d 100755
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -1084,6 +1084,10 @@ public class KeyboardView extends View implements View.OnClickListener {
if (mPreviewPopup.isShowing()) {
mPreviewPopup.dismiss();
}
+ mHandler.removeMessages(MSG_REPEAT);
+ mHandler.removeMessages(MSG_LONGPRESS);
+ mHandler.removeMessages(MSG_SHOW_PREVIEW);
+
dismissPopupKeyboard();
}
diff --git a/core/java/android/net/UrlQuerySanitizer.java b/core/java/android/net/UrlQuerySanitizer.java
index 70e50b7..a6efcdd 100644
--- a/core/java/android/net/UrlQuerySanitizer.java
+++ b/core/java/android/net/UrlQuerySanitizer.java
@@ -23,7 +23,7 @@ import java.util.Set;
import java.util.StringTokenizer;
/**
- *
+ *
* Sanitizes the Query portion of a URL. Simple example:
* <code>
* UrlQuerySanitizer sanitizer = new UrlQuerySanitizer();
@@ -32,7 +32,7 @@ import java.util.StringTokenizer;
* String name = sanitizer.getValue("name"));
* // name now contains "Joe_User"
* </code>
- *
+ *
* Register ValueSanitizers to customize the way individual
* parameters are sanitized:
* <code>
@@ -46,7 +46,7 @@ import java.util.StringTokenizer;
* unregistered parameter sanitizer does not allow any special characters,
* and ' ' is a special character.)
* </code>
- *
+ *
* There are several ways to create ValueSanitizers. In order of increasing
* sophistication:
* <ol>
@@ -56,7 +56,7 @@ import java.util.StringTokenizer;
* <li>Subclass UrlQuerySanitizer.ValueSanitizer to define your own value
* sanitizer.
* </ol>
- *
+ *
*/
public class UrlQuerySanitizer {
@@ -84,7 +84,7 @@ public class UrlQuerySanitizer {
*/
public String mValue;
}
-
+
final private HashMap<String, ValueSanitizer> mSanitizers =
new HashMap<String, ValueSanitizer>();
final private HashMap<String, String> mEntries =
@@ -95,9 +95,9 @@ public class UrlQuerySanitizer {
private boolean mPreferFirstRepeatedParameter;
private ValueSanitizer mUnregisteredParameterValueSanitizer =
getAllIllegal();
-
+
/**
- * A functor used to sanitize a single query value.
+ * A functor used to sanitize a single query value.
*
*/
public static interface ValueSanitizer {
@@ -108,7 +108,7 @@ public class UrlQuerySanitizer {
*/
public String sanitize(String value);
}
-
+
/**
* Sanitize values based on which characters they contain. Illegal
* characters are replaced with either space or '_', depending upon
@@ -117,7 +117,7 @@ public class UrlQuerySanitizer {
public static class IllegalCharacterValueSanitizer implements
ValueSanitizer {
private int mFlags;
-
+
/**
* Allow space (' ') characters.
*/
@@ -165,21 +165,21 @@ public class UrlQuerySanitizer {
* such as "javascript:" or "vbscript:"
*/
public final static int SCRIPT_URL_OK = 1 << 10;
-
+
/**
* Mask with all fields set to OK
*/
public final static int ALL_OK = 0x7ff;
-
+
/**
* Mask with both regular space and other whitespace OK
*/
public final static int ALL_WHITESPACE_OK =
SPACE_OK | OTHER_WHITESPACE_OK;
-
+
// Common flag combinations:
-
+
/**
* <ul>
* <li>Deny all special characters.
@@ -262,18 +262,18 @@ public class UrlQuerySanitizer {
*/
public final static int ALL_BUT_NUL_AND_ANGLE_BRACKETS_LEGAL =
ALL_OK & ~(NUL_OK | LT_OK | GT_OK);
-
+
/**
* Script URL definitions
*/
-
+
private final static String JAVASCRIPT_PREFIX = "javascript:";
-
+
private final static String VBSCRIPT_PREFIX = "vbscript:";
-
+
private final static int MIN_SCRIPT_PREFIX_LENGTH = Math.min(
JAVASCRIPT_PREFIX.length(), VBSCRIPT_PREFIX.length());
-
+
/**
* Construct a sanitizer. The parameters set the behavior of the
* sanitizer.
@@ -312,7 +312,7 @@ public class UrlQuerySanitizer {
}
}
}
-
+
// If whitespace isn't OK, get rid of whitespace at beginning
// and end of value.
if ( (mFlags & ALL_WHITESPACE_OK) == 0) {
@@ -337,7 +337,7 @@ public class UrlQuerySanitizer {
}
return stringBuilder.toString();
}
-
+
/**
* Trim whitespace from the beginning and end of a string.
* <p>
@@ -361,7 +361,7 @@ public class UrlQuerySanitizer {
}
return value.substring(start, end + 1);
}
-
+
/**
* Check if c is whitespace.
* @param c character to test
@@ -380,7 +380,7 @@ public class UrlQuerySanitizer {
return false;
}
}
-
+
/**
* Check whether an individual character is legal. Uses the
* flag bit-set passed into the constructor.
@@ -400,11 +400,11 @@ public class UrlQuerySanitizer {
case '%' : return (mFlags & PCT_OK) != 0;
case '\0': return (mFlags & NUL_OK) != 0;
default : return (c >= 32 && c < 127) ||
- (c >= 128 && c <= 255 && ((mFlags & NON_7_BIT_ASCII_OK) != 0));
- }
+ ((c >= 128) && ((mFlags & NON_7_BIT_ASCII_OK) != 0));
+ }
}
}
-
+
/**
* Get the current value sanitizer used when processing
* unregistered parameter values.
@@ -412,14 +412,14 @@ public class UrlQuerySanitizer {
* <b>Note:</b> The default unregistered parameter value sanitizer is
* one that doesn't allow any special characters, similar to what
* is returned by calling createAllIllegal.
- *
+ *
* @return the current ValueSanitizer used to sanitize unregistered
* parameter values.
*/
public ValueSanitizer getUnregisteredParameterValueSanitizer() {
return mUnregisteredParameterValueSanitizer;
}
-
+
/**
* Set the value sanitizer used when processing unregistered
* parameter values.
@@ -430,46 +430,46 @@ public class UrlQuerySanitizer {
ValueSanitizer sanitizer) {
mUnregisteredParameterValueSanitizer = sanitizer;
}
-
-
+
+
// Private fields for singleton sanitizers:
-
+
private static final ValueSanitizer sAllIllegal =
new IllegalCharacterValueSanitizer(
IllegalCharacterValueSanitizer.ALL_ILLEGAL);
-
+
private static final ValueSanitizer sAllButNulLegal =
new IllegalCharacterValueSanitizer(
IllegalCharacterValueSanitizer.ALL_BUT_NUL_LEGAL);
-
+
private static final ValueSanitizer sAllButWhitespaceLegal =
new IllegalCharacterValueSanitizer(
IllegalCharacterValueSanitizer.ALL_BUT_WHITESPACE_LEGAL);
-
+
private static final ValueSanitizer sURLLegal =
new IllegalCharacterValueSanitizer(
IllegalCharacterValueSanitizer.URL_LEGAL);
-
+
private static final ValueSanitizer sUrlAndSpaceLegal =
new IllegalCharacterValueSanitizer(
IllegalCharacterValueSanitizer.URL_AND_SPACE_LEGAL);
-
+
private static final ValueSanitizer sAmpLegal =
new IllegalCharacterValueSanitizer(
- IllegalCharacterValueSanitizer.AMP_LEGAL);
-
+ IllegalCharacterValueSanitizer.AMP_LEGAL);
+
private static final ValueSanitizer sAmpAndSpaceLegal =
new IllegalCharacterValueSanitizer(
IllegalCharacterValueSanitizer.AMP_AND_SPACE_LEGAL);
-
+
private static final ValueSanitizer sSpaceLegal =
new IllegalCharacterValueSanitizer(
IllegalCharacterValueSanitizer.SPACE_LEGAL);
-
+
private static final ValueSanitizer sAllButNulAndAngleBracketsLegal =
new IllegalCharacterValueSanitizer(
IllegalCharacterValueSanitizer.ALL_BUT_NUL_AND_ANGLE_BRACKETS_LEGAL);
-
+
/**
* Return a value sanitizer that does not allow any special characters,
* and also does not allow script URLs.
@@ -478,7 +478,7 @@ public class UrlQuerySanitizer {
public static final ValueSanitizer getAllIllegal() {
return sAllIllegal;
}
-
+
/**
* Return a value sanitizer that allows everything except Nul ('\0')
* characters. Script URLs are allowed.
@@ -547,7 +547,7 @@ public class UrlQuerySanitizer {
public static final ValueSanitizer getAllButNulAndAngleBracketsLegal() {
return sAllButNulAndAngleBracketsLegal;
}
-
+
/**
* Constructs a UrlQuerySanitizer.
* <p>
@@ -560,7 +560,7 @@ public class UrlQuerySanitizer {
*/
public UrlQuerySanitizer() {
}
-
+
/**
* Constructs a UrlQuerySanitizer and parse a URL.
* This constructor is provided for convenience when the
@@ -585,7 +585,7 @@ public class UrlQuerySanitizer {
setAllowUnregisteredParamaters(true);
parseUrl(url);
}
-
+
/**
* Parse the query parameters out of an encoded URL.
* Works by extracting the query portion from the URL and then
@@ -604,7 +604,7 @@ public class UrlQuerySanitizer {
}
parseQuery(query);
}
-
+
/**
* Parse a query. A query string is any number of parameter-value clauses
* separated by any non-zero number of ampersands. A parameter-value clause
@@ -631,7 +631,7 @@ public class UrlQuerySanitizer {
}
}
}
-
+
/**
* Get a set of all of the parameters found in the sanitized query.
* <p>
@@ -641,7 +641,7 @@ public class UrlQuerySanitizer {
public Set<String> getParameterSet() {
return mEntries.keySet();
}
-
+
/**
* An array list of all of the parameter value pairs in the sanitized
* query, in the order they appeared in the query. May contain duplicate
@@ -691,7 +691,7 @@ public class UrlQuerySanitizer {
}
mSanitizers.put(parameter, valueSanitizer);
}
-
+
/**
* Register a value sanitizer for an array of parameters.
* @param parameters An array of unencoded parameter names.
@@ -705,7 +705,7 @@ public class UrlQuerySanitizer {
mSanitizers.put(parameters[i], valueSanitizer);
}
}
-
+
/**
* Set whether or not unregistered parameters are allowed. If they
* are not allowed, then they will be dropped when a query is sanitized.
@@ -718,7 +718,7 @@ public class UrlQuerySanitizer {
boolean allowUnregisteredParamaters) {
mAllowUnregisteredParamaters = allowUnregisteredParamaters;
}
-
+
/**
* Get whether or not unregistered parameters are allowed. If not
* allowed, they will be dropped when a query is parsed.
@@ -728,10 +728,10 @@ public class UrlQuerySanitizer {
public boolean getAllowUnregisteredParamaters() {
return mAllowUnregisteredParamaters;
}
-
+
/**
* Set whether or not the first occurrence of a repeated parameter is
- * preferred. True means the first repeated parameter is preferred.
+ * preferred. True means the first repeated parameter is preferred.
* False means that the last repeated parameter is preferred.
* <p>
* The preferred parameter is the one that is returned when getParameter
@@ -746,7 +746,7 @@ public class UrlQuerySanitizer {
boolean preferFirstRepeatedParameter) {
mPreferFirstRepeatedParameter = preferFirstRepeatedParameter;
}
-
+
/**
* Get whether or not the first occurrence of a repeated parameter is
* preferred.
@@ -757,10 +757,10 @@ public class UrlQuerySanitizer {
public boolean getPreferFirstRepeatedParameter() {
return mPreferFirstRepeatedParameter;
}
-
+
/**
* Parse an escaped parameter-value pair. The default implementation
- * unescapes both the parameter and the value, then looks up the
+ * unescapes both the parameter and the value, then looks up the
* effective value sanitizer for the parameter and uses it to sanitize
* the value. If all goes well then addSanitizedValue is called with
* the unescaped parameter and the sanitized unescaped value.
@@ -779,7 +779,7 @@ public class UrlQuerySanitizer {
String sanitizedValue = valueSanitizer.sanitize(unescapedValue);
addSanitizedEntry(unescapedParameter, sanitizedValue);
}
-
+
/**
* Record a sanitized parameter-value pair. Override if you want to
* do additional filtering or validation.
@@ -796,7 +796,7 @@ public class UrlQuerySanitizer {
}
mEntries.put(parameter, value);
}
-
+
/**
* Get the value sanitizer for a parameter. Returns null if there
* is no value sanitizer registered for the parameter.
@@ -807,7 +807,7 @@ public class UrlQuerySanitizer {
public ValueSanitizer getValueSanitizer(String parameter) {
return mSanitizers.get(parameter);
}
-
+
/**
* Get the effective value sanitizer for a parameter. Like getValueSanitizer,
* except if there is no value sanitizer registered for a parameter, and
@@ -823,7 +823,7 @@ public class UrlQuerySanitizer {
}
return sanitizer;
}
-
+
/**
* Unescape an escaped string.
* <ul>
@@ -867,7 +867,7 @@ public class UrlQuerySanitizer {
}
return stringBuilder.toString();
}
-
+
/**
* Test if a character is a hexidecimal digit. Both upper case and lower
* case hex digits are allowed.
@@ -877,7 +877,7 @@ public class UrlQuerySanitizer {
protected boolean isHexDigit(char c) {
return decodeHexDigit(c) >= 0;
}
-
+
/**
* Convert a character that represents a hexidecimal digit into an integer.
* If the character is not a hexidecimal digit, then -1 is returned.
@@ -885,7 +885,7 @@ public class UrlQuerySanitizer {
* @param c the hexidecimal digit.
* @return the integer value of the hexidecimal digit.
*/
-
+
protected int decodeHexDigit(char c) {
if (c >= '0' && c <= '9') {
return c - '0';
@@ -900,7 +900,7 @@ public class UrlQuerySanitizer {
return -1;
}
}
-
+
/**
* Clear the existing entries. Called to get ready to parse a new
* query string.
diff --git a/core/java/android/pim/RecurrenceSet.java b/core/java/android/pim/RecurrenceSet.java
index c6615da..1a287c8 100644
--- a/core/java/android/pim/RecurrenceSet.java
+++ b/core/java/android/pim/RecurrenceSet.java
@@ -140,7 +140,6 @@ public class RecurrenceSet {
recurrence = recurrence.substring(tzidx + 1);
}
Time time = new Time(tz);
- boolean rdateNotInUtc = !tz.equals(Time.TIMEZONE_UTC);
String[] rawDates = recurrence.split(",");
int n = rawDates.length;
long[] dates = new long[n];
diff --git a/core/java/android/preference/PreferenceGroupAdapter.java b/core/java/android/preference/PreferenceGroupAdapter.java
index 05c2952..02ab1da 100644
--- a/core/java/android/preference/PreferenceGroupAdapter.java
+++ b/core/java/android/preference/PreferenceGroupAdapter.java
@@ -88,6 +88,9 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn
public PreferenceGroupAdapter(PreferenceGroup preferenceGroup) {
mPreferenceGroup = preferenceGroup;
+ // If this group gets or loses any children, let us know
+ mPreferenceGroup.setOnPreferenceChangeInternalListener(this);
+
mPreferenceList = new ArrayList<Preference>();
mPreferenceClassNames = new ArrayList<String>();
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 054da1d..c6a7b40 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -879,15 +879,6 @@ public final class Settings {
public static final String AIRPLANE_MODE_RADIOS = "airplane_mode_radios";
/**
- * The interval in milliseconds after which Wi-Fi is considered idle.
- * When idle, it is possible for the device to be switched from Wi-Fi to
- * the mobile data network.
- *
- * @hide pending API Council approval
- */
- public static final String WIFI_IDLE_MS = "wifi_idle_ms";
-
- /**
* The policy for deciding when Wi-Fi should go to sleep (which will in
* turn switch to using the mobile data as an Internet connection).
* <p>
@@ -1288,6 +1279,12 @@ public final class Settings {
*/
public static final String SOUND_EFFECTS_ENABLED = "sound_effects_enabled";
+ /**
+ * Whether the haptic feedback (long presses, ...) are enabled. The value is
+ * boolean (1 or 0).
+ */
+ public static final String HAPTIC_FEEDBACK_ENABLED = "haptic_feedback_enabled";
+
// Settings moved to Settings.Secure
/**
@@ -2732,6 +2729,13 @@ public final class Settings {
"gprs_register_check_period_ms";
/**
+ * The interval in milliseconds after which Wi-Fi is considered idle.
+ * When idle, it is possible for the device to be switched from Wi-Fi to
+ * the mobile data network.
+ */
+ public static final String WIFI_IDLE_MS = "wifi_idle_ms";
+
+ /**
* Screen timeout in milliseconds corresponding to the
* PowerManager's POKE_LOCK_SHORT_TIMEOUT flag (i.e. the fastest
* possible screen timeout behavior.)
diff --git a/core/java/android/server/BluetoothDeviceService.java b/core/java/android/server/BluetoothDeviceService.java
index d149761..7c15045 100644
--- a/core/java/android/server/BluetoothDeviceService.java
+++ b/core/java/android/server/BluetoothDeviceService.java
@@ -25,8 +25,8 @@
package android.server;
import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothHeadset; // just for dump()
import android.bluetooth.BluetoothError;
+import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothIntent;
import android.bluetooth.IBluetoothDevice;
import android.bluetooth.IBluetoothDeviceCallback;
@@ -35,23 +35,20 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.os.RemoteException;
-import android.provider.Settings;
-import android.util.Log;
import android.os.Binder;
import android.os.Handler;
import android.os.Message;
+import android.os.RemoteException;
import android.os.SystemService;
+import android.provider.Settings;
+import android.util.Log;
-import java.io.IOException;
import java.io.FileDescriptor;
-import java.io.FileNotFoundException;
-import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
public class BluetoothDeviceService extends IBluetoothDevice.Stub {
@@ -119,7 +116,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
public synchronized boolean disable() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH_ADMIN permission");
-
+
if (mEnableThread != null && mEnableThread.isAlive()) {
return false;
}
@@ -229,9 +226,9 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
long origCallerIdentityToken = Binder.clearCallingIdentity();
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.BLUETOOTH_ON,
bluetoothOn ? 1 : 0);
- Binder.restoreCallingIdentity(origCallerIdentityToken);
+ Binder.restoreCallingIdentity(origCallerIdentityToken);
}
-
+
private native int enableNative();
private native int disableNative();
@@ -247,6 +244,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
public class BondState {
private final HashMap<String, Integer> mState = new HashMap<String, Integer>();
private final HashMap<String, Integer> mPinAttempt = new HashMap<String, Integer>();
+ private final ArrayList<String> mAutoPairingFailures = new ArrayList<String>();
public synchronized void loadBondState() {
if (!mIsEnabled) {
@@ -281,8 +279,8 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
intent.putExtra(BluetoothIntent.BOND_PREVIOUS_STATE, oldState);
if (state == BluetoothDevice.BOND_NOT_BONDED) {
if (reason <= 0) {
- Log.w(TAG, "setBondState() called to unbond device with invalid reason code " +
- "Setting reason = BOND_RESULT_REMOVED");
+ Log.w(TAG, "setBondState() called to unbond device, but reason code is " +
+ "invalid. Overriding reason code with BOND_RESULT_REMOVED");
reason = BluetoothDevice.UNBOND_REASON_REMOVED;
}
intent.putExtra(BluetoothIntent.REASON, reason);
@@ -290,11 +288,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
} else {
mState.put(address, state);
}
- if (state == BluetoothDevice.BOND_BONDING) {
- mPinAttempt.put(address, Integer.valueOf(0));
- } else {
- mPinAttempt.remove(address);
- }
+
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
}
@@ -316,6 +310,24 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
return result.toArray(new String[result.size()]);
}
+ public synchronized void addAutoPairingFailure(String address) {
+ if (!mAutoPairingFailures.contains(address)) {
+ mAutoPairingFailures.add(address);
+ }
+ }
+
+ public synchronized boolean isAutoPairingAttemptsInProgress(String address) {
+ return getAttempt(address) != 0;
+ }
+
+ public synchronized void clearPinAttempts(String address) {
+ mPinAttempt.remove(address);
+ }
+
+ public synchronized boolean hasAutoPairingFailed(String address) {
+ return mAutoPairingFailures.contains(address);
+ }
+
public synchronized int getAttempt(String address) {
Integer attempt = mPinAttempt.get(address);
if (attempt == null) {
@@ -326,10 +338,13 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
public synchronized void attempt(String address) {
Integer attempt = mPinAttempt.get(address);
+ int newAttempt;
if (attempt == null) {
- return;
+ newAttempt = 1;
+ } else {
+ newAttempt = attempt.intValue() + 1;
}
- mPinAttempt.put(address, new Integer(attempt.intValue() + 1));
+ mPinAttempt.put(address, new Integer(newAttempt));
}
}
@@ -508,7 +523,11 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
return false;
}
address = address.toUpperCase();
- if (mBondState.getBondState(address) != BluetoothDevice.BOND_NOT_BONDED) {
+
+ // Check for bond state only if we are not performing auto
+ // pairing exponential back-off attempts.
+ if (!mBondState.isAutoPairingAttemptsInProgress(address) &&
+ mBondState.getBondState(address) != BluetoothDevice.BOND_NOT_BONDED) {
return false;
}
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 0f60fae..b5e4090 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -24,6 +24,8 @@ import android.bluetooth.BluetoothIntent;
import android.bluetooth.IBluetoothDeviceCallback;
import android.content.Context;
import android.content.Intent;
+import android.os.Handler;
+import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
@@ -48,9 +50,33 @@ class BluetoothEventLoop {
private BluetoothDeviceService mBluetoothService;
private Context mContext;
+ private static final int EVENT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 1;
+
+ // The time (in millisecs) to delay the pairing attempt after the first
+ // auto pairing attempt fails. We use an exponential delay with
+ // INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY as the initial value and
+ // MAX_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY as the max value.
+ private static final long INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 3000;
+ private static final long MAX_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 12000;
+
private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case EVENT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY:
+ String address = (String)msg.obj;
+ if (address != null) {
+ mBluetoothService.createBond(address);
+ return;
+ }
+ break;
+ }
+ }
+ };
+
static { classInitNative(); }
private static native void classInitNative();
@@ -149,16 +175,6 @@ class BluetoothEventLoop {
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
}
- private void onPairingRequest() {
- Intent intent = new Intent(BluetoothIntent.PAIRING_REQUEST_ACTION);
- mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
- }
-
- private void onPairingCancel() {
- Intent intent = new Intent(BluetoothIntent.PAIRING_CANCEL_ACTION);
- mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
- }
-
private void onRemoteDeviceFound(String address, int deviceClass, short rssi) {
Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_FOUND_ACTION);
intent.putExtra(BluetoothIntent.ADDRESS, address);
@@ -214,12 +230,55 @@ class BluetoothEventLoop {
address = address.toUpperCase();
if (result == BluetoothError.SUCCESS) {
mBluetoothService.getBondState().setBondState(address, BluetoothDevice.BOND_BONDED);
+ if (mBluetoothService.getBondState().isAutoPairingAttemptsInProgress(address)) {
+ mBluetoothService.getBondState().clearPinAttempts(address);
+ }
+ } else if (result == BluetoothDevice.UNBOND_REASON_AUTH_FAILED &&
+ mBluetoothService.getBondState().getAttempt(address) == 1) {
+ mBluetoothService.getBondState().addAutoPairingFailure(address);
+ pairingAttempt(address, result);
+ } else if (result == BluetoothDevice.UNBOND_REASON_REMOTE_DEVICE_DOWN &&
+ mBluetoothService.getBondState().isAutoPairingAttemptsInProgress(address)) {
+ pairingAttempt(address, result);
} else {
mBluetoothService.getBondState().setBondState(address,
BluetoothDevice.BOND_NOT_BONDED, result);
+ if (mBluetoothService.getBondState().isAutoPairingAttemptsInProgress(address)) {
+ mBluetoothService.getBondState().clearPinAttempts(address);
+ }
}
}
+ private void pairingAttempt(String address, int result) {
+ // This happens when our initial guess of "0000" as the pass key
+ // fails. Try to create the bond again and display the pin dialog
+ // to the user. Use back-off while posting the delayed
+ // message. The initial value is
+ // INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY and the max value is
+ // MAX_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY. If the max value is
+ // reached, display an error to the user.
+ int attempt = mBluetoothService.getBondState().getAttempt(address);
+ if (attempt * INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY >
+ MAX_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY) {
+ mBluetoothService.getBondState().clearPinAttempts(address);
+ mBluetoothService.getBondState().setBondState(address,
+ BluetoothDevice.BOND_NOT_BONDED, result);
+ return;
+ }
+
+ Message message = mHandler.obtainMessage(EVENT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY);
+ message.obj = address;
+ boolean postResult = mHandler.sendMessageDelayed(message,
+ attempt * INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY);
+ if (!postResult) {
+ mBluetoothService.getBondState().clearPinAttempts(address);
+ mBluetoothService.getBondState().setBondState(address,
+ BluetoothDevice.BOND_NOT_BONDED, result);
+ return;
+ }
+ mBluetoothService.getBondState().attempt(address);
+ }
+
private void onBondingCreated(String address) {
mBluetoothService.getBondState().setBondState(address.toUpperCase(),
BluetoothDevice.BOND_BONDED);
@@ -253,12 +312,12 @@ class BluetoothEventLoop {
case BluetoothClass.Device.AUDIO_VIDEO_PORTABLE_AUDIO:
case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
case BluetoothClass.Device.AUDIO_VIDEO_HIFI_AUDIO:
- if (mBluetoothService.getBondState().getAttempt(address) < 1) {
+ if (!mBluetoothService.getBondState().hasAutoPairingFailed(address)) {
mBluetoothService.getBondState().attempt(address);
mBluetoothService.setPin(address, BluetoothDevice.convertPinToBytes("0000"));
return;
}
- }
+ }
}
Intent intent = new Intent(BluetoothIntent.PAIRING_REQUEST_ACTION);
intent.putExtra(BluetoothIntent.ADDRESS, address);
diff --git a/core/java/android/text/method/ArrowKeyMovementMethod.java b/core/java/android/text/method/ArrowKeyMovementMethod.java
index a559b9d..6df0b35 100644
--- a/core/java/android/text/method/ArrowKeyMovementMethod.java
+++ b/core/java/android/text/method/ArrowKeyMovementMethod.java
@@ -16,6 +16,7 @@
package android.text.method;
+import android.util.Log;
import android.view.KeyEvent;
import android.text.*;
import android.widget.TextView;
@@ -185,15 +186,9 @@ implements MovementMethod
if (code != KeyEvent.KEYCODE_UNKNOWN
&& event.getAction() == KeyEvent.ACTION_MULTIPLE) {
int repeat = event.getRepeatCount();
- boolean first = true;
boolean handled = false;
while ((--repeat) > 0) {
- if (first && executeDown(view, text, code)) {
- handled = true;
- MetaKeyKeyListener.adjustMetaAfterKeypress(text);
- MetaKeyKeyListener.resetLockedMeta(text);
- }
- first = false;
+ handled |= executeDown(view, text, code);
}
return handled;
}
diff --git a/core/java/android/text/method/MetaKeyKeyListener.java b/core/java/android/text/method/MetaKeyKeyListener.java
index d89fbec..39ad976 100644
--- a/core/java/android/text/method/MetaKeyKeyListener.java
+++ b/core/java/android/text/method/MetaKeyKeyListener.java
@@ -287,10 +287,10 @@ public abstract class MetaKeyKeyListener {
}
public static void clearMetaKeyState(Editable content, int states) {
- if ((states&META_SHIFT_ON) != 0) resetLock(content, CAP);
- if ((states&META_ALT_ON) != 0) resetLock(content, ALT);
- if ((states&META_SYM_ON) != 0) resetLock(content, SYM);
- if ((states&META_SELECTING) != 0) resetLock(content, SELECTING);
+ if ((states&META_SHIFT_ON) != 0) content.removeSpan(CAP);
+ if ((states&META_ALT_ON) != 0) content.removeSpan(ALT);
+ if ((states&META_SYM_ON) != 0) content.removeSpan(SYM);
+ if ((states&META_SELECTING) != 0) content.removeSpan(SELECTING);
}
/**
diff --git a/core/java/android/text/method/PasswordTransformationMethod.java b/core/java/android/text/method/PasswordTransformationMethod.java
index 85adabd..fad4f64 100644
--- a/core/java/android/text/method/PasswordTransformationMethod.java
+++ b/core/java/android/text/method/PasswordTransformationMethod.java
@@ -105,8 +105,10 @@ implements TransformationMethod, TextWatcher
sp.removeSpan(old[i]);
}
- sp.setSpan(new Visible(sp, this), start, start + count,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ if (count == 1) {
+ sp.setSpan(new Visible(sp, this), start, start + count,
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
}
}
}
diff --git a/core/java/android/view/HapticFeedbackConstants.java b/core/java/android/view/HapticFeedbackConstants.java
new file mode 100644
index 0000000..cc3563c
--- /dev/null
+++ b/core/java/android/view/HapticFeedbackConstants.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+/**
+ * Constants to be used to perform haptic feedback effects via
+ * {@link View#performHapticFeedback(int)}
+ */
+public class HapticFeedbackConstants {
+
+ private HapticFeedbackConstants() {}
+
+ public static final int LONG_PRESS = 0;
+
+ /** @hide pending API council */
+ public static final int ZOOM_RING_TICK = 1;
+
+ /**
+ * Flag for {@link View#performHapticFeedback(int, int)
+ * View.performHapticFeedback(int, int)}: Ignore the setting in the
+ * view for whether to perform haptic feedback, do it always.
+ */
+ public static final int FLAG_IGNORE_VIEW_SETTING = 0x0001;
+
+ /**
+ * Flag for {@link View#performHapticFeedback(int, int)
+ * View.performHapticFeedback(int, int)}: Ignore the global setting
+ * for whether to perform haptic feedback, do it always.
+ */
+ public static final int FLAG_IGNORE_GLOBAL_SETTING = 0x0002;
+}
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 7276f17..1156856 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -106,5 +106,6 @@ interface IWindowSession {
void setInTouchMode(boolean showFocus);
boolean getInTouchMode();
+
+ boolean performHapticFeedback(IWindow window, int effectId, boolean always);
}
-
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index a51b564..1d5e7cd 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -836,6 +836,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
public static final int SOUND_EFFECTS_ENABLED = 0x08000000;
/**
+ * View flag indicating whether this view should have haptic feedback
+ * enabled for events such as long presses.
+ */
+ public static final int HAPTIC_FEEDBACK_ENABLED = 0x10000000;
+
+ /**
* Use with {@link #focusSearch}. Move focus to the previous selectable
* item.
*/
@@ -1637,6 +1643,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
public View(Context context) {
mContext = context;
mResources = context != null ? context.getResources() : null;
+ mViewFlags = SOUND_EFFECTS_ENABLED|HAPTIC_FEEDBACK_ENABLED;
++sInstanceCount;
}
@@ -1703,9 +1710,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
int scrollbarStyle = SCROLLBARS_INSIDE_OVERLAY;
- viewFlagValues |= SOUND_EFFECTS_ENABLED;
- viewFlagMasks |= SOUND_EFFECTS_ENABLED;
-
final int N = a.getIndexCount();
for (int i = 0; i < N; i++) {
int attr = a.getIndex(i);
@@ -1801,6 +1805,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
viewFlagValues &= ~SOUND_EFFECTS_ENABLED;
viewFlagMasks |= SOUND_EFFECTS_ENABLED;
}
+ case com.android.internal.R.styleable.View_hapticFeedbackEnabled:
+ if (!a.getBoolean(attr, true)) {
+ viewFlagValues &= ~HAPTIC_FEEDBACK_ENABLED;
+ viewFlagMasks |= HAPTIC_FEEDBACK_ENABLED;
+ }
case R.styleable.View_scrollbars:
final int scrollbars = a.getInt(attr, SCROLLBARS_NONE);
if (scrollbars != SCROLLBARS_NONE) {
@@ -2182,6 +2191,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
if (!handled) {
handled = showContextMenu();
}
+ if (handled) {
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+ }
return handled;
}
@@ -2742,7 +2754,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
* Set whether this view should have sound effects enabled for events such as
* clicking and touching.
*
- * You may wish to disable sound effects for a view if you already play sounds,
+ * <p>You may wish to disable sound effects for a view if you already play sounds,
* for instance, a dial key that plays dtmf tones.
*
* @param soundEffectsEnabled whether sound effects are enabled for this view.
@@ -2768,6 +2780,35 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
}
/**
+ * Set whether this view should have haptic feedback for events such as
+ * long presses.
+ *
+ * <p>You may wish to disable haptic feedback if your view already controls
+ * its own haptic feedback.
+ *
+ * @param hapticFeedbackEnabled whether haptic feedback enabled for this view.
+ * @see #isHapticFeedbackEnabled()
+ * @see #performHapticFeedback(int)
+ * @attr ref android.R.styleable#View_hapticFeedbackEnabled
+ */
+ public void setHapticFeedbackEnabled(boolean hapticFeedbackEnabled) {
+ setFlags(hapticFeedbackEnabled ? HAPTIC_FEEDBACK_ENABLED: 0, HAPTIC_FEEDBACK_ENABLED);
+ }
+
+ /**
+ * @return whether this view should have haptic feedback enabled for events
+ * long presses.
+ *
+ * @see #setHapticFeedbackEnabled(boolean)
+ * @see #performHapticFeedback(int)
+ * @attr ref android.R.styleable#View_hapticFeedbackEnabled
+ */
+ @ViewDebug.ExportedProperty
+ public boolean isHapticFeedbackEnabled() {
+ return HAPTIC_FEEDBACK_ENABLED == (mViewFlags & HAPTIC_FEEDBACK_ENABLED);
+ }
+
+ /**
* If this view doesn't do any drawing on its own, set this flag to
* allow further optimizations. By default, this flag is not set on
* View, but could be set on some View subclasses such as ViewGroup.
@@ -7312,20 +7353,57 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
/**
* Play a sound effect for this view.
*
- * The framework will play sound effects for some built in actions, such as
+ * <p>The framework will play sound effects for some built in actions, such as
* clicking, but you may wish to play these effects in your widget,
* for instance, for internal navigation.
*
- * The sound effect will only be played if sound effects are enabled by the user, and
+ * <p>The sound effect will only be played if sound effects are enabled by the user, and
* {@link #isSoundEffectsEnabled()} is true.
*
* @param soundConstant One of the constants defined in {@link SoundEffectConstants}
*/
- protected void playSoundEffect(int soundConstant) {
- if (mAttachInfo == null || mAttachInfo.mSoundEffectPlayer == null || !isSoundEffectsEnabled()) {
+ public void playSoundEffect(int soundConstant) {
+ if (mAttachInfo == null || mAttachInfo.mRootCallbacks == null || !isSoundEffectsEnabled()) {
return;
}
- mAttachInfo.mSoundEffectPlayer.playSoundEffect(soundConstant);
+ mAttachInfo.mRootCallbacks.playSoundEffect(soundConstant);
+ }
+
+ /**
+ * Provide haptic feedback to the user for this view.
+ *
+ * <p>The framework will provide haptic feedback for some built in actions,
+ * such as long presses, but you may wish to provide feedback for your
+ * own widget.
+ *
+ * <p>The feedback will only be performed if
+ * {@link #isHapticFeedbackEnabled()} is true.
+ *
+ * @param feedbackConstant One of the constants defined in
+ * {@link HapticFeedbackConstants}
+ */
+ public boolean performHapticFeedback(int feedbackConstant) {
+ return performHapticFeedback(feedbackConstant, 0);
+ }
+
+ /**
+ * Like {@link #performHapticFeedback(int)}, with additional options.
+ *
+ * @param feedbackConstant One of the constants defined in
+ * {@link HapticFeedbackConstants}
+ * @param flags Additional flags as per {@link HapticFeedbackConstants}.
+ */
+ public boolean performHapticFeedback(int feedbackConstant, int flags) {
+ if (mAttachInfo == null) {
+ return false;
+ }
+ if ((flags&HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING) == 0
+ && !isHapticFeedbackEnabled()) {
+ return false;
+ }
+ return mAttachInfo.mRootCallbacks.performHapticFeedback(
+ feedbackConstant,
+ (flags&HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING) != 0);
}
/**
@@ -7704,8 +7782,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
*/
static class AttachInfo {
- interface SoundEffectPlayer {
+ interface Callbacks {
void playSoundEffect(int effectId);
+ boolean performHapticFeedback(int effectId, boolean always);
}
/**
@@ -7775,7 +7854,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
final IBinder mWindowToken;
- final SoundEffectPlayer mSoundEffectPlayer;
+ final Callbacks mRootCallbacks;
/**
* The top view of the hierarchy.
@@ -7922,12 +8001,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
* @param handler the events handler the view must use
*/
AttachInfo(IWindowSession session, IWindow window,
- Handler handler, SoundEffectPlayer effectPlayer) {
+ Handler handler, Callbacks effectPlayer) {
mSession = session;
mWindow = window;
mWindowToken = window.asBinder();
mHandler = handler;
- mSoundEffectPlayer = effectPlayer;
+ mRootCallbacks = effectPlayer;
}
}
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 4e46397..ccfa6bf 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -61,7 +61,7 @@ import static javax.microedition.khronos.opengles.GL10.*;
*/
@SuppressWarnings({"EmptyCatchBlock"})
public final class ViewRoot extends Handler implements ViewParent,
- View.AttachInfo.SoundEffectPlayer {
+ View.AttachInfo.Callbacks {
private static final String TAG = "ViewRoot";
private static final boolean DBG = false;
@SuppressWarnings({"ConstantConditionalExpression"})
@@ -1637,7 +1637,7 @@ public final class ViewRoot extends Handler implements ViewParent,
dispatchDetachedFromWindow();
break;
case DISPATCH_KEY_FROM_IME:
- if (true) Log.v(
+ if (LOCAL_LOGV) Log.v(
"ViewRoot", "Dispatching key "
+ msg.obj + " from IME to " + mView);
deliverKeyEventToViewHierarchy((KeyEvent)msg.obj, false);
@@ -2238,6 +2238,17 @@ public final class ViewRoot extends Handler implements ViewParent,
/**
* {@inheritDoc}
*/
+ public boolean performHapticFeedback(int effectId, boolean always) {
+ try {
+ return sWindowSession.performHapticFeedback(mWindow, effectId, always);
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public View focusSearch(View focused, int direction) {
checkThread();
if (!(mView instanceof ViewGroup)) {
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index d08a6fa..406af3e3 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -925,7 +925,7 @@ public interface WindowManager extends ViewManager {
sb.append(Integer.toHexString(windowAnimations));
}
if (screenOrientation != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
- sb.append("or=");
+ sb.append(" or=");
sb.append(screenOrientation);
}
sb.append('}');
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 542b35f..051f823 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -771,4 +771,15 @@ public interface WindowManagerPolicy {
public boolean isCheekPressedAgainstScreen(MotionEvent ev);
public void setCurrentOrientation(int newOrientation);
+
+ /**
+ * Call from application to perform haptic feedback on its window.
+ */
+ public boolean performHapticFeedback(WindowState win, int effectId, boolean always);
+
+ /**
+ * Called when we have stopped keeping the screen on because a window
+ * requesting this is no longer visible.
+ */
+ public void screenOnStopped();
}
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index 56c6c92..9509b15 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -371,6 +371,14 @@ public class BaseInputConnection implements InputConnection {
if (DEBUG) Log.v(TAG, "setSelection " + start + ", " + end);
final Editable content = getEditable();
if (content == null) return false;
+ int len = content.length();
+ if (start > len || end > len) {
+ // If the given selection is out of bounds, just ignore it.
+ // Most likely the text was changed out from under the IME,
+ // the the IME is going to have to update all of its state
+ // anyway.
+ return true;
+ }
Selection.setSelection(content, start, end);
return true;
}
@@ -396,20 +404,10 @@ public class BaseInputConnection implements InputConnection {
}
/**
- * Provides standard implementation for hiding the status icon associated
- * with the current input method.
+ * Updates InputMethodManager with the current fullscreen mode.
*/
- public boolean hideStatusIcon() {
- mIMM.updateStatusIcon(0, null);
- return true;
- }
-
- /**
- * Provides standard implementation for showing the status icon associated
- * with the current input method.
- */
- public boolean showStatusIcon(String packageName, int resId) {
- mIMM.updateStatusIcon(resId, packageName);
+ public boolean reportFullscreenMode(boolean enabled) {
+ mIMM.setFullscreenMode(enabled);
return true;
}
@@ -420,7 +418,11 @@ public class BaseInputConnection implements InputConnection {
Editable content = getEditable();
if (content != null) {
- if (content.length() == 1) {
+ final int N = content.length();
+ if (N == 0) {
+ return;
+ }
+ if (N == 1) {
// If it's 1 character, we have a chance of being
// able to generate normal key events...
if (mKeyCharacterMap == null) {
diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java
index 8c30d3f..13173f6 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -267,6 +267,13 @@ public interface InputConnection {
public boolean clearMetaKeyStates(int states);
/**
+ * Called by the IME to tell the client when it switches between fullscreen
+ * and normal modes. This will normally be called for you by the standard
+ * implementation of {@link android.inputmethodservice.InputMethodService}.
+ */
+ public boolean reportFullscreenMode(boolean enabled);
+
+ /**
* API to send private commands from an input method to its connected
* editor. This can be used to provide domain-specific features that are
* only known between certain input methods and their clients. Note that
@@ -284,23 +291,4 @@ public interface InputConnection {
* valid.
*/
public boolean performPrivateCommand(String action, Bundle data);
-
- /**
- * Show an icon in the status bar.
- *
- * @param packageName The package holding the icon resource to be shown.
- * @param resId The resource id of the icon to show.
- *
- * @return Returns true on success, false if the input connection is no longer
- * valid.
- */
- public boolean showStatusIcon(String packageName, int resId);
-
- /**
- * Hide the icon shown in the status bar.
- *
- * @return Returns true on success, false if the input connection is no longer
- * valid.
- */
- public boolean hideStatusIcon();
}
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 99d5aa5..fe14166 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -214,6 +214,11 @@ public final class InputMethodManager {
*/
boolean mActive = false;
+ /**
+ * As reported by IME through InputConnection.
+ */
+ boolean mFullscreenMode;
+
// -----------------------------------------------------------
/**
@@ -374,6 +379,7 @@ public final class InputMethodManager {
public void setActive(boolean active) {
mActive = active;
+ mFullscreenMode = false;
}
};
@@ -443,14 +449,36 @@ public final class InputMethodManager {
}
}
- public void updateStatusIcon(int iconId, String iconPackage) {
+ public void showStatusIcon(IBinder imeToken, String packageName, int iconId) {
+ try {
+ mService.updateStatusIcon(imeToken, packageName, iconId);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void hideStatusIcon(IBinder imeToken) {
try {
- mService.updateStatusIcon(iconId, iconPackage);
+ mService.updateStatusIcon(imeToken, null, 0);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
+ /** @hide */
+ public void setFullscreenMode(boolean enabled) {
+ mFullscreenMode = true;
+ }
+
+ /**
+ * Allows you to discover whether the attached input method is running
+ * in fullscreen mode. Return true if it is fullscreen, entirely covering
+ * your UI, else returns false.
+ */
+ public boolean isFullscreenMode() {
+ return mFullscreenMode;
+ }
+
/**
* Return true if the given view is the currently active view for the
* input method.
@@ -503,7 +531,6 @@ public final class InputMethodManager {
void finishInputLocked() {
if (mServedView != null) {
if (DEBUG) Log.v(TAG, "FINISH INPUT: " + mServedView);
- updateStatusIcon(0, null);
if (mCurrentTextBoxAttribute != null) {
try {
diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java
index 5a37f04..07c1a5d 100644
--- a/core/java/android/webkit/CookieManager.java
+++ b/core/java/android/webkit/CookieManager.java
@@ -171,6 +171,10 @@ public final class CookieManager {
boolean pathMatch(String urlPath) {
if (urlPath.startsWith(path)) {
int len = path.length();
+ if (len == 0) {
+ Log.w(LOGTAG, "Empty cookie path");
+ return false;
+ }
int urlLen = urlPath.length();
if (path.charAt(len-1) != PATH_DELIM && urlLen > len) {
// make sure /wee doesn't match /we
@@ -864,7 +868,10 @@ public final class CookieManager {
"illegal format for max-age: " + value);
}
} else if (name.equals(PATH)) {
- cookie.path = value;
+ // only allow non-empty path value
+ if (value.length() > 0) {
+ cookie.path = value;
+ }
} else if (name.equals(DOMAIN)) {
int lastPeriod = value.lastIndexOf(PERIOD);
if (lastPeriod == 0) {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 3306700..bdbf38a 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -260,19 +260,8 @@ public class WebView extends AbsoluteLayout
// Whether we are in the drag tap mode, which exists starting at the second
// tap's down, through its move, and includes its up. These events should be
// given to the method on the zoom controller.
- private boolean mInZoomTapDragMode;
-
- // The event time of the previous touch up.
- private long mPreviousUpTime;
-
- private Runnable mRemoveReleaseSingleTap = new Runnable() {
- public void run() {
- mPrivateHandler.removeMessages(RELEASE_SINGLE_TAP);
- mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
- mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
- }
- };
-
+ private boolean mInZoomTapDragMode = false;
+
// Whether to prevent drag during touch. The initial value depends on
// mForwardTouchEvents. If WebCore wants touch events, we assume it will
// take control of touch events unless it says no for touch down event.
@@ -517,6 +506,11 @@ public class WebView extends AbsoluteLayout
private ZoomRingController mZoomRingController;
+ // These keep track of the center point of the zoom ring. They are used to
+ // determine the point around which we should zoom.
+ private float mZoomCenterX;
+ private float mZoomCenterY;
+
private ZoomRingController.OnZoomListener mZoomListener =
new ZoomRingController.OnZoomListener() {
@@ -554,12 +548,9 @@ public class WebView extends AbsoluteLayout
deltaZoomLevel == 0) {
return false;
}
-
- int deltaX = centerX - getViewWidth() / 2;
- int deltaY = centerY - getViewHeight() / 2;
+ mZoomCenterX = (float) centerX;
+ mZoomCenterY = (float) centerY;
- pinScrollBy(deltaX, deltaY, false, 0);
-
while (deltaZoomLevel != 0) {
if (deltaZoomLevel > 0) {
if (!zoomIn()) return false;
@@ -569,15 +560,16 @@ public class WebView extends AbsoluteLayout
deltaZoomLevel++;
}
}
-
- pinScrollBy(-deltaX, -deltaY, false, 0);
-
+
return true;
}
public void onSimpleZoom(boolean zoomIn) {
- if (zoomIn) zoomIn();
- else zoomOut();
+ if (zoomIn) {
+ zoomIn();
+ } else {
+ zoomOut();
+ }
}
};
@@ -1586,8 +1578,8 @@ public class WebView extends AbsoluteLayout
int oldX = mScrollX;
int oldY = mScrollY;
float ratio = scale * mInvActualScale; // old inverse
- float sx = ratio * oldX + (ratio - 1) * getViewWidth() * 0.5f;
- float sy = ratio * oldY + (ratio - 1) * getViewHeight() * 0.5f;
+ float sx = ratio * oldX + (ratio - 1) * mZoomCenterX;
+ float sy = ratio * oldY + (ratio - 1) * mZoomCenterY;
// now update our new scale and inverse
if (scale != mActualScale && !mPreviewZoomOnly) {
@@ -2264,8 +2256,8 @@ public class WebView extends AbsoluteLayout
zoomScale = mZoomScale;
}
float scale = (mActualScale - zoomScale) * mInvActualScale;
- float tx = scale * ((getLeft() + getRight()) * 0.5f + mScrollX);
- float ty = scale * ((getTop() + getBottom()) * 0.5f + mScrollY);
+ float tx = scale * (mZoomCenterX + mScrollX);
+ float ty = scale * (mZoomCenterY + mScrollY);
// this block pins the translate to "legal" bounds. This makes the
// animation a bit non-obvious, but it means we won't pop when the
@@ -3025,8 +3017,8 @@ public class WebView extends AbsoluteLayout
(keyCode == KeyEvent.KEYCODE_7) ? 1 : 0, 0);
break;
case KeyEvent.KEYCODE_9:
- debugDump();
- break;
+ nativeInstrumentReport();
+ return true;
}
}
@@ -3161,6 +3153,7 @@ public class WebView extends AbsoluteLayout
* @hide
*/
public void emulateShiftHeld() {
+ mExtendSelection = false;
mShiftIsPressed = true;
}
@@ -3176,6 +3169,7 @@ public class WebView extends AbsoluteLayout
mWebViewCore.sendMessage(EventHub.GET_SELECTION, selection);
copiedSomething = true;
}
+ mExtendSelection = false;
}
mShiftIsPressed = false;
if (mTouchMode == TOUCH_SELECT_MODE) {
@@ -3218,6 +3212,11 @@ public class WebView extends AbsoluteLayout
}
}
+ /**
+ * @deprecated WebView should not have implemented
+ * ViewTreeObserver.OnGlobalFocusChangeListener. This method
+ * does nothing now.
+ */
@Deprecated
public void onGlobalFocusChanged(View oldFocus, View newFocus) {
}
@@ -3281,7 +3280,11 @@ public class WebView extends AbsoluteLayout
@Override
protected void onSizeChanged(int w, int h, int ow, int oh) {
super.onSizeChanged(w, h, ow, oh);
-
+ // Center zooming to the center of the screen. This is appropriate for
+ // this case of zooming, and it also sets us up properly if we remove
+ // the new zoom ring controller
+ mZoomCenterX = getViewWidth() * .5f;
+ mZoomCenterY = getViewHeight() * .5f;
// we always force, in case our height changed, in which case we still
// want to send the notification over to webkit
setNewZoomScale(mActualScale, true);
@@ -3342,25 +3345,12 @@ public class WebView extends AbsoluteLayout
+ mTouchMode);
}
- if (mZoomRingController.isVisible()) {
- if (mInZoomTapDragMode) {
- mZoomRingController.handleDoubleTapEvent(ev);
- if (ev.getAction() == MotionEvent.ACTION_UP) {
- // Just released the second tap, no longer in tap-drag mode
- mInZoomTapDragMode = false;
- }
- return true;
- } else {
- // TODO: properly do this.
- /*
- * When the zoom widget is showing, the user can tap outside of
- * it to dismiss it. Furthermore, he can drag outside of it to
- * pan the browser. However, we do not want a tap on a link to
- * open the link.
- */
- post(mRemoveReleaseSingleTap);
- // Continue through to normal processing
+ if (mZoomRingController.isVisible() && mInZoomTapDragMode) {
+ if (ev.getAction() == MotionEvent.ACTION_UP) {
+ // Just released the second tap, no longer in tap-drag mode
+ mInZoomTapDragMode = false;
}
+ return mZoomRingController.handleDoubleTapEvent(ev);
}
int action = ev.getAction();
@@ -3418,21 +3408,19 @@ public class WebView extends AbsoluteLayout
, viewToContent(mSelectY), false);
mTouchSelection = mExtendSelection = true;
} else if (!ZoomRingController.useOldZoom(mContext) &&
- eventTime - mPreviousUpTime < DOUBLE_TAP_TIMEOUT &&
- getSettings().supportZoom() &&
- mMinZoomScale < mMaxZoomScale) {
+ mPrivateHandler.hasMessages(RELEASE_SINGLE_TAP)) {
// Found doubletap, invoke the zoom controller
- mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
- mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
mPrivateHandler.removeMessages(RELEASE_SINGLE_TAP);
mZoomRingController.setVisible(true);
mInZoomTapDragMode = true;
- mZoomRingController.handleDoubleTapEvent(ev);
+ return mZoomRingController.handleDoubleTapEvent(ev);
} else {
mTouchMode = TOUCH_INIT_MODE;
mPreventDrag = mForwardTouchEvents;
}
- if (mTouchMode == TOUCH_INIT_MODE) {
+ // don't trigger the link if zoom ring is visible
+ if (mTouchMode == TOUCH_INIT_MODE
+ && !mZoomRingController.isVisible()) {
mPrivateHandler.sendMessageDelayed(mPrivateHandler
.obtainMessage(SWITCH_TO_SHORTPRESS), TAP_TIMEOUT);
}
@@ -3485,9 +3473,6 @@ public class WebView extends AbsoluteLayout
mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
}
- // Prevent double-tap from being invoked
- mPreviousUpTime = 0;
-
// if it starts nearly horizontal or vertical, enforce it
int ax = Math.abs(deltaX);
int ay = Math.abs(deltaY);
@@ -3597,6 +3582,10 @@ public class WebView extends AbsoluteLayout
case MotionEvent.ACTION_UP: {
switch (mTouchMode) {
case TOUCH_INIT_MODE: // tap
+ if (mZoomRingController.isVisible()) {
+ // don't trigger the link if zoom ring is visible
+ break;
+ }
mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
if (getSettings().supportZoom()
&& (mMinZoomScale < mMaxZoomScale)) {
@@ -3611,7 +3600,7 @@ public class WebView extends AbsoluteLayout
break;
case TOUCH_SELECT_MODE:
commitCopy();
- mTouchSelection = mExtendSelection = false;
+ mTouchSelection = false;
break;
case SCROLL_ZOOM_ANIMATION_IN:
case SCROLL_ZOOM_ANIMATION_OUT:
@@ -3679,7 +3668,6 @@ public class WebView extends AbsoluteLayout
mVelocityTracker.recycle();
mVelocityTracker = null;
}
- mPreviousUpTime = eventTime;
break;
}
case MotionEvent.ACTION_CANCEL: {
@@ -4110,6 +4098,14 @@ public class WebView extends AbsoluteLayout
}
/**
+ * @hide pending API council? Assuming we make ZoomRingController itself
+ * public, which I think we will.
+ */
+ public ZoomRingController getZoomRingController() {
+ return mZoomRingController;
+ }
+
+ /**
* Perform zoom in in the webview
* @return TRUE if zoom in succeeds. FALSE if no zoom changes.
*/
@@ -4193,16 +4189,15 @@ public class WebView extends AbsoluteLayout
return;
}
switchOutDrawHistory();
- // FIXME: we don't know if the current (x,y) is on a focus node or
- // not -- so playing the sound effect here is premature
- if (nativeUpdateFocusNode()) {
- playSoundEffect(SoundEffectConstants.CLICK);
- }
// mLastTouchX and mLastTouchY are the point in the current viewport
int contentX = viewToContent((int) mLastTouchX + mScrollX);
int contentY = viewToContent((int) mLastTouchY + mScrollY);
int contentSize = ViewConfiguration.get(getContext()).getScaledTouchSlop();
nativeMotionUp(contentX, contentY, contentSize, true);
+ if (nativeUpdateFocusNode() && !mFocusNode.mIsTextField
+ && !mFocusNode.mIsTextArea) {
+ playSoundEffect(SoundEffectConstants.CLICK);
+ }
}
@Override
@@ -5013,6 +5008,7 @@ public class WebView extends AbsoluteLayout
private native boolean nativeUpdateFocusNode();
private native Rect nativeGetFocusRingBounds();
private native Rect nativeGetNavBounds();
+ private native void nativeInstrumentReport();
private native void nativeMarkNodeInvalid(int node);
private native void nativeMotionUp(int x, int y, int slop, boolean isClick);
// returns false if it handled the key
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 8f78887..b979032 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -330,8 +330,7 @@ final class WebViewCore {
String currentText, int keyCode, int keyValue, boolean down,
boolean cap, boolean fn, boolean sym);
- private native void nativeSaveDocumentState(int frame, int node, int x,
- int y);
+ private native void nativeSaveDocumentState(int frame);
private native void nativeSetFinalFocus(int framePtr, int nodePtr, int x,
int y, boolean block);
@@ -777,8 +776,7 @@ final class WebViewCore {
case SAVE_DOCUMENT_STATE: {
FocusData fDat = (FocusData) msg.obj;
- nativeSaveDocumentState(fDat.mFrame, fDat.mNode,
- fDat.mX, fDat.mY);
+ nativeSaveDocumentState(fDat.mFrame);
break;
}
diff --git a/core/java/android/webkit/WebViewDatabase.java b/core/java/android/webkit/WebViewDatabase.java
index 96f3698..1004e30 100644
--- a/core/java/android/webkit/WebViewDatabase.java
+++ b/core/java/android/webkit/WebViewDatabase.java
@@ -531,33 +531,34 @@ public class WebViewDatabase {
* @param url The url
* @return CacheResult The CacheManager.CacheResult
*/
- @SuppressWarnings("deprecation")
CacheResult getCache(String url) {
if (url == null || mCacheDatabase == null) {
return null;
}
- CacheResult ret = null;
- final String s = "SELECT filepath, lastmodify, etag, expires, mimetype, encoding, httpstatus, location, contentlength FROM cache WHERE url = ";
- StringBuilder sb = new StringBuilder(256);
- sb.append(s);
- DatabaseUtils.appendEscapedSQLString(sb, url);
- Cursor cursor = mCacheDatabase.rawQuery(sb.toString(), null);
+ Cursor cursor = mCacheDatabase.rawQuery("SELECT filepath, lastmodify, etag, expires, "
+ + "mimetype, encoding, httpstatus, location, contentlength "
+ + "FROM cache WHERE url = ?",
+ new String[] { url });
- if (cursor.moveToFirst()) {
- ret = new CacheResult();
- ret.localPath = cursor.getString(0);
- ret.lastModified = cursor.getString(1);
- ret.etag = cursor.getString(2);
- ret.expires = cursor.getLong(3);
- ret.mimeType = cursor.getString(4);
- ret.encoding = cursor.getString(5);
- ret.httpStatusCode = cursor.getInt(6);
- ret.location = cursor.getString(7);
- ret.contentLength = cursor.getLong(8);
+ try {
+ if (cursor.moveToFirst()) {
+ CacheResult ret = new CacheResult();
+ ret.localPath = cursor.getString(0);
+ ret.lastModified = cursor.getString(1);
+ ret.etag = cursor.getString(2);
+ ret.expires = cursor.getLong(3);
+ ret.mimeType = cursor.getString(4);
+ ret.encoding = cursor.getString(5);
+ ret.httpStatusCode = cursor.getInt(6);
+ ret.location = cursor.getString(7);
+ ret.contentLength = cursor.getLong(8);
+ return ret;
+ }
+ } finally {
+ if (cursor != null) cursor.close();
}
- cursor.close();
- return ret;
+ return null;
}
/**
@@ -565,16 +566,12 @@ public class WebViewDatabase {
*
* @param url The url
*/
- @SuppressWarnings("deprecation")
void removeCache(String url) {
if (url == null || mCacheDatabase == null) {
return;
}
- StringBuilder sb = new StringBuilder(256);
- sb.append("DELETE FROM cache WHERE url = ");
- DatabaseUtils.appendEscapedSQLString(sb, url);
- mCacheDatabase.execSQL(sb.toString());
+ mCacheDatabase.execSQL("DELETE FROM cache WHERE url = ?", new String[] { url });
}
/**
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 378d218..c012e25 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -31,6 +31,7 @@ import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.Gravity;
+import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -1622,6 +1623,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mContextMenuInfo = createContextMenuInfo(child, longPressPosition, longPressId);
handled = super.showContextMenuForChild(AbsListView.this);
}
+ if (handled) {
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+ }
return handled;
}
diff --git a/core/java/android/widget/CursorFilter.java b/core/java/android/widget/CursorFilter.java
index afd5b10..dbded69 100644
--- a/core/java/android/widget/CursorFilter.java
+++ b/core/java/android/widget/CursorFilter.java
@@ -60,11 +60,10 @@ class CursorFilter extends Filter {
}
@Override
- protected void publishResults(CharSequence constraint,
- FilterResults results) {
+ protected void publishResults(CharSequence constraint, FilterResults results) {
Cursor oldCursor = mClient.getCursor();
- if (results.values != oldCursor) {
+ if (results.values != null && results.values != oldCursor) {
mClient.changeCursor((Cursor) results.values);
}
}
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index 67010b2..54f2707 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -47,11 +47,8 @@ public class DatePicker extends FrameLayout {
/* UI Components */
private final NumberPicker mDayPicker;
private final NumberPicker mMonthPicker;
- private final NumberPicker mYearPicker;
-
- private final int mStartYear;
- private final int mEndYear;
-
+ private final NumberPicker mYearPicker;
+
/**
* How we notify users the date has changed.
*/
@@ -87,12 +84,9 @@ public class DatePicker extends FrameLayout {
public DatePicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- LayoutInflater inflater =
- (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- inflater.inflate(R.layout.date_picker,
- this, // we are the parent
- true);
-
+ LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ inflater.inflate(R.layout.date_picker, this, true);
+
mDayPicker = (NumberPicker) findViewById(R.id.day);
mDayPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
mDayPicker.setSpeed(100);
@@ -134,20 +128,17 @@ public class DatePicker extends FrameLayout {
});
// attributes
- TypedArray a = context
- .obtainStyledAttributes(attrs, R.styleable.DatePicker);
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DatePicker);
- mStartYear = a.getInt(R.styleable.DatePicker_startYear, DEFAULT_START_YEAR);
- mEndYear = a.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR);
+ int mStartYear = a.getInt(R.styleable.DatePicker_startYear, DEFAULT_START_YEAR);
+ int mEndYear = a.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR);
mYearPicker.setRange(mStartYear, mEndYear);
a.recycle();
// initialize to current date
Calendar cal = Calendar.getInstance();
- init(cal.get(Calendar.YEAR),
- cal.get(Calendar.MONTH),
- cal.get(Calendar.DAY_OF_MONTH), null);
+ init(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), null);
// re-order the number pickers to match the current date format
reorderPickers();
diff --git a/core/java/android/widget/Filter.java b/core/java/android/widget/Filter.java
index 7f1601e..a2316cf 100644
--- a/core/java/android/widget/Filter.java
+++ b/core/java/android/widget/Filter.java
@@ -20,6 +20,7 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
+import android.util.Log;
/**
* <p>A filter constrains data with a filtering pattern.</p>
@@ -36,6 +37,8 @@ import android.os.Message;
* @see android.widget.Filterable
*/
public abstract class Filter {
+ private static final String LOG_TAG = "Filter";
+
private static final String THREAD_NAME = "Filter";
private static final int FILTER_TOKEN = 0xD0D0F00D;
private static final int FINISH_TOKEN = 0xDEADBEEF;
@@ -221,6 +224,9 @@ public abstract class Filter {
RequestArguments args = (RequestArguments) msg.obj;
try {
args.results = performFiltering(args.constraint);
+ } catch (Exception e) {
+ args.results = new FilterResults();
+ Log.w(LOG_TAG, "An exception occured during performFiltering()!", e);
} finally {
message = mResultHandler.obtainMessage(what);
message.obj = args;
diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java
index ffabb02..e7b303a 100644
--- a/core/java/android/widget/Gallery.java
+++ b/core/java/android/widget/Gallery.java
@@ -27,6 +27,7 @@ import android.util.Config;
import android.util.Log;
import android.view.GestureDetector;
import android.view.Gravity;
+import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
@@ -994,6 +995,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
return;
}
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
long id = getItemIdAtPosition(mDownTouchPosition);
dispatchLongPress(mDownTouchView, mDownTouchPosition, id);
}
@@ -1086,6 +1088,10 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
handled = super.showContextMenuForChild(this);
}
+ if (handled) {
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+ }
+
return handled;
}
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index b5d4e2d..4ae322e 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -48,6 +48,7 @@ import android.widget.RemoteViews.RemoteView;
* @attr ref android.R.styleable#ImageView_maxHeight
* @attr ref android.R.styleable#ImageView_tint
* @attr ref android.R.styleable#ImageView_scaleType
+ * @attr ref android.R.styleable#ImageView_cropToPadding
*/
@RemoteView
public class ImageView extends View {
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index a1023bd..25afee8 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -35,6 +35,8 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.LayoutInflater.Filter;
import android.view.View.OnClickListener;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -548,6 +550,54 @@ public class RemoteViews implements Parcelable, Filter {
}
/**
+ * Equivalent to calling {@link android.widget.ViewFlipper#startFlipping()}
+ * or {@link android.widget.ViewFlipper#stopFlipping()} along with
+ * {@link android.widget.ViewFlipper#setFlipInterval(int)}.
+ */
+ private class SetFlipping extends Action {
+ public SetFlipping(int id, boolean flipping, int milliseconds) {
+ this.viewId = id;
+ this.flipping = flipping;
+ this.milliseconds = milliseconds;
+ }
+
+ public SetFlipping(Parcel parcel) {
+ viewId = parcel.readInt();
+ flipping = parcel.readInt() != 0;
+ milliseconds = parcel.readInt();
+ }
+
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(TAG);
+ dest.writeInt(viewId);
+ dest.writeInt(flipping ? 1 : 0);
+ dest.writeInt(milliseconds);
+ }
+
+ @Override
+ public void apply(View root) {
+ final View target = root.findViewById(viewId);
+ if (target instanceof ViewFlipper) {
+ final ViewFlipper flipper = (ViewFlipper) target;
+ if (milliseconds != -1) {
+ flipper.setFlipInterval(milliseconds);
+ }
+ if (flipping) {
+ flipper.startFlipping();
+ } else {
+ flipper.stopFlipping();
+ }
+ }
+ }
+
+ int viewId;
+ boolean flipping;
+ int milliseconds;
+
+ public final static int TAG = 10;
+ }
+
+ /**
* Create a new RemoteViews object that will display the views contained
* in the specified layout file.
*
@@ -603,6 +653,9 @@ public class RemoteViews implements Parcelable, Filter {
case SetTextColor.TAG:
mActions.add(new SetTextColor(parcel));
break;
+ case SetFlipping.TAG:
+ mActions.add(new SetFlipping(parcel));
+ break;
default:
throw new ActionException("Tag " + tag + "not found");
}
@@ -769,6 +822,22 @@ public class RemoteViews implements Parcelable, Filter {
}
/**
+ * Equivalent to calling {@link android.widget.ViewFlipper#startFlipping()}
+ * or {@link android.widget.ViewFlipper#stopFlipping()} along with
+ * {@link android.widget.ViewFlipper#setFlipInterval(int)}.
+ *
+ * @param viewId The id of the view to apply changes to
+ * @param flipping True means we should
+ * {@link android.widget.ViewFlipper#startFlipping()}, otherwise
+ * {@link android.widget.ViewFlipper#stopFlipping()}.
+ * @param milliseconds How long to wait before flipping to the next view, or
+ * -1 to leave unchanged.
+ */
+ public void setFlipping(int viewId, boolean flipping, int milliseconds) {
+ addAction(new SetFlipping(viewId, flipping, milliseconds));
+ }
+
+ /**
* Inflates the view hierarchy represented by this object and applies
* all of the actions.
*
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index d21c017..2ae5d4e 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3844,7 +3844,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
boolean doDown = true;
if (otherEvent != null) {
try {
- boolean handled = mMovement.onKeyOther(this, (Editable) mText,
+ boolean handled = mMovement.onKeyOther(this, (Spannable) mText,
otherEvent);
doDown = false;
if (handled) {
diff --git a/core/java/android/widget/ViewAnimator.java b/core/java/android/widget/ViewAnimator.java
index 8c652e5..fa8935e 100644
--- a/core/java/android/widget/ViewAnimator.java
+++ b/core/java/android/widget/ViewAnimator.java
@@ -28,6 +28,9 @@ import android.view.animation.AnimationUtils;
/**
* Base class for a {@link FrameLayout} container that will perform animations
* when switching between its views.
+ *
+ * @attr ref android.R.styleable#ViewAnimator_inAnimation
+ * @attr ref android.R.styleable#ViewAnimator_outAnimation
*/
public class ViewAnimator extends FrameLayout {
diff --git a/core/java/android/widget/ViewFlipper.java b/core/java/android/widget/ViewFlipper.java
index a3c15d9..e20bfdf 100644
--- a/core/java/android/widget/ViewFlipper.java
+++ b/core/java/android/widget/ViewFlipper.java
@@ -22,12 +22,16 @@ import android.content.res.TypedArray;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
+import android.widget.RemoteViews.RemoteView;
/**
* Simple {@link ViewAnimator} that will animate between two or more views
* that have been added to it. Only one child is shown at a time. If
* requested, can automatically flip between each child at a regular interval.
+ *
+ * @attr ref android.R.styleable#ViewFlipper_flipInterval
*/
+@RemoteView
public class ViewFlipper extends ViewAnimator {
private int mFlipInterval = 3000;
private boolean mKeepFlipping = false;
diff --git a/core/java/android/widget/ZoomButton.java b/core/java/android/widget/ZoomButton.java
index df3f307..0df919d 100644
--- a/core/java/android/widget/ZoomButton.java
+++ b/core/java/android/widget/ZoomButton.java
@@ -20,6 +20,7 @@ import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.GestureDetector;
+import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
@@ -57,6 +58,7 @@ public class ZoomButton extends ImageButton implements OnLongClickListener {
mGestureDetector = new GestureDetector(context, new SimpleOnGestureListener() {
@Override
public void onLongPress(MotionEvent e) {
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
onLongClick(ZoomButton.this);
}
});
diff --git a/core/java/android/widget/ZoomRing.java b/core/java/android/widget/ZoomRing.java
index 20d6056..be3b1fb 100644
--- a/core/java/android/widget/ZoomRing.java
+++ b/core/java/android/widget/ZoomRing.java
@@ -6,10 +6,9 @@ import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
-import android.os.Handler;
+import android.graphics.drawable.RotateDrawable;
import android.util.AttributeSet;
-import android.util.Log;
-import android.view.KeyEvent;
+import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
@@ -18,17 +17,20 @@ import android.view.ViewConfiguration;
* @hide
*/
public class ZoomRing extends View {
-
+
// TODO: move to ViewConfiguration?
- private static final int DOUBLE_TAP_DISMISS_TIMEOUT = ViewConfiguration.getJumpTapTimeout();
+ static final int DOUBLE_TAP_DISMISS_TIMEOUT = ViewConfiguration.getJumpTapTimeout();
// TODO: get from theme
private static final int DISABLED_ALPHA = 160;
-
+
private static final String TAG = "ZoomRing";
+ // TODO: Temporary until the trail is done
+ private static final boolean DRAW_TRAIL = false;
+
// TODO: xml
- private static final int THUMB_DISTANCE = 63;
-
+ private static final int THUMB_DISTANCE = 63;
+
/** To avoid floating point calculations, we multiply radians by this value. */
public static final int RADIAN_INT_MULTIPLIER = 100000000;
/** PI using our multiplier. */
@@ -36,68 +38,81 @@ public class ZoomRing extends View {
/** PI/2 using our multiplier. */
private static final int HALF_PI_INT_MULTIPLIED = PI_INT_MULTIPLIED / 2;
+ private int mZeroAngle = HALF_PI_INT_MULTIPLIED * 3;
+
private static final int THUMB_GRAB_SLOP = PI_INT_MULTIPLIED / 4;
-
+
/** The cached X of our center. */
private int mCenterX;
- /** The cached Y of our center. */
+ /** The cached Y of our center. */
private int mCenterY;
/** The angle of the thumb (in int radians) */
private int mThumbAngle;
private boolean mIsThumbAngleValid;
- private int mThumbCenterX;
- private int mThumbCenterY;
private int mThumbHalfWidth;
private int mThumbHalfHeight;
-
- private int mCallbackThreshold = Integer.MAX_VALUE;
-
- /** The accumulated amount of drag for the thumb (in int radians). */
- private int mAcculumalatedThumbDrag = 0;
-
+
/** The inner radius of the track. */
private int mBoundInnerRadiusSquared = 0;
/** The outer radius of the track. */
private int mBoundOuterRadiusSquared = Integer.MAX_VALUE;
-
+
private int mPreviousWidgetDragX;
private int mPreviousWidgetDragY;
-
+
private boolean mDrawThumb = true;
private Drawable mThumbDrawable;
-
+
private static final int MODE_IDLE = 0;
private static final int MODE_DRAG_THUMB = 1;
+ /**
+ * User has his finger down, but we are waiting for him to pass the touch
+ * slop before going into the #MODE_MOVE_ZOOM_RING. This is a good time to
+ * show the movable hint.
+ */
+ private static final int MODE_WAITING_FOR_MOVE_ZOOM_RING = 4;
private static final int MODE_MOVE_ZOOM_RING = 2;
private static final int MODE_TAP_DRAG = 3;
private int mMode;
- private long mPreviousTapTime;
-
- private Handler mHandler = new Handler();
-
+ private long mPreviousDownTime;
+ private int mPreviousDownX;
+ private int mPreviousDownY;
+
private Disabler mDisabler = new Disabler();
-
+
private OnZoomRingCallback mCallback;
-
+ private int mPreviousCallbackAngle;
+ private int mCallbackThreshold = Integer.MAX_VALUE;
+
private boolean mResetThumbAutomatically = true;
private int mThumbDragStartAngle;
-
+ private final int mTouchSlop;
+ private Drawable mTrail;
+ private double mAcculumalatedTrailAngle;
+
public ZoomRing(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- // TODO get drawable from style instead
+
+ ViewConfiguration viewConfiguration = ViewConfiguration.get(context);
+ mTouchSlop = viewConfiguration.getScaledTouchSlop();
+
+ // TODO get drawables from style instead
Resources res = context.getResources();
mThumbDrawable = res.getDrawable(R.drawable.zoom_ring_thumb);
-
+ if (DRAW_TRAIL) {
+ mTrail = res.getDrawable(R.drawable.zoom_ring_trail).mutate();
+ }
+
// TODO: add padding to drawable
setBackgroundResource(R.drawable.zoom_ring_track);
// TODO get from style
setBounds(30, Integer.MAX_VALUE);
-
+
mThumbHalfHeight = mThumbDrawable.getIntrinsicHeight() / 2;
mThumbHalfWidth = mThumbDrawable.getIntrinsicWidth() / 2;
-
+
mCallbackThreshold = PI_INT_MULTIPLIED / 6;
}
@@ -108,7 +123,7 @@ public class ZoomRing extends View {
public ZoomRing(Context context) {
this(context, null);
}
-
+
public void setCallback(OnZoomRingCallback callback) {
mCallback = callback;
}
@@ -132,26 +147,49 @@ public class ZoomRing extends View {
mBoundOuterRadiusSquared = Integer.MAX_VALUE;
}
}
-
+
public void setThumbAngle(int angle) {
mThumbAngle = angle;
- mThumbCenterX = (int) (Math.cos(1f * angle / RADIAN_INT_MULTIPLIER) * THUMB_DISTANCE)
- + mCenterX;
- mThumbCenterY = (int) (Math.sin(1f * angle / RADIAN_INT_MULTIPLIER) * THUMB_DISTANCE)
- * -1 + mCenterY;
+ int unoffsetAngle = angle + mZeroAngle;
+ int thumbCenterX = (int) (Math.cos(1f * unoffsetAngle / RADIAN_INT_MULTIPLIER) *
+ THUMB_DISTANCE) + mCenterX;
+ int thumbCenterY = (int) (Math.sin(1f * unoffsetAngle / RADIAN_INT_MULTIPLIER) *
+ THUMB_DISTANCE) * -1 + mCenterY;
+
+ mThumbDrawable.setBounds(thumbCenterX - mThumbHalfWidth,
+ thumbCenterY - mThumbHalfHeight,
+ thumbCenterX + mThumbHalfWidth,
+ thumbCenterY + mThumbHalfHeight);
+
+ if (DRAW_TRAIL) {
+ double degrees;
+ degrees = Math.min(359.0, Math.abs(mAcculumalatedTrailAngle));
+ int level = (int) (10000.0 * degrees / 360.0);
+
+ mTrail.setLevel((int) (10000.0 *
+ (-Math.toDegrees(angle / (double) RADIAN_INT_MULTIPLIER) -
+ degrees + 90) / 360.0));
+ ((RotateDrawable) mTrail).getDrawable().setLevel(level);
+ }
+
invalidate();
}
-
+
+ public void resetThumbAngle(int angle) {
+ mPreviousCallbackAngle = angle;
+ setThumbAngle(angle);
+ }
+
public void resetThumbAngle() {
if (mResetThumbAutomatically) {
- setThumbAngle(HALF_PI_INT_MULTIPLIED);
+ resetThumbAngle(0);
}
}
-
+
public void setResetThumbAutomatically(boolean resetThumbAutomatically) {
mResetThumbAutomatically = resetThumbAutomatically;
}
-
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec),
@@ -162,7 +200,7 @@ public class ZoomRing extends View {
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
super.onLayout(changed, left, top, right, bottom);
-
+
// Cache the center point
mCenterX = (right - left) / 2;
mCenterY = (bottom - top) / 2;
@@ -172,8 +210,12 @@ public class ZoomRing extends View {
if (mThumbAngle == Integer.MIN_VALUE) {
resetThumbAngle();
}
+
+ if (DRAW_TRAIL) {
+ mTrail.setBounds(0, 0, right - left, bottom - top);
+ }
}
-
+
@Override
public boolean onTouchEvent(MotionEvent event) {
return handleTouch(event.getAction(), event.getEventTime(),
@@ -184,61 +226,66 @@ public class ZoomRing extends View {
private void resetState() {
mMode = MODE_IDLE;
mPreviousWidgetDragX = mPreviousWidgetDragY = Integer.MIN_VALUE;
- mAcculumalatedThumbDrag = 0;
+ mAcculumalatedTrailAngle = 0.0;
mIsThumbAngleValid = false;
}
-
+
public void setTapDragMode(boolean tapDragMode, int x, int y) {
resetState();
mMode = tapDragMode ? MODE_TAP_DRAG : MODE_IDLE;
mIsThumbAngleValid = false;
-
+
if (tapDragMode && mCallback != null) {
onThumbDragStarted(getAngle(x - mCenterX, y - mCenterY));
}
}
-
+
public boolean handleTouch(int action, long time, int x, int y, int rawX, int rawY) {
switch (action) {
-
+
case MotionEvent.ACTION_DOWN:
- if (mPreviousTapTime + DOUBLE_TAP_DISMISS_TIMEOUT >= time) {
+ if (mPreviousDownTime + DOUBLE_TAP_DISMISS_TIMEOUT >= time) {
if (mCallback != null) {
mCallback.onZoomRingDismissed();
}
} else {
- mPreviousTapTime = time;
+ mPreviousDownTime = time;
+ mPreviousDownX = x;
+ mPreviousDownY = y;
}
resetState();
return true;
-
+
case MotionEvent.ACTION_MOVE:
// Fall through to code below switch
break;
-
+
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (mCallback != null) {
- if (mMode == MODE_MOVE_ZOOM_RING) {
- mCallback.onZoomRingMovingStopped();
+ if (mMode == MODE_MOVE_ZOOM_RING || mMode == MODE_WAITING_FOR_MOVE_ZOOM_RING) {
+ mCallback.onZoomRingSetMovableHintVisible(false);
+ if (mMode == MODE_MOVE_ZOOM_RING) {
+ mCallback.onZoomRingMovingStopped();
+ }
} else if (mMode == MODE_DRAG_THUMB || mMode == MODE_TAP_DRAG) {
onThumbDragStopped(getAngle(x - mCenterX, y - mCenterY));
}
}
mDisabler.setEnabling(true);
return true;
-
+
default:
return false;
}
-
+
// local{X,Y} will be where the center of the widget is (0,0)
int localX = x - mCenterX;
int localY = y - mCenterY;
boolean isTouchingThumb = true;
boolean isInBounds = true;
int touchAngle = getAngle(localX, localY);
-
+
int radiusSquared = localX * localX + localY * localY;
if (radiusSquared < mBoundInnerRadiusSquared ||
radiusSquared > mBoundOuterRadiusSquared) {
@@ -246,7 +293,7 @@ public class ZoomRing extends View {
isTouchingThumb = false;
isInBounds = false;
}
-
+
int deltaThumbAndTouch = getDelta(touchAngle, mThumbAngle);
int absoluteDeltaThumbAndTouch = deltaThumbAndTouch >= 0 ?
deltaThumbAndTouch : -deltaThumbAndTouch;
@@ -255,19 +302,35 @@ public class ZoomRing extends View {
// Didn't grab close enough to the thumb
isTouchingThumb = false;
}
-
+
if (mMode == MODE_IDLE) {
- mMode = isTouchingThumb ? MODE_DRAG_THUMB : MODE_MOVE_ZOOM_RING;
-
+ if (isTouchingThumb) {
+ mMode = MODE_DRAG_THUMB;
+ } else {
+ mMode = MODE_WAITING_FOR_MOVE_ZOOM_RING;
+ }
+
if (mCallback != null) {
if (mMode == MODE_DRAG_THUMB) {
onThumbDragStarted(touchAngle);
- } else if (mMode == MODE_MOVE_ZOOM_RING) {
+ } else if (mMode == MODE_WAITING_FOR_MOVE_ZOOM_RING) {
+ mCallback.onZoomRingSetMovableHintVisible(true);
+ }
+ }
+
+ } else if (mMode == MODE_WAITING_FOR_MOVE_ZOOM_RING) {
+ if (Math.abs(x - mPreviousDownX) > mTouchSlop ||
+ Math.abs(y - mPreviousDownY) > mTouchSlop) {
+ /* Make sure the user has moved the slop amount before going into that mode. */
+ mMode = MODE_MOVE_ZOOM_RING;
+
+ if (mCallback != null) {
mCallback.onZoomRingMovingStarted();
}
}
}
-
+
+ // Purposefully not an "else if"
if (mMode == MODE_DRAG_THUMB || mMode == MODE_TAP_DRAG) {
if (isInBounds) {
onThumbDragged(touchAngle, mIsThumbAngleValid ? deltaThumbAndTouch : 0);
@@ -277,13 +340,13 @@ public class ZoomRing extends View {
} else if (mMode == MODE_MOVE_ZOOM_RING) {
onZoomRingMoved(rawX, rawY);
}
-
+
return true;
}
-
+
private int getDelta(int angle1, int angle2) {
int delta = angle1 - angle2;
-
+
// Assume this is a result of crossing over the discontinuous 0 -> 2pi
if (delta > PI_INT_MULTIPLIED || delta < -PI_INT_MULTIPLIED) {
// Bring both the radians and previous angle onto a continuous range
@@ -295,7 +358,7 @@ public class ZoomRing extends View {
delta -= PI_INT_MULTIPLIED * 2;
}
}
-
+
return delta;
}
@@ -303,46 +366,69 @@ public class ZoomRing extends View {
mThumbDragStartAngle = startAngle;
mCallback.onZoomRingThumbDraggingStarted(startAngle);
}
-
+
private void onThumbDragged(int touchAngle, int deltaAngle) {
- mAcculumalatedThumbDrag += deltaAngle;
- if (mAcculumalatedThumbDrag > mCallbackThreshold
- || mAcculumalatedThumbDrag < -mCallbackThreshold) {
+ mAcculumalatedTrailAngle += Math.toDegrees(deltaAngle / (double) RADIAN_INT_MULTIPLIER);
+ int totalDeltaAngle = getDelta(touchAngle, mPreviousCallbackAngle);
+ if (totalDeltaAngle > mCallbackThreshold
+ || totalDeltaAngle < -mCallbackThreshold) {
if (mCallback != null) {
boolean canStillZoom = mCallback.onZoomRingThumbDragged(
- mAcculumalatedThumbDrag / mCallbackThreshold,
- mAcculumalatedThumbDrag, mThumbDragStartAngle, touchAngle);
+ totalDeltaAngle / mCallbackThreshold,
+ mThumbDragStartAngle, touchAngle);
mDisabler.setEnabling(canStillZoom);
+
+ if (canStillZoom) {
+ // TODO: we're trying the haptics to see how it goes with
+ // users, so we're ignoring the settings (for now)
+ performHapticFeedback(HapticFeedbackConstants.ZOOM_RING_TICK,
+ HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING |
+ HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
+ }
}
- mAcculumalatedThumbDrag = 0;
+
+ // Get the closest tick and lock on there
+ mPreviousCallbackAngle = getClosestTickAngle(touchAngle);
}
-
+
setThumbAngle(touchAngle);
mIsThumbAngleValid = true;
}
-
+
+ private int getClosestTickAngle(int angle) {
+ int smallerAngleDistance = angle % mCallbackThreshold;
+ int smallerAngle = angle - smallerAngleDistance;
+ if (smallerAngleDistance < mCallbackThreshold / 2) {
+ // Closer to the smaller angle
+ return smallerAngle;
+ } else {
+ // Closer to the bigger angle (premodding)
+ return (smallerAngle + mCallbackThreshold) % (PI_INT_MULTIPLIED * 2);
+ }
+ }
+
private void onThumbDragStopped(int stopAngle) {
mCallback.onZoomRingThumbDraggingStopped(stopAngle);
}
-
+
private void onZoomRingMoved(int x, int y) {
if (mPreviousWidgetDragX != Integer.MIN_VALUE) {
int deltaX = x - mPreviousWidgetDragX;
int deltaY = y - mPreviousWidgetDragY;
-
+
if (mCallback != null) {
mCallback.onZoomRingMoved(deltaX, deltaY);
}
}
-
+
mPreviousWidgetDragX = x;
mPreviousWidgetDragY = y;
}
-
+
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
-
+
if (!hasWindowFocus && mCallback != null) {
mCallback.onZoomRingDismissed();
}
@@ -353,22 +439,25 @@ public class ZoomRing extends View {
// Convert from [-pi,pi] to {0,2pi]
if (radians < 0) {
- return -radians;
+ radians = -radians;
} else if (radians > 0) {
- return 2 * PI_INT_MULTIPLIED - radians;
+ radians = 2 * PI_INT_MULTIPLIED - radians;
} else {
- return 0;
+ radians = 0;
}
+
+ radians = radians - mZeroAngle;
+ return radians >= 0 ? radians : radians + 2 * PI_INT_MULTIPLIED;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
-
+
if (mDrawThumb) {
- mThumbDrawable.setBounds(mThumbCenterX - mThumbHalfWidth, mThumbCenterY
- - mThumbHalfHeight, mThumbCenterX + mThumbHalfWidth, mThumbCenterY
- + mThumbHalfHeight);
+ if (DRAW_TRAIL) {
+ mTrail.draw(canvas);
+ }
mThumbDrawable.draw(canvas);
}
}
@@ -409,12 +498,14 @@ public class ZoomRing extends View {
}
public interface OnZoomRingCallback {
+ void onZoomRingSetMovableHintVisible(boolean visible);
+
void onZoomRingMovingStarted();
boolean onZoomRingMoved(int deltaX, int deltaY);
void onZoomRingMovingStopped();
void onZoomRingThumbDraggingStarted(int startAngle);
- boolean onZoomRingThumbDragged(int numLevels, int dragAmount, int startAngle, int curAngle);
+ boolean onZoomRingThumbDragged(int numLevels, int startAngle, int curAngle);
void onZoomRingThumbDraggingStopped(int endAngle);
void onZoomRingDismissed();
diff --git a/core/java/android/widget/ZoomRingController.java b/core/java/android/widget/ZoomRingController.java
index 2ca0374..eb28767 100644
--- a/core/java/android/widget/ZoomRingController.java
+++ b/core/java/android/widget/ZoomRingController.java
@@ -17,14 +17,17 @@
package android.widget;
import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.SharedPreferences;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
+import android.os.Vibrator;
import android.provider.Settings;
import android.util.Log;
import android.view.Gravity;
@@ -42,6 +45,7 @@ import android.view.animation.DecelerateInterpolator;
/**
* TODO: Docs
+ *
* @hide
*/
public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
@@ -222,7 +226,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
public ZoomRingController(Context context, View ownerView) {
mContext = context;
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
-
+
mOwnerView = ownerView;
mZoomRing = new ZoomRing(context);
@@ -437,7 +441,15 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
case MotionEvent.ACTION_UP:
mTouchMode = TOUCH_MODE_IDLE;
+
+ /*
+ * This is a power-user feature that only shows the
+ * zoom while the user is performing the tap-drag.
+ * That means once it is released, the zoom ring
+ * should disappear.
+ */
mZoomRing.setTapDragMode(false, (int) event.getX(), (int) event.getY());
+ dismissZoomRingDelayed(0);
break;
}
break;
@@ -560,10 +572,13 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
mZoomRing.handleTouch(event.getAction(), event.getEventTime(), x, y, rawX, rawY);
}
+ public void onZoomRingSetMovableHintVisible(boolean visible) {
+ setPanningArrowsVisible(visible);
+ }
+
public void onZoomRingMovingStarted() {
mHandler.removeMessages(MSG_DISMISS_ZOOM_RING);
mScroller.abortAnimation();
- setPanningArrowsVisible(true);
}
private void setPanningArrowsVisible(boolean visible) {
@@ -641,8 +656,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
}
}
- public boolean onZoomRingThumbDragged(int numLevels, int dragAmount, int startAngle,
- int curAngle) {
+ public boolean onZoomRingThumbDragged(int numLevels, int startAngle, int curAngle) {
if (mCallback != null) {
int deltaZoomLevel = -numLevels;
int globalZoomCenterX = mContainerLayoutParams.x + mZoomRing.getLeft() +
@@ -650,7 +664,8 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
int globalZoomCenterY = mContainerLayoutParams.y + mZoomRing.getTop() +
mZoomRingHeight / 2;
- return mCallback.onDragZoom(deltaZoomLevel, globalZoomCenterX - mOwnerViewBounds.left,
+ return mCallback.onDragZoom(deltaZoomLevel,
+ globalZoomCenterX - mOwnerViewBounds.left,
globalZoomCenterY - mOwnerViewBounds.top,
(float) startAngle / ZoomRing.RADIAN_INT_MULTIPLIER,
(float) curAngle / ZoomRing.RADIAN_INT_MULTIPLIER);
@@ -719,6 +734,45 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
ensureZoomRingIsCentered();
}
+ /**
+ * Shows a "tutorial" (some text) to the user teaching her the new zoom
+ * invocation method.
+ * <p>
+ * It checks the global system setting to ensure this has not been seen
+ * before. Furthermore, if the application does not have privilege to write
+ * to the system settings, it will store this bit locally in a shared
+ * preference.
+ *
+ * @hide This should only be used by our main apps--browser, maps, and
+ * gallery
+ */
+ public static void showZoomTutorialOnce(Context context) {
+ ContentResolver cr = context.getContentResolver();
+ if (Settings.System.getInt(cr, SETTING_NAME_SHOWN_TOAST, 0) == 1) {
+ return;
+ }
+
+ SharedPreferences sp = context.getSharedPreferences("_zoom", Context.MODE_PRIVATE);
+ if (sp.getInt(SETTING_NAME_SHOWN_TOAST, 0) == 1) {
+ return;
+ }
+
+ try {
+ Settings.System.putInt(cr, SETTING_NAME_SHOWN_TOAST, 1);
+ } catch (SecurityException e) {
+ /*
+ * The app does not have permission to clear this global flag, make
+ * sure the user does not see the message when he comes back to this
+ * same app at least.
+ */
+ sp.edit().putInt(SETTING_NAME_SHOWN_TOAST, 1).commit();
+ }
+
+ Toast.makeText(context,
+ com.android.internal.R.string.tutorial_double_tap_to_zoom_message_short,
+ Toast.LENGTH_LONG).show();
+ }
+
private class Panner implements Runnable {
private static final int RUN_DELAY = 15;
private static final float STOP_SLOWDOWN = 0.8f;
diff --git a/core/java/com/android/internal/gadget/IGadgetHost.aidl b/core/java/com/android/internal/gadget/IGadgetHost.aidl
index a5b8654..e7b5a1e 100644
--- a/core/java/com/android/internal/gadget/IGadgetHost.aidl
+++ b/core/java/com/android/internal/gadget/IGadgetHost.aidl
@@ -17,11 +17,12 @@
package com.android.internal.gadget;
import android.content.ComponentName;
-import android.gadget.GadgetInfo;
+import android.gadget.GadgetProviderInfo;
import android.widget.RemoteViews;
/** {@hide} */
oneway interface IGadgetHost {
void updateGadget(int gadgetId, in RemoteViews views);
+ void providerChanged(int gadgetId, in GadgetProviderInfo info);
}
diff --git a/core/java/com/android/internal/gadget/IGadgetService.aidl b/core/java/com/android/internal/gadget/IGadgetService.aidl
index 1b3946f..a22f3f3 100644
--- a/core/java/com/android/internal/gadget/IGadgetService.aidl
+++ b/core/java/com/android/internal/gadget/IGadgetService.aidl
@@ -17,7 +17,7 @@
package com.android.internal.gadget;
import android.content.ComponentName;
-import android.gadget.GadgetInfo;
+import android.gadget.GadgetProviderInfo;
import com.android.internal.gadget.IGadgetHost;
import android.widget.RemoteViews;
@@ -41,8 +41,8 @@ interface IGadgetService {
//
void updateGadgetIds(in int[] gadgetIds, in RemoteViews views);
void updateGadgetProvider(in ComponentName provider, in RemoteViews views);
- List<GadgetInfo> getInstalledProviders();
- GadgetInfo getGadgetInfo(int gadgetId);
+ List<GadgetProviderInfo> getInstalledProviders();
+ GadgetProviderInfo getGadgetInfo(int gadgetId);
void bindGadgetId(int gadgetId, in ComponentName provider);
}
diff --git a/core/java/com/android/internal/view/IInputConnectionWrapper.java b/core/java/com/android/internal/view/IInputConnectionWrapper.java
index b0b00b2..ac72a20 100644
--- a/core/java/com/android/internal/view/IInputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/IInputConnectionWrapper.java
@@ -32,8 +32,7 @@ public class IInputConnectionWrapper extends IInputContext.Stub {
private static final int DO_DELETE_SURROUNDING_TEXT = 80;
private static final int DO_BEGIN_BATCH_EDIT = 90;
private static final int DO_END_BATCH_EDIT = 95;
- private static final int DO_HIDE_STATUS_ICON = 100;
- private static final int DO_SHOW_STATUS_ICON = 110;
+ private static final int DO_REPORT_FULLSCREEN_MODE = 100;
private static final int DO_PERFORM_PRIVATE_COMMAND = 120;
private static final int DO_CLEAR_META_KEY_STATES = 130;
@@ -133,12 +132,8 @@ public class IInputConnectionWrapper extends IInputContext.Stub {
dispatchMessage(obtainMessage(DO_END_BATCH_EDIT));
}
- public void hideStatusIcon() {
- dispatchMessage(obtainMessage(DO_HIDE_STATUS_ICON));
- }
-
- public void showStatusIcon(String packageName, int resId) {
- dispatchMessage(obtainMessageIO(DO_SHOW_STATUS_ICON, resId, packageName));
+ public void reportFullscreenMode(boolean enabled) {
+ dispatchMessage(obtainMessageII(DO_REPORT_FULLSCREEN_MODE, enabled ? 1 : 0, 0));
}
public void performPrivateCommand(String action, Bundle data) {
@@ -323,22 +318,13 @@ public class IInputConnectionWrapper extends IInputContext.Stub {
ic.endBatchEdit();
return;
}
- case DO_HIDE_STATUS_ICON: {
- InputConnection ic = mInputConnection.get();
- if (ic == null || !isActive()) {
- Log.w(TAG, "hideStatusIcon on inactive InputConnection");
- return;
- }
- ic.hideStatusIcon();
- return;
- }
- case DO_SHOW_STATUS_ICON: {
+ case DO_REPORT_FULLSCREEN_MODE: {
InputConnection ic = mInputConnection.get();
if (ic == null || !isActive()) {
Log.w(TAG, "showStatusIcon on inactive InputConnection");
return;
}
- ic.showStatusIcon((String)msg.obj, msg.arg1);
+ ic.reportFullscreenMode(msg.arg1 != 1);
return;
}
case DO_PERFORM_PRIVATE_COMMAND: {
diff --git a/core/java/com/android/internal/view/IInputContext.aidl b/core/java/com/android/internal/view/IInputContext.aidl
index 7cc8ada..02b6044 100644
--- a/core/java/com/android/internal/view/IInputContext.aidl
+++ b/core/java/com/android/internal/view/IInputContext.aidl
@@ -56,13 +56,11 @@ import com.android.internal.view.IInputContextCallback;
void endBatchEdit();
+ void reportFullscreenMode(boolean enabled);
+
void sendKeyEvent(in KeyEvent event);
void clearMetaKeyStates(int states);
void performPrivateCommand(String action, in Bundle data);
-
- void showStatusIcon(String packageName, int resId);
-
- void hideStatusIcon();
}
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 2f5cd14..1b1c7f7 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -47,7 +47,7 @@ interface IInputMethodManager {
void showInputMethodPickerFromClient(in IInputMethodClient client);
void setInputMethod(in IBinder token, String id);
void hideMySoftInput(in IBinder token, int flags);
- void updateStatusIcon(int iconId, String iconPackage);
+ void updateStatusIcon(in IBinder token, String packageName, int iconId);
boolean setInputMethodEnabled(String id, boolean enabled);
}
diff --git a/core/java/com/android/internal/view/InputConnectionWrapper.java b/core/java/com/android/internal/view/InputConnectionWrapper.java
index af4ad25..32d9f3d 100644
--- a/core/java/com/android/internal/view/InputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/InputConnectionWrapper.java
@@ -322,18 +322,9 @@ public class InputConnectionWrapper implements InputConnection {
}
}
- public boolean hideStatusIcon() {
+ public boolean reportFullscreenMode(boolean enabled) {
try {
- mIInputContext.showStatusIcon(null, 0);
- return true;
- } catch (RemoteException e) {
- return false;
- }
- }
-
- public boolean showStatusIcon(String packageName, int resId) {
- try {
- mIInputContext.showStatusIcon(packageName, resId);
+ mIInputContext.reportFullscreenMode(enabled);
return true;
} catch (RemoteException e) {
return false;
diff --git a/core/java/com/android/internal/widget/NumberPicker.java b/core/java/com/android/internal/widget/NumberPicker.java
index 20ea6a6..1647c20 100644
--- a/core/java/com/android/internal/widget/NumberPicker.java
+++ b/core/java/com/android/internal/widget/NumberPicker.java
@@ -28,12 +28,8 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.View.OnLongClickListener;
-import android.view.animation.Animation;
-import android.view.animation.TranslateAnimation;
-import android.widget.EditText;
-import android.widget.LinearLayout;
import android.widget.TextView;
-import android.widget.ViewSwitcher;
+import android.widget.LinearLayout;
import com.android.internal.R;
@@ -71,25 +67,18 @@ public class NumberPicker extends LinearLayout implements OnClickListener,
private final Runnable mRunnable = new Runnable() {
public void run() {
if (mIncrement) {
- changeCurrent(mCurrent + 1, mSlideUpInAnimation, mSlideUpOutAnimation);
+ changeCurrent(mCurrent + 1);
mHandler.postDelayed(this, mSpeed);
} else if (mDecrement) {
- changeCurrent(mCurrent - 1, mSlideDownInAnimation, mSlideDownOutAnimation);
+ changeCurrent(mCurrent - 1);
mHandler.postDelayed(this, mSpeed);
}
}
};
-
- private final LayoutInflater mInflater;
+
private final TextView mText;
- private final InputFilter mInputFilter;
private final InputFilter mNumberInputFilter;
-
- private final Animation mSlideUpOutAnimation;
- private final Animation mSlideUpInAnimation;
- private final Animation mSlideDownOutAnimation;
- private final Animation mSlideDownInAnimation;
-
+
private String[] mDisplayedValues;
private int mStart;
private int mEnd;
@@ -110,14 +99,14 @@ public class NumberPicker extends LinearLayout implements OnClickListener,
this(context, attrs, 0);
}
- public NumberPicker(Context context, AttributeSet attrs,
- int defStyle) {
+ @SuppressWarnings({"UnusedDeclaration"})
+ public NumberPicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs);
setOrientation(VERTICAL);
- mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mInflater.inflate(R.layout.number_picker, this, true);
+ LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ inflater.inflate(R.layout.number_picker, this, true);
mHandler = new Handler();
- mInputFilter = new NumberPickerInputFilter();
+ InputFilter inputFilter = new NumberPickerInputFilter();
mNumberInputFilter = new NumberRangeKeyListener();
mIncrementButton = (NumberPickerButton) findViewById(R.id.increment);
mIncrementButton.setOnClickListener(this);
@@ -130,30 +119,9 @@ public class NumberPicker extends LinearLayout implements OnClickListener,
mText = (TextView) findViewById(R.id.timepicker_input);
mText.setOnFocusChangeListener(this);
- mText.setFilters(new InputFilter[] { mInputFilter });
+ mText.setFilters(new InputFilter[] {inputFilter});
mText.setRawInputType(InputType.TYPE_CLASS_NUMBER);
-
- mSlideUpOutAnimation = new TranslateAnimation(
- Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF,
- 0, Animation.RELATIVE_TO_SELF, 0,
- Animation.RELATIVE_TO_SELF, -100);
- mSlideUpOutAnimation.setDuration(200);
- mSlideUpInAnimation = new TranslateAnimation(
- Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF,
- 0, Animation.RELATIVE_TO_SELF, 100,
- Animation.RELATIVE_TO_SELF, 0);
- mSlideUpInAnimation.setDuration(200);
- mSlideDownOutAnimation = new TranslateAnimation(
- Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF,
- 0, Animation.RELATIVE_TO_SELF, 0,
- Animation.RELATIVE_TO_SELF, 100);
- mSlideDownOutAnimation.setDuration(200);
- mSlideDownInAnimation = new TranslateAnimation(
- Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF,
- 0, Animation.RELATIVE_TO_SELF, -100,
- Animation.RELATIVE_TO_SELF, 0);
- mSlideDownInAnimation.setDuration(200);
-
+
if (!isEnabled()) {
setEnabled(false);
}
@@ -228,9 +196,9 @@ public class NumberPicker extends LinearLayout implements OnClickListener,
// now perform the increment/decrement
if (R.id.increment == v.getId()) {
- changeCurrent(mCurrent + 1, mSlideUpInAnimation, mSlideUpOutAnimation);
+ changeCurrent(mCurrent + 1);
} else if (R.id.decrement == v.getId()) {
- changeCurrent(mCurrent - 1, mSlideDownInAnimation, mSlideDownOutAnimation);
+ changeCurrent(mCurrent - 1);
}
}
@@ -240,7 +208,7 @@ public class NumberPicker extends LinearLayout implements OnClickListener,
: String.valueOf(value);
}
- private void changeCurrent(int current, Animation in, Animation out) {
+ private void changeCurrent(int current) {
// Wrap around the values if we go past the start or end
if (current > mEnd) {
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index 307c6fd..288433a 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -267,7 +267,7 @@ static void android_media_AudioRecord_finalize(JNIEnv *env, jobject thiz) {
(AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
if (lpRecorder) {
- //LOGV("About to delete lpRecorder: %x\n", (int)lpRecorder);
+ LOGV("About to delete lpRecorder: %x\n", (int)lpRecorder);
lpRecorder->stop();
delete lpRecorder;
}
@@ -449,6 +449,39 @@ static jint android_media_AudioRecord_get_pos_update_period(JNIEnv *env, jobjec
// ----------------------------------------------------------------------------
+// returns the minimum required size for the successful creation of an AudioRecord instance.
+// returns 0 if the parameter combination is not supported.
+// return -1 if there was an error querying the buffer size.
+static jint android_media_AudioRecord_get_min_buff_size(JNIEnv *env, jobject thiz,
+ jint sampleRateInHertz, jint nbChannels, jint audioFormat) {
+
+ size_t inputBuffSize = 0;
+ LOGV(">> android_media_AudioRecord_get_min_buff_size(%d, %d, %d)", sampleRateInHertz, nbChannels, audioFormat);
+
+ status_t result = AudioSystem::getInputBufferSize(
+ sampleRateInHertz,
+ (audioFormat == javaAudioRecordFields.PCM16 ?
+ AudioSystem::PCM_16_BIT : AudioSystem::PCM_8_BIT),
+ nbChannels, &inputBuffSize);
+ switch(result) {
+ case(NO_ERROR):
+ if(inputBuffSize == 0) {
+ LOGV("Recording parameters are not supported: %dHz, %d channel(s), (java) format %d",
+ sampleRateInHertz, nbChannels, audioFormat);
+ return 0;
+ } else {
+ // the minimum buffer size is twice the hardware input buffer size
+ return 2*inputBuffSize;
+ }
+ break;
+ case(PERMISSION_DENIED):
+ default:
+ return -1;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
static JNINativeMethod gMethods[] = {
// name, signature, funcPtr
@@ -470,6 +503,8 @@ static JNINativeMethod gMethods[] = {
"(I)I", (void *)android_media_AudioRecord_set_pos_update_period},
{"native_get_pos_update_period",
"()I", (void *)android_media_AudioRecord_get_pos_update_period},
+ {"native_get_min_buff_size",
+ "(III)I", (void *)android_media_AudioRecord_get_min_buff_size},
};
// field names found in android/media/AudioRecord.java
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 6bd3655..692610e 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -53,13 +53,8 @@ static int
android_media_AudioSystem_setVolume(JNIEnv *env, jobject clazz, jint type, jint volume)
{
LOGV("setVolume(%d)", int(volume));
- if (int(type) == AudioTrack::VOICE_CALL) {
- return check_AudioSystem_Command(AudioSystem::setStreamVolume(type, float(volume) / 100.0));
- } else if (int(type) == AudioTrack::BLUETOOTH_SCO) {
- return check_AudioSystem_Command(AudioSystem::setStreamVolume(type, float(1.0)));
- } else {
- return check_AudioSystem_Command(AudioSystem::setStreamVolume(type, AudioSystem::linearToLog(volume)));
- }
+
+ return check_AudioSystem_Command(AudioSystem::setStreamVolume(type, AudioSystem::linearToLog(volume)));
}
static int
@@ -68,12 +63,7 @@ android_media_AudioSystem_getVolume(JNIEnv *env, jobject clazz, jint type)
float v;
int v_int = -1;
if (AudioSystem::getStreamVolume(int(type), &v) == NO_ERROR) {
- // voice call volume is converted to log scale in the hardware
- if (int(type) == AudioTrack::VOICE_CALL) {
- v_int = lrint(v * 100.0);
- } else {
- v_int = AudioSystem::logToLinear(v);
- }
+ v_int = AudioSystem::logToLinear(v);
}
return v_int;
}
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index bbecc1b..6ca821d 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -72,6 +72,7 @@ class AudioTrackJniStorage {
sp<MemoryHeapBase> mMemHeap;
sp<MemoryBase> mMemBase;
audiotrack_callback_cookie mCallbackData;
+ int mStreamType;
AudioTrackJniStorage() {
}
@@ -168,11 +169,11 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th
int afSampleRate;
int afFrameCount;
- if (AudioSystem::getOutputFrameCount(&afFrameCount) != NO_ERROR) {
+ if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) {
LOGE("Error creating AudioTrack: Could not get AudioSystem frame count.");
return AUDIOTRACK_ERROR_SETUP_AUDIOSYSTEM;
}
- if (AudioSystem::getOutputSamplingRate(&afSampleRate) != NO_ERROR) {
+ if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
LOGE("Error creating AudioTrack: Could not get AudioSystem sampling rate.");
return AUDIOTRACK_ERROR_SETUP_AUDIOSYSTEM;
}
@@ -183,21 +184,21 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th
}
// check the stream type
- AudioTrack::stream_type atStreamType;
+ AudioSystem::stream_type atStreamType;
if (streamType == javaAudioTrackFields.STREAM_VOICE_CALL) {
- atStreamType = AudioTrack::VOICE_CALL;
+ atStreamType = AudioSystem::VOICE_CALL;
} else if (streamType == javaAudioTrackFields.STREAM_SYSTEM) {
- atStreamType = AudioTrack::SYSTEM;
+ atStreamType = AudioSystem::SYSTEM;
} else if (streamType == javaAudioTrackFields.STREAM_RING) {
- atStreamType = AudioTrack::RING;
+ atStreamType = AudioSystem::RING;
} else if (streamType == javaAudioTrackFields.STREAM_MUSIC) {
- atStreamType = AudioTrack::MUSIC;
+ atStreamType = AudioSystem::MUSIC;
} else if (streamType == javaAudioTrackFields.STREAM_ALARM) {
- atStreamType = AudioTrack::ALARM;
+ atStreamType = AudioSystem::ALARM;
} else if (streamType == javaAudioTrackFields.STREAM_NOTIFICATION) {
- atStreamType = AudioTrack::NOTIFICATION;
+ atStreamType = AudioSystem::NOTIFICATION;
} else if (streamType == javaAudioTrackFields.STREAM_BLUETOOTH_SCO) {
- atStreamType = AudioTrack::BLUETOOTH_SCO;
+ atStreamType = AudioSystem::BLUETOOTH_SCO;
} else {
LOGE("Error creating AudioTrack: unknown stream type.");
return AUDIOTRACK_ERROR_SETUP_INVALIDSTREAMTYPE;
@@ -238,6 +239,8 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th
// we use a weak reference so the AudioTrack object can be garbage collected.
lpJniStorage->mCallbackData.audioTrack_ref = env->NewGlobalRef(weak_this);
+ lpJniStorage->mStreamType = atStreamType;
+
// create the native AudioTrack object
AudioTrack* lpTrack = new AudioTrack();
if (lpTrack == NULL) {
@@ -656,8 +659,14 @@ static jint android_media_AudioTrack_reload(JNIEnv *env, jobject thiz) {
// ----------------------------------------------------------------------------
static jint android_media_AudioTrack_get_output_sample_rate(JNIEnv *env, jobject thiz) {
- int afSamplingRate;
- if (AudioSystem::getOutputSamplingRate(&afSamplingRate) != NO_ERROR) {
+ int afSamplingRate;
+ AudioTrackJniStorage* lpJniStorage = (AudioTrackJniStorage *)env->GetIntField(
+ thiz, javaAudioTrackFields.jniData);
+ if (lpJniStorage == NULL) {
+ return DEFAULT_OUTPUT_SAMPLE_RATE;
+ }
+
+ if (AudioSystem::getOutputSamplingRate(&afSamplingRate, lpJniStorage->mStreamType) != NO_ERROR) {
return DEFAULT_OUTPUT_SAMPLE_RATE;
} else {
return afSamplingRate;
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index 75a0fbe..e5ae2ea 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -751,6 +751,10 @@ void onCreateBondingResult(DBusMessage *msg, void *user) {
// Other device is not responding at all
LOGV("... error = %s (%s)\n", err.name, err.message);
result = BOND_RESULT_REMOTE_DEVICE_DOWN;
+ } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AlreadyExists")) {
+ // already bonded
+ LOGV("... error = %s (%s)\n", err.name, err.message);
+ result = BOND_RESULT_SUCCESS;
} else {
LOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message);
result = BOND_RESULT_ERROR;
diff --git a/core/jni/android_util_EventLog.cpp b/core/jni/android_util_EventLog.cpp
index d0cac18..5e5103a 100644
--- a/core/jni/android_util_EventLog.cpp
+++ b/core/jni/android_util_EventLog.cpp
@@ -19,7 +19,7 @@
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include "jni.h"
-#include "utils/logger.h"
+#include "cutils/logger.h"
#define END_DELIMITER '\n'
#define INT_BUFFER_SIZE (sizeof(jbyte)+sizeof(jint)+sizeof(END_DELIMITER))
diff --git a/core/res/res/drawable/presence_away.png b/core/res/res/drawable/presence_away.png
index a539ec7..f8120df 100644
--- a/core/res/res/drawable/presence_away.png
+++ b/core/res/res/drawable/presence_away.png
Binary files differ
diff --git a/core/res/res/drawable/presence_busy.png b/core/res/res/drawable/presence_busy.png
index 1e3f547..9d7620b 100644
--- a/core/res/res/drawable/presence_busy.png
+++ b/core/res/res/drawable/presence_busy.png
Binary files differ
diff --git a/core/res/res/drawable/presence_invisible.png b/core/res/res/drawable/presence_invisible.png
index fb86cf1..21399a4 100644
--- a/core/res/res/drawable/presence_invisible.png
+++ b/core/res/res/drawable/presence_invisible.png
Binary files differ
diff --git a/core/res/res/drawable/presence_offline.png b/core/res/res/drawable/presence_offline.png
index da54fe7..3941b82 100644
--- a/core/res/res/drawable/presence_offline.png
+++ b/core/res/res/drawable/presence_offline.png
Binary files differ
diff --git a/core/res/res/drawable/presence_online.png b/core/res/res/drawable/presence_online.png
index 879a762..22d5683 100644
--- a/core/res/res/drawable/presence_online.png
+++ b/core/res/res/drawable/presence_online.png
Binary files differ
diff --git a/core/res/res/drawable/zoom_ring_trail.xml b/core/res/res/drawable/zoom_ring_trail.xml
new file mode 100644
index 0000000..08931ac
--- /dev/null
+++ b/core/res/res/drawable/zoom_ring_trail.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<rotate xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:fromDegrees="0"
+ android:toDegrees="360">
+
+ <shape
+ android:shape="ring"
+ android:innerRadius="60dip"
+ android:thickness="14dip"
+ android:useLevel="true">
+
+ <gradient
+ android:type="sweep"
+ android:useLevel="true"
+ android:startColor="#1000ceff"
+ android:endColor="#ffadd252" />
+
+ </shape>
+
+ </rotate>
diff --git a/core/res/res/layout/date_picker.xml b/core/res/res/layout/date_picker.xml
index a398bd0..0760cc0 100644
--- a/core/res/res/layout/date_picker.xml
+++ b/core/res/res/layout/date_picker.xml
@@ -24,6 +24,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/parent"
android:orientation="horizontal"
+ android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
diff --git a/core/res/res/layout/date_picker_dialog.xml b/core/res/res/layout/date_picker_dialog.xml
index 879f339..949c8a3 100644
--- a/core/res/res/layout/date_picker_dialog.xml
+++ b/core/res/res/layout/date_picker_dialog.xml
@@ -17,11 +17,9 @@
*/
-->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:padding="5dip">
- <DatePicker android:id="@+id/datePicker"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"/>
-</FrameLayout>
+<DatePicker xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/datePicker"
+ android:padding="5dip"
+ android:layout_gravity="center_horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
diff --git a/core/res/res/layout/number_picker.xml b/core/res/res/layout/number_picker.xml
index 422733a..bbdb31c 100644
--- a/core/res/res/layout/number_picker.xml
+++ b/core/res/res/layout/number_picker.xml
@@ -22,23 +22,21 @@
<com.android.internal.widget.NumberPickerButton android:id="@+id/increment"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:background="@drawable/timepicker_up_btn"
- />
-
- <EditText android:id="@+id/timepicker_input"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:singleLine="true"
- style="?android:attr/textAppearanceLargeInverse"
- android:textSize="30sp"
- android:background="@drawable/timepicker_input"
- />
-
+ android:background="@drawable/timepicker_up_btn" />
+
+ <EditText android:id="@+id/timepicker_input"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:singleLine="true"
+ style="?android:attr/textAppearanceLargeInverse"
+ android:textColor="@android:color/primary_text_light"
+ android:textSize="30sp"
+ android:background="@drawable/timepicker_input" />
+
<com.android.internal.widget.NumberPickerButton android:id="@+id/decrement"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:background="@drawable/timepicker_down_btn"
- />
-
+ android:background="@drawable/timepicker_down_btn" />
+
</merge>
diff --git a/core/res/res/layout/number_picker_edit.xml b/core/res/res/layout/number_picker_edit.xml
index 46f4845..f3af6e9 100644
--- a/core/res/res/layout/number_picker_edit.xml
+++ b/core/res/res/layout/number_picker_edit.xml
@@ -23,6 +23,7 @@
android:gravity="center_horizontal"
android:singleLine="true"
style="?android:attr/textAppearanceLargeInverse"
+ android:textColor="@android:color/primary_text_light"
android:textSize="30sp"
android:background="@drawable/timepicker_input"
/>
diff --git a/core/res/res/layout/time_picker.xml b/core/res/res/layout/time_picker.xml
index bdfe490..c601e0e 100644
--- a/core/res/res/layout/time_picker.xml
+++ b/core/res/res/layout/time_picker.xml
@@ -21,6 +21,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
+ android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
@@ -55,5 +56,6 @@
android:paddingLeft="20dip"
android:paddingRight="20dip"
style="?android:attr/textAppearanceLargeInverse"
+ android:textColor="@android:color/primary_text_light_nodisable"
/>
</LinearLayout>
diff --git a/core/res/res/layout/time_picker_dialog.xml b/core/res/res/layout/time_picker_dialog.xml
index 6dc1bf6..d5a6b5e 100644
--- a/core/res/res/layout/time_picker_dialog.xml
+++ b/core/res/res/layout/time_picker_dialog.xml
@@ -17,11 +17,9 @@
*/
-->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:padding="5dip">
- <TimePicker android:id="@+id/timePicker"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"/>
-</FrameLayout>
+<TimePicker xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/timePicker"
+ android:layout_gravity="center_horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="5dip" />
diff --git a/core/res/res/layout/time_picker_text.xml b/core/res/res/layout/time_picker_text.xml
deleted file mode 100644
index bad980b..0000000
--- a/core/res/res/layout/time_picker_text.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<!-- TextView of time picker-->
-
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:textAppearance="?attr/textAppearanceLargeInverse"
- android:gravity="center"
- />
diff --git a/core/res/res/values-cs-rCZ/strings.xml b/core/res/res/values-cs-rCZ/strings.xml
deleted file mode 100644
index e1eb3f4..0000000
--- a/core/res/res/values-cs-rCZ/strings.xml
+++ /dev/null
@@ -1,1112 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for byteShort (2850097084724465606) -->
- <skip />
- <!-- no translation found for kilobyteShort (5865542430193761682) -->
- <skip />
- <!-- no translation found for megabyteShort (112984851085937882) -->
- <skip />
- <!-- no translation found for gigabyteShort (8586075069559273847) -->
- <skip />
- <!-- no translation found for terabyteShort (5828502357595687794) -->
- <skip />
- <!-- no translation found for petabyteShort (7523248732657962413) -->
- <skip />
- <string name="untitled">"&lt;bez názvu&gt;"</string>
- <string name="ellipsis">"…"</string>
- <string name="emptyPhoneNumber">"(žádné telefonní číslo)"</string>
- <string name="unknownName">"(neznámý)"</string>
- <string name="defaultVoiceMailAlphaTag">"Hlasová schránka"</string>
- <string name="defaultMsisdnAlphaTag">"Msisdn1"</string>
- <string name="mmiError">"Chyba sítě nebo neplatný kód MMI."</string>
- <string name="serviceEnabled">"Služba povolena"</string>
- <string name="serviceEnabledFor">"Služba povolena pro:"</string>
- <string name="serviceDisabled">"Služba zakázána"</string>
- <string name="serviceRegistered">"Registrace úspěšná"</string>
- <string name="serviceErased">"Odstranění úspěšné"</string>
- <string name="passwordIncorrect">"Nesprávné heslo."</string>
- <string name="mmiComplete">"MMI dokončeno"</string>
- <!-- no translation found for badPin (5103184589972647739) -->
- <skip />
- <!-- no translation found for badPuk (2200634943393540609) -->
- <skip />
- <!-- no translation found for mismatchPin (5055729703806180857) -->
- <skip />
- <!-- no translation found for invalidPin (6201854814319326475) -->
- <skip />
- <!-- no translation found for needPuk (4788728144863892764) -->
- <skip />
- <!-- no translation found for needPuk2 (7056908944942451033) -->
- <skip />
- <!-- no translation found for ClipMmi (5649729434121615509) -->
- <skip />
- <!-- no translation found for ClirMmi (5220979296096544477) -->
- <skip />
- <!-- no translation found for CfMmi (4998483717856803914) -->
- <skip />
- <!-- no translation found for CwMmi (5678103638951836350) -->
- <skip />
- <!-- no translation found for BaMmi (6030555200442855833) -->
- <skip />
- <!-- no translation found for PwdMmi (2549941247959366670) -->
- <skip />
- <!-- no translation found for PinMmi (2463353963837922189) -->
- <skip />
- <string name="CLIRDefaultOnNextCallOn">"Výchozí nastavení omezení ID - omezení. Další hovor: omezení"</string>
- <string name="CLIRDefaultOnNextCallOff">"Výchozí nastavení omezení ID - omezení. Další hovor: bez omezení"</string>
- <string name="CLIRDefaultOffNextCallOn">"Výchozí nastavení omezení ID - bez omezení. Další hovor: omezení"</string>
- <string name="CLIRDefaultOffNextCallOff">"Výchozí nastavení omezení ID - bez omezení. Další hovor: bez omezení"</string>
- <string name="serviceNotProvisioned">"Služba není poskytována."</string>
- <string name="CLIRPermanent">"Omezení ID v trvalém režimu."</string>
- <string name="serviceClassVoice">"Hlasový záznam"</string>
- <string name="serviceClassData">"Data"</string>
- <string name="serviceClassFAX">"FAX"</string>
- <string name="serviceClassSMS">"SMS"</string>
- <string name="serviceClassDataAsync">"Asynchronní"</string>
- <string name="serviceClassDataSync">"Synchronizace"</string>
- <string name="serviceClassPacket">"Pakety"</string>
- <string name="serviceClassPAD">"PAD"</string>
- <string name="cfTemplateNotForwarded">"{0}: Nepřesměrováno"</string>
- <string name="cfTemplateForwarded">"{0}: {1}"</string>
- <string name="cfTemplateForwardedTime">"{0}: {1} po {2} sekundách"</string>
- <string name="cfTemplateRegistered">"{0}: Nepřesměrováno ({1})"</string>
- <string name="cfTemplateRegisteredTime">"{0}: Nepřesměrováno ({1} po {2} sekundách)"</string>
- <string name="httpErrorOk">"OK"</string>
- <string name="httpError">"Neznámá chyba"</string>
- <string name="httpErrorLookup">"Neznámý hostitel"</string>
- <string name="httpErrorUnsupportedAuthScheme">"Nepodporované schéma ověření. Ověření se nezdařilo."</string>
- <string name="httpErrorAuth">"Ověřování se nezdařilo"</string>
- <string name="httpErrorProxyAuth">"Ověření serverem proxy se nezdařilo"</string>
- <string name="httpErrorConnect">"Připojení k serveru se nezdařilo"</string>
- <string name="httpErrorIO">"Čtení nebo zápis na server se nezdařil"</string>
- <string name="httpErrorTimeout">"Časový limit připojení k serveru vypršel"</string>
- <string name="httpErrorRedirectLoop">"Příliš mnoho přesměrování serverů"</string>
- <string name="httpErrorUnsupportedScheme">"Nepodporovaný protokol"</string>
- <string name="httpErrorFailedSslHandshake">"Navázání spojení typu SSL handshake se nezdařilo"</string>
- <string name="httpErrorBadUrl">"Nepodařilo se analyzovat URL"</string>
- <string name="httpErrorFile">"File error"</string>
- <string name="httpErrorFileNotFound">"File not found"</string>
- <!-- no translation found for httpErrorTooManyRequests (3764334538393544875) -->
- <skip />
- <string name="contentServiceSync">"Synchronizace"</string>
- <string name="contentServiceSyncNotificationTitle">"Synchronizace"</string>
- <!-- no translation found for contentServiceTooManyDeletesNotificationDesc (8477597194404210723) -->
- <skip />
- <!-- no translation found for low_memory (4191592786596642367) -->
- <skip />
- <!-- no translation found for me (4616693653158602117) -->
- <skip />
- <string name="power_dialog">"Možnosti napájení"</string>
- <string name="silent_mode">"Tichý režim"</string>
- <string name="turn_on_radio">"Zapnout rádio"</string>
- <string name="turn_off_radio">"Vypnout rádio"</string>
- <!-- no translation found for screen_lock (1560333453597081877) -->
- <skip />
- <string name="power_off">"Vypnuto"</string>
- <!-- no translation found for shutdown_progress (3735034517335251808) -->
- <skip />
- <!-- no translation found for shutdown_confirm (699224922526414097) -->
- <skip />
- <!-- no translation found for no_recent_tasks (1367712919998349373) -->
- <skip />
- <!-- no translation found for global_actions (8299888906525675157) -->
- <skip />
- <!-- no translation found for global_action_lock (5943677976245541105) -->
- <skip />
- <!-- no translation found for global_action_power_off (3143027278596694254) -->
- <skip />
- <!-- no translation found for global_action_toggle_silent_mode (5849335789367070450) -->
- <skip />
- <!-- no translation found for global_action_silent_mode_on_status (6053429980569202260) -->
- <skip />
- <!-- no translation found for global_action_silent_mode_off_status (1994514127029249081) -->
- <skip />
- <!-- no translation found for safeMode (3375134507868534320) -->
- <skip />
- <!-- no translation found for permgrouplab_costMoney (904087853776533085) -->
- <skip />
- <!-- no translation found for permgroupdesc_costMoney (4662370555643969515) -->
- <skip />
- <!-- no translation found for permgrouplab_messages (2984053976424233925) -->
- <skip />
- <!-- no translation found for permgroupdesc_messages (2129093134354989379) -->
- <skip />
- <!-- no translation found for permgrouplab_personalInfo (4548406335021507392) -->
- <skip />
- <!-- no translation found for permgroupdesc_personalInfo (8499310823817958034) -->
- <skip />
- <!-- no translation found for permgrouplab_location (8535677827151907069) -->
- <skip />
- <!-- no translation found for permgroupdesc_location (2341662219604651887) -->
- <skip />
- <!-- no translation found for permgrouplab_network (3597781730625751831) -->
- <skip />
- <!-- no translation found for permgroupdesc_network (8332572695347918340) -->
- <skip />
- <!-- no translation found for permgrouplab_accounts (8631201594657951893) -->
- <skip />
- <!-- no translation found for permgroupdesc_accounts (443982868906396781) -->
- <skip />
- <!-- no translation found for permgrouplab_hardwareControls (5074512938567152139) -->
- <skip />
- <!-- no translation found for permgroupdesc_hardwareControls (8772503144945278440) -->
- <skip />
- <!-- no translation found for permgrouplab_phoneCalls (7096448531266882376) -->
- <skip />
- <!-- no translation found for permgroupdesc_phoneCalls (6703873478653366233) -->
- <skip />
- <!-- no translation found for permgrouplab_systemTools (1840847965111633430) -->
- <skip />
- <!-- no translation found for permgroupdesc_systemTools (2810337951496685271) -->
- <skip />
- <!-- no translation found for permgrouplab_developmentTools (692844635256963358) -->
- <skip />
- <!-- no translation found for permgroupdesc_developmentTools (5253915519857796400) -->
- <skip />
- <!-- no translation found for permlab_statusBar (8789506912215455922) -->
- <skip />
- <!-- no translation found for permdesc_statusBar (5034247171231682403) -->
- <skip />
- <!-- no translation found for permlab_expandStatusBar (6382500803293284173) -->
- <skip />
- <!-- no translation found for permdesc_expandStatusBar (90953162060681436) -->
- <skip />
- <!-- no translation found for permlab_processOutgoingCalls (786316295241100144) -->
- <skip />
- <!-- no translation found for permdesc_processOutgoingCalls (1655242138991854396) -->
- <skip />
- <string name="permlab_receiveSms">"Příjem zpráv SMS"</string>
- <string name="permdesc_receiveSms">"Umožňuje aplikacím přijímat a zpracovávat zprávy SMS. Škodlivé aplikace mohou sledovat vaše zprávy nebo je odstraňovat, aniž by se zobrazily."</string>
- <string name="permlab_receiveMms">"Příjem zpráv MMS"</string>
- <string name="permdesc_receiveMms">"Umožňuje aplikacím přijímat a zpracovávat zprávy MMS. Škodlivé aplikace mohou sledovat vaše zprávy nebo je odstraňovat, aniž by se zobrazily."</string>
- <!-- no translation found for permlab_sendSms (4713837923748234081) -->
- <skip />
- <!-- no translation found for permdesc_sendSms (7126594387176704010) -->
- <skip />
- <!-- no translation found for permlab_readSms (4256004535185449429) -->
- <skip />
- <!-- no translation found for permdesc_readSms (4586480500886941902) -->
- <skip />
- <!-- no translation found for permlab_writeSms (8453452414726246828) -->
- <skip />
- <!-- no translation found for permdesc_writeSms (1036408118901361812) -->
- <skip />
- <string name="permlab_receiveWapPush">"Příjem zpráv WAP"</string>
- <string name="permdesc_receiveWapPush">"Umožňuje aplikacím přijímat a zpracovávat zprávy WAP. Škodlivé aplikace mohou sledovat vaše zprávy nebo je odstraňovat, aniž by se zobrazily."</string>
- <string name="permlab_getTasks">"Získat informace o úkolech"</string>
- <string name="permdesc_getTasks">"Umožňuje aplikacím načítat informace o aktuálně a naposledy spuštěných úkolech. Umožňuje škodlivým aplikacím zjišťovat soukromé informace o jiných aplikacích."</string>
- <!-- no translation found for permlab_reorderTasks (4758862288285224517) -->
- <skip />
- <!-- no translation found for permdesc_reorderTasks (7507060843941912021) -->
- <skip />
- <!-- no translation found for permlab_setDebugApp (2973363275929449444) -->
- <skip />
- <!-- no translation found for permdesc_setDebugApp (5720449860498265972) -->
- <skip />
- <!-- no translation found for permlab_changeConfiguration (8581093564179818627) -->
- <skip />
- <!-- no translation found for permdesc_changeConfiguration (4055366453803187171) -->
- <skip />
- <!-- no translation found for permlab_restartPackages (5836367540766044606) -->
- <skip />
- <!-- no translation found for permdesc_restartPackages (1764965996765573321) -->
- <skip />
- <!-- no translation found for permlab_setProcessForeground (4860990420780868638) -->
- <skip />
- <!-- no translation found for permdesc_setProcessForeground (3795477299954784360) -->
- <skip />
- <!-- no translation found for permlab_forceBack (4737517869935566733) -->
- <skip />
- <!-- no translation found for permdesc_forceBack (5579316297001154697) -->
- <skip />
- <string name="permlab_dump">"Výpis stavu systému"</string>
- <string name="permdesc_dump">"Umožňuje aplikacím načítat vnitřní stav systému. Škodlivé aplikace mohou načítat široký rozsah soukromých a důvěrných informací, jež by obvykle neměly nikdy vyžadovat."</string>
- <string name="permlab_addSystemService">"Přidat systémovou službu"</string>
- <string name="permdesc_addSystemService">"Umožňuje aplikacím vydávat vlastní systémové služby nižší úrovně. Škodlivé aplikace mohou napadnout systém a vykrást nebo poškodit jeho data."</string>
- <string name="permlab_runSetActivityWatcher">"Nastavení sledování činností"</string>
- <string name="permdesc_runSetActivityWatcher">"Umožňuje aplikacím sledovat a řídit spouštění činností systému. Škodlivé aplikace mohou zcela zničit systém. Toto oprávnění je nutné pouze pro vývoj, nikdy pro normální používání zařízení."</string>
- <string name="permlab_broadcastPackageRemoved">"Sada vysílání odebrána"</string>
- <string name="permdesc_broadcastPackageRemoved">"Umožňuje aplikacím vysílat oznámení o odebrání sady aplikací. Škodlivé aplikace toho mohou využít k likvidaci jiné spuštěné aplikace."</string>
- <!-- no translation found for permlab_broadcastSmsReceived (1994692154847312518) -->
- <skip />
- <!-- no translation found for permdesc_broadcastSmsReceived (6072362543164841432) -->
- <skip />
- <!-- no translation found for permlab_broadcastWapPush (3070023012636951639) -->
- <skip />
- <!-- no translation found for permdesc_broadcastWapPush (726912255218924336) -->
- <skip />
- <!-- no translation found for permlab_setProcessLimit (5190694306017260601) -->
- <skip />
- <!-- no translation found for permdesc_setProcessLimit (593938303319848578) -->
- <skip />
- <!-- no translation found for permlab_setAlwaysFinish (8745533365504920540) -->
- <skip />
- <!-- no translation found for permdesc_setAlwaysFinish (2437195869854312148) -->
- <skip />
- <string name="permlab_fotaUpdate">"Instalace aktualizace systému"</string>
- <string name="permdesc_fotaUpdate">"Umožňuje aplikacím přijímat oznámení o aktualizacích systému čekajících na dokončení a spouštět jejich instalaci. Škodlivé aplikace toho mohou využít k poškození systému neautorizovanými aktualizacemi nebo obecně k zásahům do aktualizačního procesu."</string>
- <!-- no translation found for permlab_batteryStats (1598947993704535568) -->
- <skip />
- <!-- no translation found for permdesc_batteryStats (6247598531831307989) -->
- <skip />
- <string name="permlab_internalSystemWindow">"Okno vnitřního systému"</string>
- <string name="permdesc_internalSystemWindow">"Umožňuje vytváření oken určených k použití uživatelským rozhraním vnitřního systému . Není určeno k použití normálními aplikacemi."</string>
- <string name="permlab_systemAlertWindow">"Okno systémových výstrah"</string>
- <string name="permdesc_systemAlertWindow">"Umožňuje aplikacím zobrazovat okna systémových výstrah. Škodlivé aplikace mohou ovládnout celou obrazovku zařízení."</string>
- <!-- no translation found for permlab_setAnimationScale (2419250686027992384) -->
- <skip />
- <!-- no translation found for permdesc_setAnimationScale (8518027785481727264) -->
- <skip />
- <!-- no translation found for permlab_manageAppTokens (1033424552444304594) -->
- <skip />
- <!-- no translation found for permdesc_manageAppTokens (7285840918912623550) -->
- <skip />
- <!-- no translation found for permlab_injectEvents (1383601196263145482) -->
- <skip />
- <!-- no translation found for permdesc_injectEvents (840097509341464737) -->
- <skip />
- <!-- no translation found for permlab_readInputState (2723668746963882102) -->
- <skip />
- <!-- no translation found for permdesc_readInputState (4651137638757852001) -->
- <skip />
- <!-- no translation found for permlab_setOrientation (1112555600323148680) -->
- <skip />
- <!-- no translation found for permdesc_setOrientation (1960269530378827858) -->
- <skip />
- <string name="permlab_signalPersistentProcesses">"Signálové trvalé procesy"</string>
- <string name="permdesc_signalPersistentProcesses">"Umožňuje aplikacím vyžadovat, aby se přiváděný signál odesílal do všech trvalých procesů."</string>
- <!-- no translation found for permlab_persistentActivity (8163108526929094627) -->
- <skip />
- <!-- no translation found for permdesc_persistentActivity (5258975883823299624) -->
- <skip />
- <string name="permlab_deletePackages">"Odstranit sady"</string>
- <string name="permdesc_deletePackages">"Umožňuje aplikacím odstranit sady systému Android. Škodlivé aplikace toho mohou využít k odstranění důležitých aplikací."</string>
- <!-- no translation found for permlab_clearAppUserData (3858185484601410171) -->
- <skip />
- <!-- no translation found for permdesc_clearAppUserData (7233537744753081136) -->
- <skip />
- <!-- no translation found for permlab_deleteCacheFiles (7362746182961997888) -->
- <skip />
- <!-- no translation found for permdesc_deleteCacheFiles (8293849509208181266) -->
- <skip />
- <!-- no translation found for permlab_getPackageSize (6743556676630447973) -->
- <skip />
- <!-- no translation found for permdesc_getPackageSize (2893996655828539776) -->
- <skip />
- <string name="permlab_installPackages">"Instalovat sady"</string>
- <string name="permdesc_installPackages">"Umožňuje aplikacím instalovat nové nebo aktualizované sady systému Android. Škodlivé aplikace toho mohou využít k přidání nových aplikací s libovolně silnými oprávněními."</string>
- <!-- no translation found for permlab_clearAppCache (7860214328511700776) -->
- <skip />
- <!-- no translation found for permdesc_clearAppCache (5203820862573167878) -->
- <skip />
- <!-- no translation found for permlab_readLogs (6653488552442991707) -->
- <skip />
- <!-- no translation found for permdesc_readLogs (356352685800884319) -->
- <skip />
- <!-- no translation found for permlab_diagnostic (2955142476313469329) -->
- <skip />
- <!-- no translation found for permdesc_diagnostic (1282409892215520166) -->
- <skip />
- <string name="permlab_changeComponentState">"Povolit nebo zakázat součásti aplikací"</string>
- <string name="permdesc_changeComponentState">"Umožňuje změnu aplikace bez ohledu na to, zda je součást další aplikace povolená nebo zakázaná. Škodlivá aplikace toho může využít k zakázání důležitých funkcí zařízení. Je třeba nakládat s oprávněními opatrně, protože se mohou součásti aplikace dostat do stavu nepoužitelnosti, nekonzistence nebo nestability."</string>
- <string name="permlab_setPreferredApplications">"Nastavení upřednostňovaných aplikací"</string>
- <string name="permdesc_setPreferredApplications">"Umožňuje aplikacím upravovat oblíbené aplikace. Škodlivé aplikace tak mohou bez upozornění měnit spouštěné aplikace a klamně využívat stávající aplikace ke shromažďování vašich soukromých dat."</string>
- <string name="permlab_writeSettings">"Nastavení systému pro zápis"</string>
- <string name="permdesc_writeSettings">"Umožňuje aplikacím upravovat data nastavení systému. Škodlivé aplikace mohou narušit systémovou konfiguraci."</string>
- <!-- no translation found for permlab_writeSecureSettings (4851801872124242319) -->
- <skip />
- <!-- no translation found for permdesc_writeSecureSettings (2080620249472761366) -->
- <skip />
- <!-- no translation found for permlab_writeGservices (296370685945777755) -->
- <skip />
- <!-- no translation found for permdesc_writeGservices (2496928471286495053) -->
- <skip />
- <string name="permlab_receiveBootCompleted">"Spustit při spouštění"</string>
- <string name="permdesc_receiveBootCompleted">"Umožňuje aplikacím spouštět se po dokončení spuštění systému. Tím se může prodlužovat doba spouštění zařízení a aplikace může svým stálým spouštěním zpomalovat celé zařízení."</string>
- <string name="permlab_broadcastSticky">"Vysílat lepivý obsah (sticky)"</string>
- <string name="permdesc_broadcastSticky">"Umožňuje aplikacím odesílat tzv. lepivé (sticky) vysílání, které zůstává i po ukončení vysílání. Škodlivé aplikace mohou zpomalit zařízení nebo narušit jeho stabilitu vynucením využívání příliš velké části paměti."</string>
- <string name="permlab_readContacts">"Čtení dat o kontaktech"</string>
- <string name="permdesc_readContacts">"Umožňuje aplikacím číst všechna data o kontaktech (adresy) uložená v zařízení. Škodlivé aplikace toho mohou využívat k odesílání vašich dat jiným osobám."</string>
- <string name="permlab_writeContacts">"Zápis dat o kontaktech"</string>
- <string name="permdesc_writeContacts">"Umožňuje aplikacím upravovat data o kontaktech (adresy) uložená v zařízení. Škodlivé aplikace toho mohou využívat k vymazání nebo úpravě dat o kontaktech."</string>
- <!-- no translation found for permlab_writeOwnerData (8036840529708535113) -->
- <skip />
- <!-- no translation found for permdesc_writeOwnerData (5873447528845878348) -->
- <skip />
- <!-- no translation found for permlab_readOwnerData (1847040178513733757) -->
- <skip />
- <!-- no translation found for permdesc_readOwnerData (7563299529149214764) -->
- <skip />
- <!-- no translation found for permlab_readCalendar (2111238731453410895) -->
- <skip />
- <!-- no translation found for permdesc_readCalendar (4408253940601239114) -->
- <skip />
- <!-- no translation found for permlab_writeCalendar (7518052789370653396) -->
- <skip />
- <!-- no translation found for permdesc_writeCalendar (8057304232140147596) -->
- <skip />
- <!-- no translation found for permlab_accessMockLocation (321094551062270213) -->
- <skip />
- <!-- no translation found for permdesc_accessMockLocation (3651565866471419739) -->
- <skip />
- <!-- no translation found for permlab_accessLocationExtraCommands (8291822077788811687) -->
- <skip />
- <!-- no translation found for permdesc_accessLocationExtraCommands (5135782633548630731) -->
- <skip />
- <string name="permlab_accessFineLocation">"Používat službu GPS"</string>
- <string name="permdesc_accessFineLocation">"Technologii GPS v zařízení lze používat, pokud je k dispozici. Toto oprávnění vyžaduje oprávnění ACCESS_LOCATION. Škodlivé aplikace toho mohou využívat k určení vaší polohy a mohou spotřebovávat zbytečně energii baterie."</string>
- <string name="permlab_accessCoarseLocation">"Používat službu Cell ID"</string>
- <string name="permdesc_accessCoarseLocation">"Identifikátory pro technologii využívající polohu vysílačů mobilních sítí (je-li k dispozici) se používají k určení přibližné polohy zařízení. Toto oprávnění vyžaduje oprávnění ACCESS_LOCATION. Škodlivé aplikace toho mohou využívat k určení vaší přibližné polohy."</string>
- <string name="permlab_accessSurfaceFlinger">"Používat službu SurfaceFlinger"</string>
- <string name="permdesc_accessSurfaceFlinger">"Umožňuje aplikacím používat funkce nižší úrovně SurfaceFlinger."</string>
- <string name="permlab_readFrameBuffer">"Čtení vyrovnávací paměti rámce"</string>
- <string name="permdesc_readFrameBuffer">"Umožňuje aplikacím používat čtení obsahu vyrovnávací paměti rámce."</string>
- <!-- no translation found for permlab_modifyAudioSettings (1587341813207960943) -->
- <skip />
- <!-- no translation found for permdesc_modifyAudioSettings (1447143004892708149) -->
- <skip />
- <!-- no translation found for permlab_recordAudio (4447848534036991667) -->
- <skip />
- <!-- no translation found for permdesc_recordAudio (6936874682400894820) -->
- <skip />
- <!-- no translation found for permlab_camera (1944473855727060380) -->
- <skip />
- <!-- no translation found for permdesc_camera (5978058582323766022) -->
- <skip />
- <!-- no translation found for permlab_brick (4749832243303289777) -->
- <skip />
- <!-- no translation found for permdesc_brick (7428524578693695766) -->
- <skip />
- <!-- no translation found for permlab_reboot (8844650672567077423) -->
- <skip />
- <!-- no translation found for permdesc_reboot (4704919552870918328) -->
- <skip />
- <!-- no translation found for permlab_mount_unmount_filesystems (1009574821038043781) -->
- <skip />
- <!-- no translation found for permdesc_mount_unmount_filesystems (100792065894811109) -->
- <skip />
- <!-- no translation found for permlab_vibrate (61984555644467146) -->
- <skip />
- <!-- no translation found for permdesc_vibrate (7831723100758509238) -->
- <skip />
- <!-- no translation found for permlab_flashlight (9097145977808182652) -->
- <skip />
- <!-- no translation found for permdesc_flashlight (7851502731988978358) -->
- <skip />
- <!-- no translation found for permlab_hardware_test (4103324677866524254) -->
- <skip />
- <!-- no translation found for permdesc_hardware_test (7315242723603994769) -->
- <skip />
- <string name="permlab_callPhone">"Volat telefonní čísla"</string>
- <string name="permdesc_callPhone">"Umožňuje aplikacím volat telefonní čísla bez vašeho zásahu. Škodlivé aplikace mohou přinést na váš telefonní účet neočekávané hovory."</string>
- <!-- no translation found for permlab_callPrivileged (2166923597287697159) -->
- <skip />
- <!-- no translation found for permdesc_callPrivileged (5109789447971735501) -->
- <skip />
- <!-- no translation found for permlab_locationUpdates (4216418293360456836) -->
- <skip />
- <!-- no translation found for permdesc_locationUpdates (7635814693478743648) -->
- <skip />
- <!-- no translation found for permlab_checkinProperties (2260796787386280708) -->
- <skip />
- <!-- no translation found for permdesc_checkinProperties (3508022022841741945) -->
- <skip />
- <!-- no translation found for permlab_modifyPhoneState (7791696535097912313) -->
- <skip />
- <!-- no translation found for permdesc_modifyPhoneState (6352405226410454770) -->
- <skip />
- <!-- no translation found for permlab_readPhoneState (7320082586621086653) -->
- <skip />
- <!-- no translation found for permdesc_readPhoneState (8004450067066407969) -->
- <skip />
- <!-- no translation found for permlab_wakeLock (1591164750935072136) -->
- <skip />
- <!-- no translation found for permdesc_wakeLock (160471538196734936) -->
- <skip />
- <!-- no translation found for permlab_devicePower (9214865067086065548) -->
- <skip />
- <!-- no translation found for permdesc_devicePower (5608364066480036402) -->
- <skip />
- <!-- no translation found for permlab_factoryTest (7786199300637896247) -->
- <skip />
- <!-- no translation found for permdesc_factoryTest (3466066005210542042) -->
- <skip />
- <!-- no translation found for permlab_setWallpaper (2256730637138641725) -->
- <skip />
- <!-- no translation found for permdesc_setWallpaper (3034653140208685093) -->
- <skip />
- <!-- no translation found for permlab_setWallpaperHints (4192438316932517807) -->
- <skip />
- <!-- no translation found for permdesc_setWallpaperHints (738757439960921674) -->
- <skip />
- <!-- no translation found for permlab_masterClear (6155403967270586906) -->
- <skip />
- <!-- no translation found for permdesc_masterClear (4213553172342689754) -->
- <skip />
- <!-- no translation found for permlab_setTimeZone (477196167239548690) -->
- <skip />
- <!-- no translation found for permdesc_setTimeZone (8564892020460841198) -->
- <skip />
- <!-- no translation found for permlab_getAccounts (2764070033402295170) -->
- <skip />
- <!-- no translation found for permdesc_getAccounts (1203491378748649898) -->
- <skip />
- <!-- no translation found for permlab_accessNetworkState (2032916924886010827) -->
- <skip />
- <!-- no translation found for permdesc_accessNetworkState (7081329402551195933) -->
- <skip />
- <!-- no translation found for permlab_createNetworkSockets (4706698319966917864) -->
- <skip />
- <!-- no translation found for permdesc_createNetworkSockets (2580337178778551792) -->
- <skip />
- <!-- no translation found for permlab_writeApnSettings (3190585220761979369) -->
- <skip />
- <!-- no translation found for permdesc_writeApnSettings (4093875220468761052) -->
- <skip />
- <!-- no translation found for permlab_changeNetworkState (2710779001260856872) -->
- <skip />
- <!-- no translation found for permdesc_changeNetworkState (8076109230787022270) -->
- <skip />
- <!-- no translation found for permlab_accessWifiState (3613679494230374297) -->
- <skip />
- <!-- no translation found for permdesc_accessWifiState (8226508433563326925) -->
- <skip />
- <!-- no translation found for permlab_changeWifiState (6043889338995432957) -->
- <skip />
- <!-- no translation found for permdesc_changeWifiState (7829372845909567994) -->
- <skip />
- <!-- no translation found for permlab_bluetoothAdmin (5513286736585647334) -->
- <skip />
- <!-- no translation found for permdesc_bluetoothAdmin (1838208497914347365) -->
- <skip />
- <!-- no translation found for permlab_bluetooth (6378797624765639115) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth (8592386018922265273) -->
- <skip />
- <!-- no translation found for permlab_disableKeyguard (4574886811903233903) -->
- <skip />
- <!-- no translation found for permdesc_disableKeyguard (815972646344251271) -->
- <skip />
- <!-- no translation found for permlab_readSyncSettings (8818819977141505127) -->
- <skip />
- <!-- no translation found for permdesc_readSyncSettings (8454705401908767847) -->
- <skip />
- <!-- no translation found for permlab_writeSyncSettings (4514911143753152941) -->
- <skip />
- <!-- no translation found for permdesc_writeSyncSettings (7630627689635091836) -->
- <skip />
- <!-- no translation found for permlab_readSyncStats (5748337739678952863) -->
- <skip />
- <!-- no translation found for permdesc_readSyncStats (582551457321957183) -->
- <skip />
- <!-- no translation found for permlab_subscribedFeedsRead (2043206814904506589) -->
- <skip />
- <!-- no translation found for permdesc_subscribedFeedsRead (6977343942680042449) -->
- <skip />
- <!-- no translation found for permlab_subscribedFeedsWrite (2556727307229571556) -->
- <skip />
- <!-- no translation found for permdesc_subscribedFeedsWrite (4134783294590266220) -->
- <skip />
- <!-- no translation found for phoneTypes:7 (1326005699931077792) -->
- <string-array name="emailAddressTypes">
- <item>"Výchozí"</item>
- <item>"Zaměstnání"</item>
- <item>"Primární"</item>
- <item>"Vlastní…"</item>
- </string-array>
- <string-array name="postalAddressTypes">
- <item>"Poštovní"</item>
- <item>"Výchozí"</item>
- <item>"Zaměstnání"</item>
- <item>"Vlastní…"</item>
- </string-array>
- <!-- no translation found for imAddressTypes:0 (7806620012096518833) -->
- <!-- no translation found for imAddressTypes:1 (5748846799950672787) -->
- <!-- no translation found for imAddressTypes:2 (6196536810275073680) -->
- <!-- no translation found for imAddressTypes:3 (8519128375350623648) -->
- <!-- no translation found for organizationTypes:0 (1299224825223821142) -->
- <!-- no translation found for organizationTypes:1 (2455717447227299354) -->
- <!-- no translation found for organizationTypes:2 (7027570839313438290) -->
- <!-- no translation found for imProtocols:0 (3318725788774688043) -->
- <!-- no translation found for imProtocols:1 (1787713387022932886) -->
- <!-- no translation found for imProtocols:2 (6751174158442316516) -->
- <!-- no translation found for imProtocols:3 (1151283347465052653) -->
- <!-- no translation found for imProtocols:4 (2157980008878817934) -->
- <!-- no translation found for imProtocols:5 (7836237460308230767) -->
- <!-- no translation found for imProtocols:6 (1180789904462172516) -->
- <!-- no translation found for imProtocols:7 (21955111672779862) -->
- <!-- no translation found for keyguard_password_enter_pin_code (6779835451906812518) -->
- <skip />
- <!-- no translation found for keyguard_password_wrong_pin_code (230312338493035499) -->
- <skip />
- <string name="keyguard_label_text">"Telefon odemknete stisknutím tlačítka nabídky a poté 0."</string>
- <!-- no translation found for emergency_call_dialog_number_for_display (6256361184251050511) -->
- <skip />
- <!-- no translation found for lockscreen_carrier_default (5222269885486229730) -->
- <skip />
- <!-- no translation found for lockscreen_screen_locked (1922273663462058967) -->
- <skip />
- <!-- no translation found for lockscreen_instructions_when_pattern_enabled (7535864145009679967) -->
- <skip />
- <!-- no translation found for lockscreen_instructions_when_pattern_disabled (6526504555912746785) -->
- <skip />
- <!-- no translation found for lockscreen_pattern_instructions (8984964506352089877) -->
- <skip />
- <!-- no translation found for lockscreen_emergency_call (422835617844547383) -->
- <skip />
- <!-- no translation found for lockscreen_pattern_correct (7104753084746383672) -->
- <skip />
- <!-- no translation found for lockscreen_pattern_wrong (7517004470797680361) -->
- <skip />
- <!-- no translation found for lockscreen_plugged_in (8806977650003537118) -->
- <skip />
- <!-- no translation found for lockscreen_low_battery (9002637795199621345) -->
- <skip />
- <!-- no translation found for lockscreen_missing_sim_message_short (5051192587315492957) -->
- <skip />
- <!-- no translation found for lockscreen_missing_sim_message (8912914495901434841) -->
- <skip />
- <!-- no translation found for lockscreen_missing_sim_instructions (8125847194365725429) -->
- <skip />
- <!-- no translation found for lockscreen_network_locked_message (323609607922245071) -->
- <skip />
- <!-- no translation found for lockscreen_sim_puk_locked_message (1005803622871256359) -->
- <skip />
- <!-- no translation found for lockscreen_sim_puk_locked_instructions (5033160098036646955) -->
- <skip />
- <!-- no translation found for lockscreen_sim_locked_message (7398401200962556379) -->
- <skip />
- <!-- no translation found for lockscreen_sim_unlock_progress_dialog_message (5939537246164692076) -->
- <skip />
- <!-- no translation found for lockscreen_too_many_failed_attempts_dialog_message (6709066241494622136) -->
- <skip />
- <!-- no translation found for lockscreen_failed_attempts_almost_glogin (1569017295989454551) -->
- <skip />
- <!-- no translation found for lockscreen_too_many_failed_attempts_countdown (8823588000022797566) -->
- <skip />
- <!-- no translation found for lockscreen_forgot_pattern_button_text (4219994639843985488) -->
- <skip />
- <!-- no translation found for lockscreen_glogin_too_many_attempts (7504679498838839295) -->
- <skip />
- <!-- no translation found for lockscreen_glogin_instructions (6542400673357252011) -->
- <skip />
- <!-- no translation found for lockscreen_glogin_username_hint (6378418320242015111) -->
- <skip />
- <!-- no translation found for lockscreen_glogin_password_hint (3224230234042131153) -->
- <skip />
- <!-- no translation found for lockscreen_glogin_submit_button (5562051040043760034) -->
- <skip />
- <!-- no translation found for lockscreen_glogin_invalid_input (4881057177478491580) -->
- <skip />
- <!-- no translation found for status_bar_time_format (2168573805413119180) -->
- <skip />
- <!-- no translation found for hour_minute_ampm (1850330605794978742) -->
- <skip />
- <!-- no translation found for hour_minute_cap_ampm (1122840227537374196) -->
- <skip />
- <!-- no translation found for hour_ampm (7665432130905376251) -->
- <skip />
- <!-- no translation found for hour_cap_ampm (3600295014648400268) -->
- <skip />
- <!-- no translation found for status_bar_clear_all_button (2202004591253243750) -->
- <skip />
- <!-- no translation found for status_bar_no_notifications_title (5123133188102094464) -->
- <skip />
- <!-- no translation found for status_bar_ongoing_events_title (799961521630569167) -->
- <skip />
- <!-- no translation found for status_bar_latest_events_title (5414094466807164279) -->
- <skip />
- <!-- no translation found for battery_status_text_percent_format (7391464609447031944) -->
- <skip />
- <!-- no translation found for battery_status_charging (5078780715755132756) -->
- <skip />
- <!-- no translation found for battery_low_title (3665400828395001695) -->
- <skip />
- <!-- no translation found for battery_low_subtitle (7537149915372180016) -->
- <skip />
- <!-- no translation found for battery_low_percent_format (8635359708781261154) -->
- <skip />
- <string name="factorytest_failed">"Výrobní test skončil chybou"</string>
- <string name="factorytest_not_system">"Akce FACTORY_TEST je podporována pouze pro sady instalované v adresáři /system/app."</string>
- <string name="factorytest_no_action">"Nebyla nalezena žádná sada, která zajišťuje akci FACTORY_TEST."</string>
- <string name="factorytest_reboot">"Restartovat"</string>
- <!-- no translation found for save_password_label (4129493019621348626) -->
- <skip />
- <!-- no translation found for save_password_message (7412617920202682045) -->
- <skip />
- <!-- no translation found for save_password_notnow (3887362423496820832) -->
- <skip />
- <!-- no translation found for save_password_remember (4319688896716308569) -->
- <skip />
- <!-- no translation found for save_password_never (1836981952883642377) -->
- <skip />
- <!-- no translation found for open_permission_deny (6408502671105717111) -->
- <skip />
- <!-- no translation found for text_copied (6106873823411904723) -->
- <skip />
- <string name="more_item_label">"Další"</string>
- <string name="prepend_shortcut_label">"Menu+"</string>
- <!-- no translation found for menu_space_shortcut_label (194586306440382711) -->
- <skip />
- <!-- no translation found for menu_enter_shortcut_label (7214761412193519345) -->
- <skip />
- <!-- no translation found for menu_delete_shortcut_label (2854936426194985313) -->
- <skip />
- <string name="search_go">"PŘEJÍT"</string>
- <string name="today">"Dnes"</string>
- <string name="yesterday">"Včera"</string>
- <string name="tomorrow">"Zítra"</string>
- <!-- no translation found for oneMonthDurationPast (3402179395240209557) -->
- <skip />
- <!-- no translation found for beforeOneMonthDurationPast (7578100953282866827) -->
- <skip />
- <!-- no translation found for num_seconds_ago:one (7416512229671810725) -->
- <!-- no translation found for num_seconds_ago:other (8138756910300398447) -->
- <!-- no translation found for num_minutes_ago:one (8620869479299420562) -->
- <!-- no translation found for num_minutes_ago:other (5065488162050522741) -->
- <!-- no translation found for num_hours_ago:one (853404611989669641) -->
- <!-- no translation found for num_hours_ago:other (3558873784561756849) -->
- <!-- no translation found for num_days_ago:one (4222479980812128212) -->
- <!-- no translation found for num_days_ago:other (5445701370433601703) -->
- <!-- no translation found for in_num_seconds:one (4253290037777327003) -->
- <!-- no translation found for in_num_seconds:other (1280033870920841404) -->
- <!-- no translation found for in_num_minutes:one (1487585791027953091) -->
- <!-- no translation found for in_num_minutes:other (6274204576475209932) -->
- <!-- no translation found for in_num_hours:one (6501470863235186391) -->
- <!-- no translation found for in_num_hours:other (4415358752953289251) -->
- <!-- no translation found for in_num_days:one (5608475533104443893) -->
- <!-- no translation found for in_num_days:other (3827193006163842267) -->
- <!-- no translation found for preposition_for_date (2689847983632851560) -->
- <skip />
- <!-- no translation found for preposition_for_time (2613388053493148013) -->
- <skip />
- <!-- no translation found for preposition_for_year (6968468294728152393) -->
- <skip />
- <string name="day">"den"</string>
- <string name="days">"dnů"</string>
- <string name="hour">"hodinu"</string>
- <string name="hours">"hodin"</string>
- <string name="minute">"minutu"</string>
- <string name="minutes">"minut"</string>
- <string name="second">"sekund"</string>
- <string name="seconds">"sekund"</string>
- <string name="week">"týden"</string>
- <string name="weeks">"týdnů"</string>
- <!-- no translation found for year (8024790425994085153) -->
- <skip />
- <!-- no translation found for years (8592090054773244417) -->
- <skip />
- <string name="sunday">"Neděle"</string>
- <string name="monday">"Pondělí"</string>
- <string name="tuesday">"Úterý"</string>
- <string name="wednesday">"Středa"</string>
- <string name="thursday">"Čtvrtek"</string>
- <string name="friday">"Pátek"</string>
- <string name="saturday">"Sobota"</string>
- <string name="every_weekday">"Každý den v týdnu (Po–Pá)"</string>
- <string name="daily">"Denně"</string>
- <string name="weekly">"Týdně (%s)"</string>
- <string name="monthly">"Měsíčně"</string>
- <string name="yearly">"Ročně"</string>
- <!-- no translation found for VideoView_error_title (1024334251681931859) -->
- <skip />
- <!-- no translation found for VideoView_error_text_unknown (3398417247398476771) -->
- <skip />
- <!-- no translation found for VideoView_error_button (3144127115413163445) -->
- <skip />
- <string name="am">"dop."</string>
- <string name="pm">"odp."</string>
- <!-- no translation found for numeric_date (5120078478872821100) -->
- <skip />
- <!-- no translation found for wday1_date1_time1_wday2_date2_time2 (7066878981949584861) -->
- <skip />
- <!-- no translation found for wday1_date1_wday2_date2 (8671068747172261907) -->
- <skip />
- <!-- no translation found for date1_time1_date2_time2 (3645498975775629615) -->
- <skip />
- <!-- no translation found for date1_date2 (377057563556488062) -->
- <skip />
- <!-- no translation found for time1_time2 (3173474242109288305) -->
- <skip />
- <!-- no translation found for time_wday_date (8928955562064570313) -->
- <skip />
- <!-- no translation found for wday_date (8794741400546136975) -->
- <skip />
- <!-- no translation found for time_date (1922644512833014496) -->
- <skip />
- <!-- no translation found for time_wday (1422050241301754712) -->
- <skip />
- <!-- no translation found for full_date_month_first (6011143962222283357) -->
- <skip />
- <!-- no translation found for full_date_day_first (8621594762705478189) -->
- <skip />
- <!-- no translation found for medium_date_month_first (48990963718825728) -->
- <skip />
- <!-- no translation found for medium_date_day_first (2898992016440387123) -->
- <skip />
- <!-- no translation found for twelve_hour_time_format (6015557937879492156) -->
- <skip />
- <!-- no translation found for twenty_four_hour_time_format (5176807998669709535) -->
- <skip />
- <!-- no translation found for noon (8390796001560682897) -->
- <skip />
- <!-- no translation found for Noon (7698941576181064429) -->
- <skip />
- <!-- no translation found for midnight (7773339795626486146) -->
- <skip />
- <!-- no translation found for Midnight (1260172107848123187) -->
- <skip />
- <!-- no translation found for month_day (3356633704511426364) -->
- <skip />
- <!-- no translation found for month (3017405760734206414) -->
- <skip />
- <!-- no translation found for month_day_year (2435948225709176752) -->
- <skip />
- <!-- no translation found for month_year (6228414124777343135) -->
- <skip />
- <!-- no translation found for time_of_day (8375993139317154157) -->
- <skip />
- <!-- no translation found for date_and_time (9197690194373107109) -->
- <skip />
- <!-- no translation found for same_year_md1_md2 (9199324363135981317) -->
- <skip />
- <!-- no translation found for same_year_wday1_md1_wday2_md2 (6006392413355305178) -->
- <skip />
- <!-- no translation found for same_year_mdy1_mdy2 (1576657593937827090) -->
- <skip />
- <!-- no translation found for same_year_wday1_mdy1_wday2_mdy2 (9135935796468891580) -->
- <skip />
- <!-- no translation found for same_year_md1_time1_md2_time2 (2172964106375558081) -->
- <skip />
- <!-- no translation found for same_year_wday1_md1_time1_wday2_md2_time2 (1702879534101786310) -->
- <skip />
- <!-- no translation found for same_year_mdy1_time1_mdy2_time2 (2476443311723358767) -->
- <skip />
- <!-- no translation found for same_year_wday1_mdy1_time1_wday2_mdy2_time2 (1564837340334069879) -->
- <skip />
- <!-- no translation found for numeric_md1_md2 (8908376522875100300) -->
- <skip />
- <!-- no translation found for numeric_wday1_md1_wday2_md2 (3239690882018292077) -->
- <skip />
- <!-- no translation found for numeric_mdy1_mdy2 (8883797176939233525) -->
- <skip />
- <!-- no translation found for numeric_wday1_mdy1_wday2_mdy2 (4150475769255828954) -->
- <skip />
- <!-- no translation found for numeric_md1_time1_md2_time2 (3624746590607741419) -->
- <skip />
- <!-- no translation found for numeric_wday1_md1_time1_wday2_md2_time2 (4258040955467298134) -->
- <skip />
- <!-- no translation found for numeric_mdy1_time1_mdy2_time2 (3598215409314517987) -->
- <skip />
- <!-- no translation found for numeric_wday1_mdy1_time1_wday2_mdy2_time2 (264076937155877259) -->
- <skip />
- <!-- no translation found for same_month_md1_md2 (2393563617438036111) -->
- <skip />
- <!-- no translation found for same_month_wday1_md1_wday2_md2 (1208946773794057819) -->
- <skip />
- <!-- no translation found for same_month_mdy1_mdy2 (3713236637869030492) -->
- <skip />
- <!-- no translation found for same_month_wday1_mdy1_wday2_mdy2 (389638922479870472) -->
- <skip />
- <!-- no translation found for same_month_md1_time1_md2_time2 (7477075526337542685) -->
- <skip />
- <!-- no translation found for same_month_wday1_md1_time1_wday2_md2_time2 (3516978303779391173) -->
- <skip />
- <!-- no translation found for same_month_mdy1_time1_mdy2_time2 (7320410992514057310) -->
- <skip />
- <!-- no translation found for same_month_wday1_mdy1_time1_wday2_mdy2_time2 (1332950588774239228) -->
- <skip />
- <!-- no translation found for abbrev_month_day_year (5767271534015320250) -->
- <skip />
- <!-- no translation found for abbrev_month_year (8058929633673942490) -->
- <skip />
- <!-- no translation found for abbrev_month_day (458867920693482757) -->
- <skip />
- <!-- no translation found for abbrev_month (1674509986330181349) -->
- <skip />
- <!-- no translation found for day_of_week_long_sunday (9057662850446501884) -->
- <skip />
- <!-- no translation found for day_of_week_long_monday (7358451993082888343) -->
- <skip />
- <!-- no translation found for day_of_week_long_tuesday (2282901451170509613) -->
- <skip />
- <!-- no translation found for day_of_week_long_wednesday (2100217950343286482) -->
- <skip />
- <!-- no translation found for day_of_week_long_thursday (5475158963242863176) -->
- <skip />
- <!-- no translation found for day_of_week_long_friday (4081018004819837155) -->
- <skip />
- <!-- no translation found for day_of_week_long_saturday (1929694088305891795) -->
- <skip />
- <!-- no translation found for day_of_week_medium_sunday (6462580883948669820) -->
- <skip />
- <!-- no translation found for day_of_week_medium_monday (6960587654241349502) -->
- <skip />
- <!-- no translation found for day_of_week_medium_tuesday (7004462235990108936) -->
- <skip />
- <!-- no translation found for day_of_week_medium_wednesday (5688564741951314696) -->
- <skip />
- <!-- no translation found for day_of_week_medium_thursday (1784339868453982400) -->
- <skip />
- <!-- no translation found for day_of_week_medium_friday (4314577583604069357) -->
- <skip />
- <!-- no translation found for day_of_week_medium_saturday (70321191398427845) -->
- <skip />
- <!-- no translation found for day_of_week_short_sunday (7403409454572591357) -->
- <skip />
- <!-- no translation found for day_of_week_short_monday (5278358100012478239) -->
- <skip />
- <!-- no translation found for day_of_week_short_tuesday (5121116040712487059) -->
- <skip />
- <!-- no translation found for day_of_week_short_wednesday (1601079579293330319) -->
- <skip />
- <!-- no translation found for day_of_week_short_thursday (5863422096017401812) -->
- <skip />
- <!-- no translation found for day_of_week_short_friday (2916686031099723960) -->
- <skip />
- <!-- no translation found for day_of_week_short_saturday (8521564973195542073) -->
- <skip />
- <!-- no translation found for day_of_week_shorter_sunday (1650484495176707638) -->
- <skip />
- <!-- no translation found for day_of_week_shorter_monday (9133193697786876074) -->
- <skip />
- <!-- no translation found for day_of_week_shorter_tuesday (4012095408481489663) -->
- <skip />
- <!-- no translation found for day_of_week_shorter_wednesday (6279056612496078470) -->
- <skip />
- <!-- no translation found for day_of_week_shorter_thursday (2748599403545071011) -->
- <skip />
- <!-- no translation found for day_of_week_shorter_friday (5037282109124849673) -->
- <skip />
- <!-- no translation found for day_of_week_shorter_saturday (3208167155877833783) -->
- <skip />
- <!-- no translation found for day_of_week_shortest_sunday (4683862964821549758) -->
- <skip />
- <!-- no translation found for day_of_week_shortest_monday (6701142261471667000) -->
- <skip />
- <!-- no translation found for day_of_week_shortest_tuesday (9098171980161292477) -->
- <skip />
- <!-- no translation found for day_of_week_shortest_wednesday (655049238289460956) -->
- <skip />
- <!-- no translation found for day_of_week_shortest_thursday (7816913627500884083) -->
- <skip />
- <!-- no translation found for day_of_week_shortest_friday (903301878650619398) -->
- <skip />
- <!-- no translation found for day_of_week_shortest_saturday (5359692489649817988) -->
- <skip />
- <!-- no translation found for month_long_january (7128497801440564337) -->
- <skip />
- <!-- no translation found for month_long_february (7808570514581190617) -->
- <skip />
- <!-- no translation found for month_long_march (2061328556983796034) -->
- <skip />
- <!-- no translation found for month_long_april (6575007959043269919) -->
- <skip />
- <!-- no translation found for month_long_may (8404051103463071121) -->
- <skip />
- <!-- no translation found for month_long_june (6255771619238859451) -->
- <skip />
- <!-- no translation found for month_long_july (4129177743136800884) -->
- <skip />
- <!-- no translation found for month_long_august (5494331003296804494) -->
- <skip />
- <!-- no translation found for month_long_september (2691137479752033087) -->
- <skip />
- <!-- no translation found for month_long_october (7501261567327243313) -->
- <skip />
- <!-- no translation found for month_long_november (8759690753068763664) -->
- <skip />
- <!-- no translation found for month_long_december (4505008719696569497) -->
- <skip />
- <!-- no translation found for month_medium_january (2315492772833932512) -->
- <skip />
- <!-- no translation found for month_medium_february (118412521324313430) -->
- <skip />
- <!-- no translation found for month_medium_march (5546835583839352358) -->
- <skip />
- <!-- no translation found for month_medium_april (7052559668687733702) -->
- <skip />
- <!-- no translation found for month_medium_may (2825303871720116018) -->
- <skip />
- <!-- no translation found for month_medium_june (829843667101495271) -->
- <skip />
- <!-- no translation found for month_medium_july (5029778226925324789) -->
- <skip />
- <!-- no translation found for month_medium_august (8851230594641162805) -->
- <skip />
- <!-- no translation found for month_medium_september (8420590486625304647) -->
- <skip />
- <!-- no translation found for month_medium_october (1787382806172930239) -->
- <skip />
- <!-- no translation found for month_medium_november (675513809622370603) -->
- <skip />
- <!-- no translation found for month_medium_december (2934948295928978783) -->
- <skip />
- <!-- no translation found for month_shortest_january (6070060405144675883) -->
- <skip />
- <!-- no translation found for month_shortest_february (5632605004902176653) -->
- <skip />
- <!-- no translation found for month_shortest_march (4304231552356086624) -->
- <skip />
- <!-- no translation found for month_shortest_april (1166434066469385532) -->
- <skip />
- <!-- no translation found for month_shortest_may (9131326028845529001) -->
- <skip />
- <!-- no translation found for month_shortest_june (1875723154506665289) -->
- <skip />
- <!-- no translation found for month_shortest_july (2003596275389810773) -->
- <skip />
- <!-- no translation found for month_shortest_august (9120245162625763214) -->
- <skip />
- <!-- no translation found for month_shortest_september (7980651111022693669) -->
- <skip />
- <!-- no translation found for month_shortest_october (3640405450427788312) -->
- <skip />
- <!-- no translation found for month_shortest_november (4002935318566146993) -->
- <skip />
- <!-- no translation found for month_shortest_december (6213739417171334040) -->
- <skip />
- <!-- no translation found for elapsed_time_short_format_mm_ss (1294409362352514646) -->
- <skip />
- <!-- no translation found for elapsed_time_short_format_h_mm_ss (2997059666628785039) -->
- <skip />
- <!-- no translation found for selectAll (691691810023908884) -->
- <skip />
- <!-- no translation found for cut (5845613239192595662) -->
- <skip />
- <!-- no translation found for cutAll (4474519683293791451) -->
- <skip />
- <!-- no translation found for copy (8603721575469529820) -->
- <skip />
- <!-- no translation found for copyAll (4777548804630476932) -->
- <skip />
- <!-- no translation found for paste (6458036735811828538) -->
- <skip />
- <!-- no translation found for copyUrl (5785708478767435812) -->
- <skip />
- <!-- no translation found for inputMethod (7911866729148111492) -->
- <skip />
- <!-- no translation found for editTextMenuTitle (3984253728638788023) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_title (5997772070488639934) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (2230118755295375293) -->
- <skip />
- <!-- no translation found for ok (4003878536083514869) -->
- <skip />
- <!-- no translation found for cancel (1527674037280267012) -->
- <skip />
- <!-- no translation found for yes (8185296114406773873) -->
- <skip />
- <!-- no translation found for no (2300685350903156262) -->
- <skip />
- <!-- no translation found for capital_on (8418242581217554942) -->
- <skip />
- <!-- no translation found for capital_off (8870368560477693851) -->
- <skip />
- <!-- no translation found for whichApplication (2828159696176255212) -->
- <skip />
- <!-- no translation found for alwaysUse (6433627451071144629) -->
- <skip />
- <!-- no translation found for clearDefaultHintMsg (5742432113023174321) -->
- <skip />
- <!-- no translation found for chooseActivity (7588691622928031978) -->
- <skip />
- <!-- no translation found for noApplications (4068560364116066745) -->
- <skip />
- <!-- no translation found for aerr_title (2654390351574026098) -->
- <skip />
- <!-- no translation found for aerr_application (4917288809565116720) -->
- <skip />
- <!-- no translation found for aerr_process (1273819861108073461) -->
- <skip />
- <!-- no translation found for anr_title (3305935690891435915) -->
- <skip />
- <!-- no translation found for anr_activity_application (1653036325679156678) -->
- <skip />
- <!-- no translation found for anr_activity_process (2674027618362070465) -->
- <skip />
- <!-- no translation found for anr_application_process (2163656674970221928) -->
- <skip />
- <!-- no translation found for anr_process (7747550780123472160) -->
- <skip />
- <!-- no translation found for force_close (9020954128872810669) -->
- <skip />
- <!-- no translation found for wait (7973775702304037058) -->
- <skip />
- <!-- no translation found for debug (857932504764728770) -->
- <skip />
- <!-- no translation found for sendText (6158329286172492543) -->
- <skip />
- <!-- no translation found for volume_ringtone (4121694816346562058) -->
- <skip />
- <!-- no translation found for volume_music (4869950240104717493) -->
- <skip />
- <!-- no translation found for volume_call (5723421277753250395) -->
- <skip />
- <!-- no translation found for volume_alarm (2752102730973081294) -->
- <skip />
- <!-- no translation found for volume_unknown (6908187627672375742) -->
- <skip />
- <!-- no translation found for ringtone_default (2873893375149093475) -->
- <skip />
- <!-- no translation found for ringtone_default_with_actual (5474076151665761913) -->
- <skip />
- <!-- no translation found for ringtone_silent (7477159279081654685) -->
- <skip />
- <!-- no translation found for ringtone_picker_title (7055241890764367884) -->
- <skip />
- <!-- no translation found for ringtone_unknown (6888219771401173795) -->
- <skip />
- <!-- no translation found for wifi_available:one (8168012881468888470) -->
- <!-- no translation found for wifi_available:other (4666122955807117718) -->
- <!-- no translation found for wifi_available_detailed:one (5107769161192143259) -->
- <!-- no translation found for wifi_available_detailed:other (853347657960575809) -->
- <!-- no translation found for select_character (3735110139249491726) -->
- <skip />
- <!-- no translation found for sms_control_default_app_name (7522184737840550841) -->
- <skip />
- <!-- no translation found for sms_control_title (2742400596989418394) -->
- <skip />
- <!-- no translation found for sms_control_message (3447126217666595989) -->
- <skip />
- <!-- no translation found for sms_control_yes (8839660939359273650) -->
- <skip />
- <!-- no translation found for sms_control_no (909756849988183801) -->
- <skip />
- <!-- no translation found for date_time_set (2495199891239480952) -->
- <skip />
- <!-- no translation found for default_permission_group (7742780381379652409) -->
- <skip />
- <!-- no translation found for no_permissions (85461124044682315) -->
- <skip />
- <!-- no translation found for perms_hide (4145325555929151849) -->
- <skip />
- <!-- no translation found for perms_show_all (6040194843455403173) -->
- <skip />
- <!-- no translation found for googlewebcontenthelper_loading (2140804350507245589) -->
- <skip />
- <!-- no translation found for usb_storage_title (8699631567051394409) -->
- <skip />
- <!-- no translation found for usb_storage_message (5344039189213308733) -->
- <skip />
- <!-- no translation found for usb_storage_button_mount (6700104384375121662) -->
- <skip />
- <!-- no translation found for usb_storage_button_unmount (465869657252626688) -->
- <skip />
- <!-- no translation found for usb_storage_error_message (3192564550748426087) -->
- <skip />
- <!-- no translation found for usb_storage_notification_title (6237028017872246940) -->
- <skip />
- <!-- no translation found for usb_storage_notification_message (7371717280517625905) -->
- <skip />
- <!-- no translation found for select_input_method (2658280517827502015) -->
- <skip />
- <!-- no translation found for fast_scroll_alphabet (1017432309285755759) -->
- <skip />
- <!-- no translation found for fast_scroll_numeric_alphabet (3092587363718901074) -->
- <skip />
- <!-- no translation found for candidates_style (7738463880139922176) -->
- <skip />
-</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 37632f8..e0c0a64 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -817,6 +817,5 @@
<skip />
<!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
<skip />
- <!-- no translation found for tutorial_double_tap_to_zoom_message (9111326385548696308) -->
<skip />
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 3015957..d9c4174 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -818,6 +818,5 @@
<skip />
<!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
<skip />
- <!-- no translation found for tutorial_double_tap_to_zoom_message (9111326385548696308) -->
<skip />
</resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 4cb3ee1..d9cf3d5 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1,765 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="byteShort">"B"</string>
- <string name="kilobyteShort">"KB"</string>
- <string name="megabyteShort">"MB"</string>
- <string name="gigabyteShort">"GB"</string>
- <string name="terabyteShort">"TB"</string>
- <string name="petabyteShort">"PB"</string>
- <string name="untitled">"&lt;untitled&gt;"</string>
- <string name="ellipsis">"…"</string>
- <string name="emptyPhoneNumber">"(No phone number)"</string>
- <string name="unknownName">"(Unknown)"</string>
- <string name="defaultVoiceMailAlphaTag">"Voicemail"</string>
- <string name="defaultMsisdnAlphaTag">"MSISDN1"</string>
- <string name="mmiError">"Connection problem or invalid MMI code."</string>
- <string name="serviceEnabled">"Service was enabled."</string>
- <string name="serviceEnabledFor">"Service was enabled for:"</string>
- <string name="serviceDisabled">"Service has been disabled."</string>
- <string name="serviceRegistered">"Registration was successful."</string>
- <string name="serviceErased">"Erasure was successful."</string>
- <string name="passwordIncorrect">"Incorrect password."</string>
- <string name="mmiComplete">"MMI complete."</string>
- <string name="badPin">"The old PIN you typed is not correct."</string>
- <string name="badPuk">"The PUK you typed is not correct."</string>
- <string name="mismatchPin">"The PINs you entered do not match."</string>
- <string name="invalidPin">"Type a PIN that is 4 to 8 numbers."</string>
- <!-- no translation found for needPuk (4788728144863892764) -->
- <skip />
- <string name="needPuk2">"Type PUK2 to unblock SIM card."</string>
- <string name="ClipMmi">"Incoming Caller ID"</string>
- <string name="ClirMmi">"Outgoing Caller ID"</string>
- <string name="CfMmi">"Call forwarding"</string>
- <string name="CwMmi">"Call waiting"</string>
- <string name="BaMmi">"Call barring"</string>
- <string name="PwdMmi">"Password change"</string>
- <string name="PinMmi">"PIN change"</string>
- <string name="CLIRDefaultOnNextCallOn">"Caller ID defaults to restricted. Next call: Restricted"</string>
- <string name="CLIRDefaultOnNextCallOff">"Caller ID defaults to restricted. Next call: Not restricted"</string>
- <string name="CLIRDefaultOffNextCallOn">"Caller ID defaults to not restricted. Next call: Restricted"</string>
- <string name="CLIRDefaultOffNextCallOff">"Caller ID defaults to not restricted. Next call: Not restricted"</string>
- <string name="serviceNotProvisioned">"Service not provisioned."</string>
- <string name="CLIRPermanent">"The caller ID setting cannot be changed."</string>
- <string name="serviceClassVoice">"Voice"</string>
- <string name="serviceClassData">"Data"</string>
- <string name="serviceClassFAX">"FAX"</string>
- <string name="serviceClassSMS">"SMS"</string>
- <string name="serviceClassDataAsync">"Async"</string>
- <string name="serviceClassDataSync">"Sync"</string>
- <string name="serviceClassPacket">"Packet"</string>
- <string name="serviceClassPAD">"PAD"</string>
- <string name="cfTemplateNotForwarded">"{0}: Not forwarded"</string>
- <string name="cfTemplateForwarded">"{0}: {1}"</string>
- <string name="cfTemplateForwardedTime">"{0}: {1} after {2} seconds"</string>
- <string name="cfTemplateRegistered">"{0}: Not forwarded"</string>
- <string name="cfTemplateRegisteredTime">"{0}: Not forwarded"</string>
- <string name="httpErrorOk">"OK"</string>
- <string name="httpError">"The Web page contains an error."</string>
- <string name="httpErrorLookup">"The URL could not be found."</string>
- <string name="httpErrorUnsupportedAuthScheme">"The site authentication scheme is not supported."</string>
- <string name="httpErrorAuth">"Authentication was unsuccessful."</string>
- <string name="httpErrorProxyAuth">"Authentication via the proxy server was unsuccessful."</string>
- <string name="httpErrorConnect">"The connection to the server was unsuccessful."</string>
- <string name="httpErrorIO">"The server failed to communicate. Try again later."</string>
- <string name="httpErrorTimeout">"The connection to the server timed out."</string>
- <string name="httpErrorRedirectLoop">"The page contains too many server redirects."</string>
- <string name="httpErrorUnsupportedScheme">"The protocol is not supported."</string>
- <string name="httpErrorFailedSslHandshake">"A secure connection could not be established."</string>
- <string name="httpErrorBadUrl">"The page could not be opened because the URL is invalid."</string>
- <string name="httpErrorFile">"The file could not be accessed."</string>
- <string name="httpErrorFileNotFound">"The requested file was not found."</string>
- <string name="httpErrorTooManyRequests">"Too many requests are being processed. Try again later."</string>
- <string name="contentServiceSync">"Sync"</string>
- <string name="contentServiceSyncNotificationTitle">"Sync"</string>
- <string name="contentServiceTooManyDeletesNotificationDesc">"Too many %s deletes."</string>
- <string name="low_memory">"Phone storage is full! Delete some files to free space."</string>
- <string name="me">"Me"</string>
- <string name="power_dialog">"Phone options"</string>
- <string name="silent_mode">"Silent mode"</string>
- <string name="turn_on_radio">"Turn on wireless"</string>
- <string name="turn_off_radio">"Turn off wireless"</string>
- <string name="screen_lock">"Screen lock"</string>
- <string name="power_off">"Power off"</string>
- <string name="shutdown_progress">"Shutting down…"</string>
- <string name="shutdown_confirm">"Your phone will shut down."</string>
- <string name="no_recent_tasks">"No recent applications."</string>
- <string name="global_actions">"Phone options"</string>
- <string name="global_action_lock">"Screen lock"</string>
- <string name="global_action_power_off">"Power off"</string>
- <string name="global_action_toggle_silent_mode">"Silent mode"</string>
- <string name="global_action_silent_mode_on_status">"Sound is OFF"</string>
- <string name="global_action_silent_mode_off_status">"Sound is ON"</string>
- <string name="safeMode">"Safe mode"</string>
- <string name="permgrouplab_costMoney">"Cost you money"</string>
- <string name="permgroupdesc_costMoney">"Allow applications to do things that can cost you money."</string>
- <string name="permgrouplab_messages">"Your messages"</string>
- <string name="permgroupdesc_messages">"Read and write your SMS, e-mail, and other messages."</string>
- <string name="permgrouplab_personalInfo">"Your personal information"</string>
- <string name="permgroupdesc_personalInfo">"Direct access to your contacts and calendar stored on the phone."</string>
- <string name="permgrouplab_location">"Your location"</string>
- <string name="permgroupdesc_location">"Monitor your physical location"</string>
- <string name="permgrouplab_network">"Network communication"</string>
- <string name="permgroupdesc_network">"Allow applications to access various network features."</string>
- <string name="permgrouplab_accounts">"Your Google accounts"</string>
- <string name="permgroupdesc_accounts">"Access the available Google accounts."</string>
- <string name="permgrouplab_hardwareControls">"Hardware controls"</string>
- <string name="permgroupdesc_hardwareControls">"Direct access to hardware on the handset."</string>
- <string name="permgrouplab_phoneCalls">"Phone calls"</string>
- <string name="permgroupdesc_phoneCalls">"Monitor, record, and process phone calls."</string>
- <string name="permgrouplab_systemTools">"System tools"</string>
- <string name="permgroupdesc_systemTools">"Lower-level access and control of the system."</string>
- <string name="permgrouplab_developmentTools">"Development tools"</string>
- <string name="permgroupdesc_developmentTools">"Features only needed for application developers."</string>
- <string name="permlab_statusBar">"disable or modify status bar"</string>
- <string name="permdesc_statusBar">"Allows application to disable the status bar or add and remove system icons."</string>
- <string name="permlab_expandStatusBar">"expand/collapse status bar"</string>
- <string name="permdesc_expandStatusBar">"Allows application to expand or collapse the status bar."</string>
- <string name="permlab_processOutgoingCalls">"intercept outgoing calls"</string>
- <string name="permdesc_processOutgoingCalls">"Allows application to process outgoing calls and change the number to be dialed. Malicious applications may monitor, redirect, or prevent outgoing calls."</string>
- <string name="permlab_receiveSms">"receive SMS"</string>
- <string name="permdesc_receiveSms">"Allows application to receive and process SMS messages. Malicious applications may monitor your messages or delete them without showing them to you."</string>
- <string name="permlab_receiveMms">"receive MMS"</string>
- <string name="permdesc_receiveMms">"Allows application to receive and process MMS messages. Malicious applications may monitor your messages or delete them without showing them to you."</string>
- <string name="permlab_sendSms">"send SMS messages"</string>
- <string name="permdesc_sendSms">"Allows application to send SMS messages. Malicious applications may cost you money by sending messages without your confirmation."</string>
- <string name="permlab_readSms">"read SMS or MMS"</string>
- <string name="permdesc_readSms">"Allows application to read SMS messages stored on your phone or SIM card. Malicious applications may read your confidential messages."</string>
- <string name="permlab_writeSms">"edit SMS or MMS"</string>
- <string name="permdesc_writeSms">"Allows application to write to SMS messages stored on your phone or SIM card. Malicious applications may delete your messages."</string>
- <string name="permlab_receiveWapPush">"receive WAP"</string>
- <string name="permdesc_receiveWapPush">"Allows application to receive and process WAP messages. Malicious applications may monitor your messages or delete them without showing them to you."</string>
- <string name="permlab_getTasks">"retrieve running applications"</string>
- <string name="permdesc_getTasks">"Allows application to retrieve information about currently and recently running tasks. May allow malicious applications to discover private information about other applications."</string>
- <string name="permlab_reorderTasks">"reorder running applications"</string>
- <string name="permdesc_reorderTasks">"Allows an application to move tasks to the foreground and background. Malicious applications can force themselves to the front without your control."</string>
- <string name="permlab_setDebugApp">"enable application debugging"</string>
- <string name="permdesc_setDebugApp">"Allows an application to turn on debugging for another application. Malicious applications can use this to kill other applications."</string>
- <string name="permlab_changeConfiguration">"change your UI settings"</string>
- <string name="permdesc_changeConfiguration">"Allows an application to change the current configuration, such as the locale or overall font size."</string>
- <string name="permlab_restartPackages">"restart other applications"</string>
- <string name="permdesc_restartPackages">"Allows an application to forcibly restart other applications."</string>
- <string name="permlab_setProcessForeground">"keep from being stopped"</string>
- <!-- unknown placeholder BREAK in permdesc_setProcessForeground -->
- <skip />
- <string name="permlab_forceBack">"force application to close"</string>
- <string name="permdesc_forceBack">"Allows an application to force any activity that is in the foreground to close and go back. Should never be needed for normal applications."</string>
- <string name="permlab_dump">"retrieve system internal state"</string>
- <string name="permdesc_dump">"Allows application to retrieve internal state of the system. Malicious applications may retrieve a wide variety of private and secure information that they should never normally need."</string>
- <string name="permlab_addSystemService">"publish low-level services"</string>
- <string name="permdesc_addSystemService">"Allows application to publish its own low-level system services. Malicious applications may hijack the system, and steal or corrupt any data on it."</string>
- <string name="permlab_runSetActivityWatcher">"monitor and control all application launching"</string>
- <string name="permdesc_runSetActivityWatcher">"Allows an application to monitor and control how the system launches activities. Malicious applications may completely compromise the system. This permission is only needed for development, never for normal phone usage."</string>
- <string name="permlab_broadcastPackageRemoved">"send package removed broadcast"</string>
- <string name="permdesc_broadcastPackageRemoved">"Allows an application to broadcast a notification that an application package has been removed. Malicious applications may use this to kill any other running application."</string>
- <!-- no translation found for permlab_broadcastSmsReceived (1994692154847312518) -->
- <skip />
- <!-- no translation found for permdesc_broadcastSmsReceived (6072362543164841432) -->
- <skip />
- <!-- no translation found for permlab_broadcastWapPush (3070023012636951639) -->
- <skip />
- <!-- no translation found for permdesc_broadcastWapPush (726912255218924336) -->
- <skip />
- <string name="permlab_setProcessLimit">"limit number of running processes"</string>
- <string name="permdesc_setProcessLimit">"Allows an application to control the maximum number of processes that will run. Never needed for normal applications."</string>
- <string name="permlab_setAlwaysFinish">"make all background applications close"</string>
- <string name="permdesc_setAlwaysFinish">"Allows an application to control whether activities are always finished as soon as they go to the background. Never needed for normal applications."</string>
- <string name="permlab_fotaUpdate">"automatically install system updates"</string>
- <string name="permdesc_fotaUpdate">"Allows an application to receive notifications about pending system updates and trigger their installation. Malicious applications may use this to corrupt the system with unauthorized updates, or generally interfere with the update process."</string>
- <string name="permlab_batteryStats">"modify battery statistics"</string>
- <string name="permdesc_batteryStats">"Allows the modification of collected battery statistics. Not for use by normal applications."</string>
- <string name="permlab_internalSystemWindow">"display unauthorized windows"</string>
- <string name="permdesc_internalSystemWindow">"Allows the creation of windows that are intended to be used by the internal system user interface. Not for use by normal applications."</string>
- <string name="permlab_systemAlertWindow">"display system-level alerts"</string>
- <string name="permdesc_systemAlertWindow">"Allows an application to show system alert windows. Malicious applications can take over the entire screen of the phone."</string>
- <string name="permlab_setAnimationScale">"modify global animation speed"</string>
- <string name="permdesc_setAnimationScale">"Allows an application to change the global animation speed (faster or slower animations) at any time."</string>
- <string name="permlab_manageAppTokens">"manage application tokens"</string>
- <string name="permdesc_manageAppTokens">"Allows applications to create and manage their own tokens, bypassing their normal Z-ordering. Should never be needed for normal applications."</string>
- <string name="permlab_injectEvents">"press keys and control buttons"</string>
- <string name="permdesc_injectEvents">"Allows an application to deliver its own input events (key presses, etc.) to other applications. Malicious applications can use this to take over the phone."</string>
- <string name="permlab_readInputState">"record what you type and actions you take"</string>
- <string name="permdesc_readInputState">"Allows applications to watch the keys you press even when interacting with another application (such as entering a password). Should never be needed for normal applications."</string>
- <string name="permlab_setOrientation">"change screen orientation"</string>
- <string name="permdesc_setOrientation">"Allows an application to change the rotation of the screen at any time. Should never be needed for normal applications."</string>
- <string name="permlab_signalPersistentProcesses">"send Linux signals to applications"</string>
- <string name="permdesc_signalPersistentProcesses">"Allows application to request that the supplied signal be sent to all persistent processes."</string>
- <string name="permlab_persistentActivity">"make application always run"</string>
- <!-- unknown placeholder BREAK in permdesc_persistentActivity -->
- <skip />
- <string name="permlab_deletePackages">"delete applications"</string>
- <string name="permdesc_deletePackages">"Allows an application to delete Android packages. Malicious applications can use this to delete important applications."</string>
- <string name="permlab_clearAppUserData">"delete other applications data"</string>
- <string name="permdesc_clearAppUserData">"Allows an application to clear user data."</string>
- <string name="permlab_deleteCacheFiles">"delete other applications cache"</string>
- <string name="permdesc_deleteCacheFiles">"Allows an application to delete cache files."</string>
- <string name="permlab_getPackageSize">"measure application storage space"</string>
- <string name="permdesc_getPackageSize">"Allows an application to retrieve its code, data, and cache sizes"</string>
- <string name="permlab_installPackages">"directly install applications"</string>
- <string name="permdesc_installPackages">"Allows an application to install new or updated Android packages. Malicious applications can use this to add new applications with arbitrarily powerful permissions."</string>
- <string name="permlab_clearAppCache">"delete all application cache data"</string>
- <string name="permdesc_clearAppCache">"Allows an application to free phone storage by deleting files in application cache directory. Access is very restricted usually to system process."</string>
- <string name="permlab_readLogs">"read system log files"</string>
- <!-- unknown placeholder BREAK_0 in permdesc_readLogs -->
- <skip />
- <!-- no translation found for permlab_diagnostic (2955142476313469329) -->
- <skip />
- <!-- no translation found for permdesc_diagnostic (1282409892215520166) -->
- <skip />
- <string name="permlab_changeComponentState">"enable or disable application components"</string>
- <string name="permdesc_changeComponentState">"Allows an application to change whether a component of another application is enabled or not. Malicious applications can use this to disable important phone capabilities. Care must be used with permission, as it is possible to get application components into an unusable, inconsistant, or unstable state."</string>
- <string name="permlab_setPreferredApplications">"set preferred applications"</string>
- <string name="permdesc_setPreferredApplications">"Allows an application to modify your preferred applications. This can allow malicious applications to silently change the applications that are run, spoofing your existing applications to collect private data from you."</string>
- <string name="permlab_writeSettings">"modify global system settings"</string>
- <string name="permdesc_writeSettings">"Allows an application to modify the systems settings data. Malicious applications can corrupt your systems configuration."</string>
- <!-- no translation found for permlab_writeSecureSettings (4851801872124242319) -->
- <skip />
- <!-- no translation found for permdesc_writeSecureSettings (2080620249472761366) -->
- <skip />
- <!-- no translation found for permlab_writeGservices (296370685945777755) -->
- <skip />
- <!-- no translation found for permdesc_writeGservices (2496928471286495053) -->
- <skip />
- <string name="permlab_receiveBootCompleted">"automatically start at boot"</string>
- <string name="permdesc_receiveBootCompleted">"Allows an application to have itself started as soon as the system has finished booting. This can make it take longer to start the phone and allow the application to slow down the overall phone by always running."</string>
- <string name="permlab_broadcastSticky">"send sticky broadcast"</string>
- <string name="permdesc_broadcastSticky">"Allows an application to send sticky broadcasts, which remain after the broadcast ends. Malicious applications can make the phone slow or unstable by causing it to use too much memory."</string>
- <string name="permlab_readContacts">"read contact data"</string>
- <string name="permdesc_readContacts">"Allows an application to read all of the contact (address) data stored on your phone. Malicious applications can use this to send your data to other people."</string>
- <string name="permlab_writeContacts">"write contact data"</string>
- <string name="permdesc_writeContacts">"Allows an application to modify the contact (address) data stored on your phone. Malicious applications can use this to erase or modify your contact data."</string>
- <string name="permlab_writeOwnerData">"write owner data"</string>
- <string name="permdesc_writeOwnerData">"Allows an application to modify the phone owner data stored on your phone. Malicious applications can use this to erase or modify owner data."</string>
- <string name="permlab_readOwnerData">"read owner data"</string>
- <string name="permdesc_readOwnerData">"Allows an application read the phone owner data stored on your phone. Malicious applications can use this to read phone owner data."</string>
- <string name="permlab_readCalendar">"read calendar data"</string>
- <string name="permdesc_readCalendar">"Allows an application to read all of the calendar events stored on your phone. Malicious applications can use this to send your calendar events to other people."</string>
- <string name="permlab_writeCalendar">"write calendar data"</string>
- <string name="permdesc_writeCalendar">"Allows an application to modify the calendar events stored on your phone. Malicious applications can use this to erase or modify your calendar data."</string>
- <string name="permlab_accessMockLocation">"mock location sources for testing"</string>
- <string name="permdesc_accessMockLocation">"Create mock location sources for testing. Malicious applications can use this to override the location and/or status returned by real location sources such as GPS or Network providers."</string>
- <!-- no translation found for permlab_accessLocationExtraCommands (8291822077788811687) -->
- <skip />
- <!-- no translation found for permdesc_accessLocationExtraCommands (5135782633548630731) -->
- <skip />
- <string name="permlab_accessFineLocation">"fine (GPS) location"</string>
- <string name="permdesc_accessFineLocation">"Access fine location sources such as the Global Positioning System on the phone, where available. Malicious applications can use this to determine where you are, and may consume additional battery power."</string>
- <string name="permlab_accessCoarseLocation">"coarse (network-based) location"</string>
- <string name="permdesc_accessCoarseLocation">"Access coarse location sources such as the cellular network database to determine an approximate phone location, where available. Malicious applications can use this to determine approximately where you are."</string>
- <string name="permlab_accessSurfaceFlinger">"access SurfaceFlinger"</string>
- <string name="permdesc_accessSurfaceFlinger">"Allows application to use SurfaceFlinger low-level features."</string>
- <string name="permlab_readFrameBuffer">"read frame buffer"</string>
- <string name="permdesc_readFrameBuffer">"Allows application to use read the content of the frame buffer."</string>
- <string name="permlab_modifyAudioSettings">"change your audio settings"</string>
- <string name="permdesc_modifyAudioSettings">"Allows application to modify global audio settings such as volume and routing."</string>
- <string name="permlab_recordAudio">"record audio"</string>
- <string name="permdesc_recordAudio">"Allows application to access the audio record path."</string>
- <string name="permlab_camera">"take pictures"</string>
- <string name="permdesc_camera">"Allows application to take pictures with the camera. This allows the application at any time to collect images the camera is seeing."</string>
- <string name="permlab_brick">"permanently disable phone"</string>
- <string name="permdesc_brick">"Allows the application to disable the entire phone permanently. This is very dangerous."</string>
- <!-- no translation found for permlab_reboot (8844650672567077423) -->
- <skip />
- <!-- no translation found for permdesc_reboot (4704919552870918328) -->
- <skip />
- <string name="permlab_mount_unmount_filesystems">"mount and unmount filesystems"</string>
- <string name="permdesc_mount_unmount_filesystems">"Allows the application to mount and unmount filesystems for removable storage."</string>
- <string name="permlab_vibrate">"control vibrator"</string>
- <string name="permdesc_vibrate">"Allows the application to control the vibrator."</string>
- <string name="permlab_flashlight">"control flashlight"</string>
- <string name="permdesc_flashlight">"Allows the application to control the flashlight."</string>
- <string name="permlab_hardware_test">"test hardware"</string>
- <string name="permdesc_hardware_test">"Allows the application to control various peripherals for the purpose of hardware testing."</string>
- <string name="permlab_callPhone">"directly call phone numbers"</string>
- <string name="permdesc_callPhone">"Allows the application to call phone numbers without your intervention. Malicious applications may cause unexpected calls on your phone bill. Note that this does not allow the application to call emergency numbers."</string>
- <!-- no translation found for permlab_callPrivileged (2166923597287697159) -->
- <skip />
- <!-- no translation found for permdesc_callPrivileged (5109789447971735501) -->
- <skip />
- <!-- no translation found for permlab_locationUpdates (4216418293360456836) -->
- <skip />
- <!-- no translation found for permdesc_locationUpdates (7635814693478743648) -->
- <skip />
- <!-- no translation found for permlab_checkinProperties (2260796787386280708) -->
- <skip />
- <!-- no translation found for permdesc_checkinProperties (3508022022841741945) -->
- <skip />
- <string name="permlab_modifyPhoneState">"modify phone state"</string>
- <string name="permdesc_modifyPhoneState">"Allows the application to control the phone features of the device. An application with this permission can switch networks, turn the phone radio on and off and the like without ever notifying you."</string>
- <string name="permlab_readPhoneState">"read phone state"</string>
- <string name="permdesc_readPhoneState">"Allows the application to access the phone features of the device. An application with this permission can determine the phone number of this phone, whether a call is active, the number that call is connected to and the like."</string>
- <string name="permlab_wakeLock">"prevent phone from sleeping"</string>
- <string name="permdesc_wakeLock">"Allows an application to prevent the phone from going to sleep."</string>
- <string name="permlab_devicePower">"power phone on or off"</string>
- <string name="permdesc_devicePower">"Allows the application to turn the phone on or off."</string>
- <string name="permlab_factoryTest">"run in factory test mode"</string>
- <string name="permdesc_factoryTest">"Run as a low-level manufacturer test, allowing complete access to the phone hardware. Only available when a phone is running in manufacturer test mode."</string>
- <string name="permlab_setWallpaper">"set wallpaper"</string>
- <string name="permdesc_setWallpaper">"Allows the application to set the system wallpaper."</string>
- <string name="permlab_setWallpaperHints">"set wallpaper size hints"</string>
- <string name="permdesc_setWallpaperHints">"Allows the application to set the system wallpaper size hints."</string>
- <string name="permlab_masterClear">"reset system to factory defaults"</string>
- <string name="permdesc_masterClear">"Allows an application to completely reset the system to its factory settings, erasing all data, configuration, and installed applications."</string>
- <string name="permlab_setTimeZone">"set time zone"</string>
- <string name="permdesc_setTimeZone">"Allows an application to change the phones time zone."</string>
- <string name="permlab_getAccounts">"discover known accounts"</string>
- <string name="permdesc_getAccounts">"Allows an application to get the list of accounts known by the phone."</string>
- <string name="permlab_accessNetworkState">"view network state"</string>
- <string name="permdesc_accessNetworkState">"Allows an application to view the state of all networks."</string>
- <string name="permlab_createNetworkSockets">"full Internet access"</string>
- <string name="permdesc_createNetworkSockets">"Allows an application to create network sockets."</string>
- <!-- no translation found for permlab_writeApnSettings (3190585220761979369) -->
- <skip />
- <!-- no translation found for permdesc_writeApnSettings (4093875220468761052) -->
- <skip />
- <string name="permlab_changeNetworkState">"change network connectivity"</string>
- <string name="permdesc_changeNetworkState">"Allows an application to change the state network connectivity."</string>
- <string name="permlab_accessWifiState">"view Wi-Fi state"</string>
- <string name="permdesc_accessWifiState">"Allows an application to view the information about the state of Wi-Fi."</string>
- <string name="permlab_changeWifiState">"change Wi-Fi state"</string>
- <string name="permdesc_changeWifiState">"Allows an application to connect to and disconnect from Wi-Fi access points, and to make changes to configured Wi-Fi networks."</string>
- <string name="permlab_bluetoothAdmin">"bluetooth administration"</string>
- <string name="permdesc_bluetoothAdmin">"Allows an application to configure the local Bluetooth phone, and to discover and pair with remote devices."</string>
- <string name="permlab_bluetooth">"create Bluetooth connections"</string>
- <string name="permdesc_bluetooth">"Allows an application to view configuration of the local Bluetooth phone, and to make and accept connections with paired devices."</string>
- <string name="permlab_disableKeyguard">"disable keylock"</string>
- <string name="permdesc_disableKeyguard">"Allows an application to disable the keylock and any associated password security. A legitimate example of this is the phone disabling the keylock when receiving an incoming phone call, then re-enabling the keylock when the call is finished."</string>
- <string name="permlab_readSyncSettings">"read sync settings"</string>
- <string name="permdesc_readSyncSettings">"Allows an application to read the sync settings, such as whether sync is enabled for Contacts."</string>
- <string name="permlab_writeSyncSettings">"write sync settings"</string>
- <string name="permdesc_writeSyncSettings">"Allows an application to modify the sync settings, such as whether sync is enabled for Contacts."</string>
- <string name="permlab_readSyncStats">"read sync statistics"</string>
- <string name="permdesc_readSyncStats">"Allows an application to reafocusd the sync stats; e.g., the history of syncs that have occurred."</string>
- <!-- no translation found for permlab_subscribedFeedsRead (2043206814904506589) -->
- <skip />
- <!-- no translation found for permdesc_subscribedFeedsRead (6977343942680042449) -->
- <skip />
- <!-- no translation found for permlab_subscribedFeedsWrite (2556727307229571556) -->
- <skip />
- <!-- no translation found for permdesc_subscribedFeedsWrite (4134783294590266220) -->
- <skip />
- <!-- no translation found for phoneTypes:0 (6070018634209800981) -->
- <!-- no translation found for phoneTypes:1 (1514509689885965711) -->
- <!-- no translation found for phoneTypes:2 (497473201754095234) -->
- <!-- no translation found for phoneTypes:3 (5554432614281047787) -->
- <!-- no translation found for phoneTypes:4 (2222084401110150993) -->
- <!-- no translation found for phoneTypes:5 (2290007103906353121) -->
- <!-- no translation found for phoneTypes:6 (6930783706213719251) -->
- <!-- no translation found for phoneTypes:7 (1326005699931077792) -->
- <!-- no translation found for emailAddressTypes:0 (1540640638077615417) -->
- <!-- no translation found for emailAddressTypes:1 (4252853367575831977) -->
- <!-- no translation found for emailAddressTypes:2 (7158046581744435718) -->
- <!-- no translation found for emailAddressTypes:3 (3625034471181268169) -->
- <!-- no translation found for postalAddressTypes:0 (5732960259696659380) -->
- <!-- no translation found for postalAddressTypes:1 (7132240704786130285) -->
- <!-- no translation found for postalAddressTypes:2 (1317604357745852817) -->
- <!-- no translation found for postalAddressTypes:3 (1582953598462826702) -->
- <!-- no translation found for imAddressTypes:0 (7806620012096518833) -->
- <!-- no translation found for imAddressTypes:1 (5748846799950672787) -->
- <!-- no translation found for imAddressTypes:2 (6196536810275073680) -->
- <!-- no translation found for imAddressTypes:3 (8519128375350623648) -->
- <!-- no translation found for organizationTypes:0 (1299224825223821142) -->
- <!-- no translation found for organizationTypes:1 (2455717447227299354) -->
- <!-- no translation found for organizationTypes:2 (7027570839313438290) -->
- <!-- no translation found for imProtocols:0 (3318725788774688043) -->
- <!-- no translation found for imProtocols:1 (1787713387022932886) -->
- <!-- no translation found for imProtocols:2 (6751174158442316516) -->
- <!-- no translation found for imProtocols:3 (1151283347465052653) -->
- <!-- no translation found for imProtocols:4 (2157980008878817934) -->
- <!-- no translation found for imProtocols:5 (7836237460308230767) -->
- <!-- no translation found for imProtocols:6 (1180789904462172516) -->
- <!-- no translation found for imProtocols:7 (21955111672779862) -->
- <string name="keyguard_password_enter_pin_code">"Enter PIN code:"</string>
- <string name="keyguard_password_wrong_pin_code">"Incorrect PIN code!"</string>
- <string name="keyguard_label_text">"To unlock, press Menu then 0."</string>
- <string name="emergency_call_dialog_number_for_display">"Emergency number"</string>
- <string name="lockscreen_carrier_default">"(No service)"</string>
- <string name="lockscreen_screen_locked">"Screen locked"</string>
- <string name="lockscreen_instructions_when_pattern_enabled">"Press Menu to unlock or place emergency call."</string>
- <string name="lockscreen_instructions_when_pattern_disabled">"Press Menu to unlock."</string>
- <string name="lockscreen_pattern_instructions">"Draw pattern to unlock:"</string>
- <string name="lockscreen_emergency_call">"Emergency call"</string>
- <string name="lockscreen_pattern_correct">"Correct!"</string>
- <string name="lockscreen_pattern_wrong">"Sorry, try again:"</string>
- <string name="lockscreen_plugged_in">"Charging (<xliff:g id="NUMBER">%d%%</xliff:g>)"</string>
- <string name="lockscreen_low_battery">"Connect your charger."</string>
- <string name="lockscreen_missing_sim_message_short">"No SIM card."</string>
- <string name="lockscreen_missing_sim_message">"No SIM card in phone."</string>
- <string name="lockscreen_missing_sim_instructions">"Please insert a SIM card."</string>
- <!-- no translation found for lockscreen_network_locked_message (323609607922245071) -->
- <skip />
- <string name="lockscreen_sim_puk_locked_message">"SIM card is PUK-locked."</string>
- <string name="lockscreen_sim_puk_locked_instructions">"Please contact Customer Care."</string>
- <string name="lockscreen_sim_locked_message">"SIM card is locked."</string>
- <string name="lockscreen_sim_unlock_progress_dialog_message">"Unlocking SIM card…"</string>
- <string name="lockscreen_too_many_failed_attempts_dialog_message">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. "\n\n"Please try again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
- <string name="lockscreen_failed_attempts_almost_glogin">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using your Google sign-in."\n\n" Please try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
- <string name="lockscreen_too_many_failed_attempts_countdown">"Try again in <xliff:g id="NUMBER">%d</xliff:g> seconds."</string>
- <string name="lockscreen_forgot_pattern_button_text">"Forgot pattern?"</string>
- <string name="lockscreen_glogin_too_many_attempts">"Too many pattern attempts!"</string>
- <string name="lockscreen_glogin_instructions">"To unlock,"\n"sign in with your Google account:"</string>
- <string name="lockscreen_glogin_username_hint">"Username (email)"</string>
- <string name="lockscreen_glogin_password_hint">"Password"</string>
- <string name="lockscreen_glogin_submit_button">"Sign in"</string>
- <string name="lockscreen_glogin_invalid_input">"Invalid username or password."</string>
- <!-- unknown placeholder FORMAT in status_bar_time_format -->
- <skip />
- <!-- no translation found for hour_minute_ampm (1850330605794978742) -->
- <skip />
- <!-- no translation found for hour_minute_cap_ampm (1122840227537374196) -->
- <skip />
- <!-- no translation found for hour_ampm (7665432130905376251) -->
- <skip />
- <!-- no translation found for hour_cap_ampm (3600295014648400268) -->
- <skip />
- <string name="status_bar_clear_all_button">"Clear notifications"</string>
- <string name="status_bar_no_notifications_title">"No notifications"</string>
- <string name="status_bar_ongoing_events_title">"Ongoing"</string>
- <string name="status_bar_latest_events_title">"Notifications"</string>
- <string name="battery_status_text_percent_format">"<xliff:g id="NUMBER">%d</xliff:g>"</string>
- <string name="battery_status_charging">"Charging…"</string>
- <string name="battery_low_title">"Please connect charger"</string>
- <string name="battery_low_subtitle">"The battery is getting low:"</string>
- <string name="battery_low_percent_format">"less than <xliff:g id="NUMBER">%d%%</xliff:g> remaining."</string>
- <string name="factorytest_failed">"Factory test failed"</string>
- <string name="factorytest_not_system">"The FACTORY_TEST action is only supported for packages installed in /system/app."</string>
- <string name="factorytest_no_action">"No package was found that provides the FACTORY_TEST action."</string>
- <string name="factorytest_reboot">"Reboot"</string>
- <string name="save_password_label">"Confirm"</string>
- <string name="save_password_message">"Do you want the browser to remember this password?"</string>
- <string name="save_password_notnow">"Not now"</string>
- <string name="save_password_remember">"Remember"</string>
- <string name="save_password_never">"Never"</string>
- <string name="open_permission_deny">"You do not have permission to open this page."</string>
- <string name="text_copied">"Text copied to clipboard."</string>
- <string name="more_item_label">"More"</string>
- <string name="prepend_shortcut_label">"Menu+"</string>
- <!-- no translation found for menu_space_shortcut_label (194586306440382711) -->
- <skip />
- <!-- no translation found for menu_enter_shortcut_label (7214761412193519345) -->
- <skip />
- <!-- no translation found for menu_delete_shortcut_label (2854936426194985313) -->
- <skip />
- <string name="search_go">"Search"</string>
- <string name="today">"Today"</string>
- <string name="yesterday">"Yesterday"</string>
- <string name="tomorrow">"Tomorrow"</string>
- <string name="oneMonthDurationPast">"1 month ago"</string>
- <!-- no translation found for beforeOneMonthDurationPast (7578100953282866827) -->
- <skip />
- <!-- no translation found for num_seconds_ago:one (7416512229671810725) -->
- <!-- no translation found for num_seconds_ago:other (8138756910300398447) -->
- <!-- no translation found for num_minutes_ago:one (8620869479299420562) -->
- <!-- no translation found for num_minutes_ago:other (5065488162050522741) -->
- <!-- no translation found for num_hours_ago:one (853404611989669641) -->
- <!-- no translation found for num_hours_ago:other (3558873784561756849) -->
- <!-- no translation found for num_days_ago:one (4222479980812128212) -->
- <!-- no translation found for num_days_ago:other (5445701370433601703) -->
- <!-- no translation found for in_num_seconds:one (4253290037777327003) -->
- <!-- no translation found for in_num_seconds:other (1280033870920841404) -->
- <!-- no translation found for in_num_minutes:one (1487585791027953091) -->
- <!-- no translation found for in_num_minutes:other (6274204576475209932) -->
- <!-- no translation found for in_num_hours:one (6501470863235186391) -->
- <!-- no translation found for in_num_hours:other (4415358752953289251) -->
- <!-- no translation found for in_num_days:one (5608475533104443893) -->
- <!-- no translation found for in_num_days:other (3827193006163842267) -->
- <string name="preposition_for_date">"on %s"</string>
- <string name="preposition_for_time">"at %s"</string>
- <string name="preposition_for_year">"in %s"</string>
- <string name="day">"day"</string>
- <string name="days">"days"</string>
- <string name="hour">"hour"</string>
- <string name="hours">"hours"</string>
- <string name="minute">"min"</string>
- <string name="minutes">"mins"</string>
- <string name="second">"sec"</string>
- <string name="seconds">"secs"</string>
- <string name="week">"week"</string>
- <string name="weeks">"weeks"</string>
- <string name="year">"year"</string>
- <string name="years">"years"</string>
- <string name="sunday">"Sunday"</string>
- <string name="monday">"Monday"</string>
- <string name="tuesday">"Tuesday"</string>
- <string name="wednesday">"Wednesday"</string>
- <string name="thursday">"Thursday"</string>
- <string name="friday">"Friday"</string>
- <string name="saturday">"Saturday"</string>
- <string name="every_weekday">"Every weekday (Mon–Fri)"</string>
- <string name="daily">"Daily"</string>
- <string name="weekly">"Weekly on <xliff:g id="DAY">%s</xliff:g>"</string>
- <string name="monthly">"Monthly"</string>
- <string name="yearly">"Yearly"</string>
- <string name="VideoView_error_title">"Cannot play video"</string>
- <string name="VideoView_error_text_unknown">"Sorry, this video cannot be played."</string>
- <string name="VideoView_error_button">"OK"</string>
- <string name="am">"AM"</string>
- <string name="pm">"PM"</string>
- <!-- unknown placeholder FORMAT in numeric_date -->
- <skip />
- <!-- unknown placeholder FORMAT in wday1_date1_time1_wday2_date2_time2 -->
- <skip />
- <!-- unknown placeholder FORMAT in wday1_date1_wday2_date2 -->
- <skip />
- <!-- unknown placeholder FORMAT in date1_time1_date2_time2 -->
- <skip />
- <!-- unknown placeholder FORMAT in date1_date2 -->
- <skip />
- <!-- unknown placeholder FORMAT in time1_time2 -->
- <skip />
- <!-- unknown placeholder FORMAT in time_wday_date -->
- <skip />
- <!-- unknown placeholder FORMAT in wday_date -->
- <skip />
- <!-- unknown placeholder FORMAT in time_date -->
- <skip />
- <!-- unknown placeholder FORMAT in time_wday -->
- <skip />
- <!-- no translation found for full_date_month_first (6011143962222283357) -->
- <skip />
- <!-- no translation found for full_date_day_first (8621594762705478189) -->
- <skip />
- <!-- no translation found for medium_date_month_first (48990963718825728) -->
- <skip />
- <!-- no translation found for medium_date_day_first (2898992016440387123) -->
- <skip />
- <!-- no translation found for twelve_hour_time_format (6015557937879492156) -->
- <skip />
- <!-- no translation found for twenty_four_hour_time_format (5176807998669709535) -->
- <skip />
- <string name="noon">"noon"</string>
- <string name="Noon">"Noon"</string>
- <string name="midnight">"midnight"</string>
- <string name="Midnight">"Midnight"</string>
- <!-- unknown placeholder FORMAT in month_day -->
- <skip />
- <!-- unknown placeholder FORMAT in month -->
- <skip />
- <!-- unknown placeholder FORMAT in month_day_year -->
- <skip />
- <!-- unknown placeholder FORMAT in month_year -->
- <skip />
- <!-- no translation found for time_of_day (8375993139317154157) -->
- <skip />
- <!-- no translation found for date_and_time (9197690194373107109) -->
- <skip />
- <!-- unknown placeholder FORMAT in same_year_md1_md2 -->
- <skip />
- <!-- unknown placeholder FORMAT in same_year_wday1_md1_wday2_md2 -->
- <skip />
- <!-- unknown placeholder FORMAT in same_year_mdy1_mdy2 -->
- <skip />
- <!-- unknown placeholder FORMAT in same_year_wday1_mdy1_wday2_mdy2 -->
- <skip />
- <!-- unknown placeholder FORMAT in same_year_md1_time1_md2_time2 -->
- <skip />
- <!-- unknown placeholder FORMAT in same_year_wday1_md1_time1_wday2_md2_time2 -->
- <skip />
- <!-- unknown placeholder FORMAT in same_year_mdy1_time1_mdy2_time2 -->
- <skip />
- <!-- unknown placeholder FORMAT in same_year_wday1_mdy1_time1_wday2_mdy2_time2 -->
- <skip />
- <!-- unknown placeholder FORMAT in numeric_md1_md2 -->
- <skip />
- <!-- unknown placeholder FORMAT in numeric_wday1_md1_wday2_md2 -->
- <skip />
- <!-- unknown placeholder FORMAT in numeric_mdy1_mdy2 -->
- <skip />
- <!-- unknown placeholder FORMAT in numeric_wday1_mdy1_wday2_mdy2 -->
- <skip />
- <!-- unknown placeholder FORMAT in numeric_md1_time1_md2_time2 -->
- <skip />
- <!-- unknown placeholder FORMAT in numeric_wday1_md1_time1_wday2_md2_time2 -->
- <skip />
- <!-- unknown placeholder FORMAT in numeric_mdy1_time1_mdy2_time2 -->
- <skip />
- <!-- unknown placeholder FORMAT in numeric_wday1_mdy1_time1_wday2_mdy2_time2 -->
- <skip />
- <!-- unknown placeholder FORMAT in same_month_md1_md2 -->
- <skip />
- <!-- unknown placeholder FORMAT in same_month_wday1_md1_wday2_md2 -->
- <skip />
- <!-- unknown placeholder FORMAT in same_month_mdy1_mdy2 -->
- <skip />
- <!-- unknown placeholder FORMAT in same_month_wday1_mdy1_wday2_mdy2 -->
- <skip />
- <!-- unknown placeholder FORMAT in same_month_md1_time1_md2_time2 -->
- <skip />
- <!-- unknown placeholder FORMAT in same_month_wday1_md1_time1_wday2_md2_time2 -->
- <skip />
- <!-- unknown placeholder FORMAT in same_month_mdy1_time1_mdy2_time2 -->
- <skip />
- <!-- unknown placeholder FORMAT in same_month_wday1_mdy1_time1_wday2_mdy2_time2 -->
- <skip />
- <!-- unknown placeholder FORMAT in abbrev_month_day_year -->
- <skip />
- <!-- unknown placeholder FORMAT in abbrev_month_year -->
- <skip />
- <!-- unknown placeholder FORMAT in abbrev_month_day -->
- <skip />
- <!-- unknown placeholder FORMAT in abbrev_month -->
- <skip />
- <string name="day_of_week_long_sunday">"Sunday"</string>
- <string name="day_of_week_long_monday">"Monday"</string>
- <string name="day_of_week_long_tuesday">"Tuesday"</string>
- <string name="day_of_week_long_wednesday">"Wednesday"</string>
- <string name="day_of_week_long_thursday">"Thursday"</string>
- <string name="day_of_week_long_friday">"Friday"</string>
- <string name="day_of_week_long_saturday">"Saturday"</string>
- <string name="day_of_week_medium_sunday">"Sun"</string>
- <string name="day_of_week_medium_monday">"Mon"</string>
- <string name="day_of_week_medium_tuesday">"Tue"</string>
- <string name="day_of_week_medium_wednesday">"Wed"</string>
- <string name="day_of_week_medium_thursday">"Thu"</string>
- <string name="day_of_week_medium_friday">"Fri"</string>
- <string name="day_of_week_medium_saturday">"Sat"</string>
- <string name="day_of_week_short_sunday">"Su"</string>
- <string name="day_of_week_short_monday">"Mo"</string>
- <string name="day_of_week_short_tuesday">"Tu"</string>
- <string name="day_of_week_short_wednesday">"We"</string>
- <string name="day_of_week_short_thursday">"Th"</string>
- <string name="day_of_week_short_friday">"Fr"</string>
- <string name="day_of_week_short_saturday">"Sa"</string>
- <string name="day_of_week_shorter_sunday">"Su"</string>
- <string name="day_of_week_shorter_monday">"M"</string>
- <string name="day_of_week_shorter_tuesday">"Tu"</string>
- <string name="day_of_week_shorter_wednesday">"W"</string>
- <string name="day_of_week_shorter_thursday">"Th"</string>
- <string name="day_of_week_shorter_friday">"F"</string>
- <string name="day_of_week_shorter_saturday">"Sa"</string>
- <string name="day_of_week_shortest_sunday">"S"</string>
- <string name="day_of_week_shortest_monday">"M"</string>
- <string name="day_of_week_shortest_tuesday">"T"</string>
- <string name="day_of_week_shortest_wednesday">"W"</string>
- <string name="day_of_week_shortest_thursday">"T"</string>
- <string name="day_of_week_shortest_friday">"F"</string>
- <string name="day_of_week_shortest_saturday">"S"</string>
- <string name="month_long_january">"January"</string>
- <string name="month_long_february">"February"</string>
- <string name="month_long_march">"March"</string>
- <string name="month_long_april">"April"</string>
- <string name="month_long_may">"May"</string>
- <string name="month_long_june">"June"</string>
- <string name="month_long_july">"July"</string>
- <string name="month_long_august">"August"</string>
- <string name="month_long_september">"September"</string>
- <string name="month_long_october">"October"</string>
- <string name="month_long_november">"November"</string>
- <string name="month_long_december">"December"</string>
- <string name="month_medium_january">"Jan"</string>
- <string name="month_medium_february">"Feb"</string>
- <string name="month_medium_march">"Mar"</string>
- <string name="month_medium_april">"Apr"</string>
- <string name="month_medium_may">"May"</string>
- <string name="month_medium_june">"Jun"</string>
- <string name="month_medium_july">"Jul"</string>
- <string name="month_medium_august">"Aug"</string>
- <string name="month_medium_september">"Sep"</string>
- <string name="month_medium_october">"Oct"</string>
- <string name="month_medium_november">"Nov"</string>
- <string name="month_medium_december">"Dec"</string>
- <string name="month_shortest_january">"J"</string>
- <string name="month_shortest_february">"F"</string>
- <string name="month_shortest_march">"M"</string>
- <string name="month_shortest_april">"A"</string>
- <string name="month_shortest_may">"M"</string>
- <string name="month_shortest_june">"J"</string>
- <string name="month_shortest_july">"J"</string>
- <string name="month_shortest_august">"A"</string>
- <string name="month_shortest_september">"S"</string>
- <string name="month_shortest_october">"O"</string>
- <string name="month_shortest_november">"N"</string>
- <string name="month_shortest_december">"D"</string>
- <!-- unknown placeholder FORMAT in elapsed_time_short_format_mm_ss -->
- <skip />
- <!-- unknown placeholder FORMAT in elapsed_time_short_format_h_mm_ss -->
- <skip />
- <string name="selectAll">"Select all"</string>
- <string name="cut">"Cut"</string>
- <string name="cutAll">"Cut all"</string>
- <string name="copy">"Copy"</string>
- <string name="copyAll">"Copy all"</string>
- <string name="paste">"Paste"</string>
- <string name="copyUrl">"Copy URL"</string>
- <!-- no translation found for inputMethod (7911866729148111492) -->
- <skip />
- <!-- no translation found for editTextMenuTitle (3984253728638788023) -->
- <skip />
- <string name="low_internal_storage_view_title">"Low on space"</string>
- <string name="low_internal_storage_view_text">"Your phone is running low on internal storage space."</string>
- <string name="ok">"OK"</string>
- <string name="cancel">"Cancel"</string>
- <string name="yes">"OK"</string>
- <string name="no">"Cancel"</string>
- <string name="capital_on">"ON"</string>
- <string name="capital_off">"OFF"</string>
- <string name="whichApplication">"Complete action using"</string>
- <string name="alwaysUse">"Use by default for this action."</string>
- <string name="clearDefaultHintMsg">"Clear default in Home Settings &gt; Applications &gt; Manage applications."</string>
- <string name="chooseActivity">"Select an action"</string>
- <string name="noApplications">"No applications can perform this action."</string>
- <string name="aerr_title">"Sorry!"</string>
- <string name="aerr_application">"The application <xliff:g id="APPLICATION">%1$s</xliff:g> (process <xliff:g id="PROCESS">%2$s</xliff:g>) has stopped unexpectedly. Please try again."</string>
- <string name="aerr_process">"The process <xliff:g id="PROCESS">%1$s</xliff:g> has stopped unexpectedly. Please try again."</string>
- <string name="anr_title">"Application unresponsive"</string>
- <string name="anr_activity_application">"Activity <xliff:g id="ACTIVITY">%1$s</xliff:g> (in application <xliff:g id="APPLICATION">%2$s</xliff:g>) is not responding."</string>
- <string name="anr_activity_process">"Activity <xliff:g id="ACTIVITY">%1$s</xliff:g> (in process <xliff:g id="PROCESS">%2$s</xliff:g>) is not responding."</string>
- <string name="anr_application_process">"Application <xliff:g id="APPLICATION">%1$s</xliff:g> (in process <xliff:g id="PROCESS">%2$s</xliff:g>) is not responding."</string>
- <string name="anr_process">"Process <xliff:g id="PROCESS">%1$s</xliff:g> is not responding."</string>
- <string name="force_close">"Force close"</string>
- <string name="wait">"Wait"</string>
- <string name="debug">"Debug"</string>
- <string name="sendText">"Select an action for text"</string>
- <string name="volume_ringtone">"Ringer volume"</string>
- <string name="volume_music">"Music/video volume"</string>
- <string name="volume_call">"In-call volume"</string>
- <string name="volume_alarm">"Alarm volume"</string>
- <string name="volume_unknown">"Volume"</string>
- <string name="ringtone_default">"Default ringtone"</string>
- <string name="ringtone_default_with_actual">"Default ringtone (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
- <string name="ringtone_silent">"Silent"</string>
- <string name="ringtone_picker_title">"Select a ringtone"</string>
- <string name="ringtone_unknown">"Unknown ringtone"</string>
- <!-- no translation found for wifi_available:one (8168012881468888470) -->
- <!-- no translation found for wifi_available:other (4666122955807117718) -->
- <!-- no translation found for wifi_available_detailed:one (5107769161192143259) -->
- <!-- no translation found for wifi_available_detailed:other (853347657960575809) -->
- <string name="select_character">"Select character to insert"</string>
- <!-- no translation found for sms_control_default_app_name (7522184737840550841) -->
- <skip />
- <string name="sms_control_title">"Sending SMS messages"</string>
- <string name="sms_control_message">"A large number of SMS messages are being sent. Select \"OK\" to continue, or \"Cancel\" to stop sending."</string>
- <string name="sms_control_yes">"OK"</string>
- <string name="sms_control_no">"Cancel"</string>
- <string name="date_time_set">"Set"</string>
- <string name="default_permission_group">"Default"</string>
- <string name="no_permissions">"No permissions required"</string>
- <!-- no translation found for perms_hide (4145325555929151849) -->
- <skip />
- <!-- no translation found for perms_show_all (6040194843455403173) -->
- <skip />
- <!-- no translation found for googlewebcontenthelper_loading (2140804350507245589) -->
- <skip />
- <!-- no translation found for usb_storage_title (8699631567051394409) -->
- <skip />
- <!-- no translation found for usb_storage_message (5344039189213308733) -->
- <skip />
- <!-- no translation found for usb_storage_button_mount (6700104384375121662) -->
- <skip />
- <!-- no translation found for usb_storage_button_unmount (465869657252626688) -->
- <skip />
- <!-- no translation found for usb_storage_error_message (3192564550748426087) -->
- <skip />
- <!-- no translation found for usb_storage_notification_title (6237028017872246940) -->
- <skip />
- <!-- no translation found for usb_storage_notification_message (7371717280517625905) -->
- <skip />
- <!-- no translation found for select_input_method (2658280517827502015) -->
- <skip />
- <!-- no translation found for fast_scroll_alphabet (1017432309285755759) -->
- <skip />
- <!-- no translation found for fast_scroll_numeric_alphabet (3092587363718901074) -->
- <skip />
- <!-- no translation found for candidates_style (7738463880139922176) -->
- <skip />
+ <string name="byteShort">B</string>
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index f8881b6..dc17445 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -817,6 +817,5 @@
<skip />
<!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
<skip />
- <!-- no translation found for tutorial_double_tap_to_zoom_message (9111326385548696308) -->
<skip />
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 47f1bf4..95e3052 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -817,6 +817,5 @@
<skip />
<!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
<skip />
- <!-- no translation found for tutorial_double_tap_to_zoom_message (9111326385548696308) -->
<skip />
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 710c493..2cf7b43 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -817,6 +817,5 @@
<skip />
<!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
<skip />
- <!-- no translation found for tutorial_double_tap_to_zoom_message (9111326385548696308) -->
<skip />
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 0eba7f5..24e3cb6 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -558,12 +558,12 @@
<!-- no translation found for relative_time (1818557177829411417) -->
<skip />
<string name="time_wday">"<xliff:g id="WEEKDAY">%2$s</xliff:g>、<xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="full_date_month_first">"<xliff:g id="YEAR">yyyy</xliff:g>\'年\'<xliff:g id="MONTH">MMMM</xliff:g><xliff:g id="DAY">d</xliff:g>\'日\'"</string>
- <string name="full_date_day_first">"<xliff:g id="YEAR">yyyy</xliff:g>\'年\'<xliff:g id="MONTH">MMMM</xliff:g><xliff:g id="DAY">d</xliff:g>\'日\'"</string>
- <string name="medium_date_month_first">"<xliff:g id="YEAR">yyyy</xliff:g>\'年\'<xliff:g id="MONTH">MMM</xliff:g><xliff:g id="DAY">d</xliff:g>\'日\'"</string>
- <string name="medium_date_day_first">"<xliff:g id="YEAR">yyyy</xliff:g>\'年\'<xliff:g id="MONTH">MMM</xliff:g><xliff:g id="DAY">d</xliff:g>\'日\'"</string>
- <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>:<xliff:g id="MINUTE">mm</xliff:g> <xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>:<xliff:g id="MINUTE">mm</xliff:g>"</string>
+ <string name="full_date_month_first">"<xliff:g id="YEAR">yyyy</xliff:g>'\'\'年\'\''<xliff:g id="MONTH">MMMM</xliff:g><xliff:g id="DAY">d</xliff:g>'\'\'日\'\''"</string>
+ <string name="full_date_day_first">"<xliff:g id="YEAR">yyyy</xliff:g>'\'\'年\'\''<xliff:g id="MONTH">MMMM</xliff:g><xliff:g id="DAY">d</xliff:g>'\'\'日\'\''"</string>
+ <string name="medium_date_month_first">"<xliff:g id="YEAR">yyyy</xliff:g>'\'\'年\'\''<xliff:g id="MONTH">MMM</xliff:g><xliff:g id="DAY">d</xliff:g>'\'\'日\'\''"</string>
+ <string name="medium_date_day_first">"<xliff:g id="YEAR">yyyy</xliff:g>'\'\'年\'\''<xliff:g id="MONTH">MMM</xliff:g><xliff:g id="DAY">d</xliff:g>'\'\'日\'\''"</string>
+ <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
+ <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"正午"</string>
<string name="Noon">"正午"</string>
<string name="midnight">"午前0時"</string>
@@ -573,7 +573,8 @@
<!-- no translation found for month (7026169712234774086) -->
<skip />
<string name="month_day_year">"<xliff:g id="YEAR">%Y</xliff:g>年<xliff:g id="MONTH">%B</xliff:g><xliff:g id="DAY">%-d</xliff:g>日"</string>
- <string name="month_year">"<xliff:g id="YEAR">%Y</xliff:g>年 <xliff:g id="MONTH">%B</xliff:g>"</string>
+ <!-- no translation found for month_year (9219019380312413367) -->
+ <skip />
<string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
<string name="date_and_time">"<xliff:g id="YEAR">%Y</xliff:g>年<xliff:g id="MONTH">%B</xliff:g><xliff:g id="DAY">%-d</xliff:g>日<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
<string name="same_year_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1">%3$s</xliff:g>日~<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2">%8$s</xliff:g>日"</string>
@@ -816,6 +817,5 @@
<skip />
<!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
<skip />
- <!-- no translation found for tutorial_double_tap_to_zoom_message (9111326385548696308) -->
<skip />
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 4272684..140f32f 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -817,6 +817,5 @@
<skip />
<!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
<skip />
- <!-- no translation found for tutorial_double_tap_to_zoom_message (9111326385548696308) -->
<skip />
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 9f49557..466f2b1 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_reboot">"Lar applikasjonen tvinge telefonen til å starte på nytt."</string>
<string name="permlab_mount_unmount_filesystems">"montere og avmontere filsystemer"</string>
<string name="permdesc_mount_unmount_filesystems">"Lar applikasjonen montere og avmontere filsystemer for uttagbar lagring."</string>
- <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) -->
- <skip />
- <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) -->
- <skip />
+ <string name="permlab_mount_format_filesystems">"formatere ekstern lagringsplass"</string>
+ <string name="permdesc_mount_format_filesystems">"Lar applikasjonen formatere ekstern lagringsplass."</string>
<string name="permlab_vibrate">"kontrollere vibratoren"</string>
<string name="permdesc_vibrate">"Lar applikasjonen kontrollere vibratoren."</string>
<string name="permlab_flashlight">"kontrollere lommelykten"</string>
@@ -280,10 +278,8 @@
<string name="permdesc_locationUpdates">"Lar applikasjonen slå av/på varsling om plasseringsendringer fra radioen. Ikke ment for vanlige applikasjoner."</string>
<string name="permlab_checkinProperties">"få tilgang til egenskaper for innsjekking"</string>
<string name="permdesc_checkinProperties">"Gir lese- og skrivetilgang til egenskaper lastet opp av innsjekkingstjenesten. Ikke ment for vanlige applikasjoner."</string>
- <!-- no translation found for permlab_bindGadget (2519859363977647275) -->
- <skip />
- <!-- no translation found for permdesc_bindGadget (7865866514555126333) -->
- <skip />
+ <string name="permlab_bindGadget">"velg gadgeter"</string>
+ <string name="permdesc_bindGadget">"Lar applikasjonen fortelle systemet hvilke gadgeter som kan brukes av hvilke applikasjoner. Med denne rettigheten kan applikasjoner andre applikasjoner tilgang til personlig data. Ikke ment for vanlige applikasjoner."</string>
<string name="permlab_modifyPhoneState">"endre telefontilstand"</string>
<string name="permdesc_modifyPhoneState">"Lar applikasjonen kontrollere telefonfunksjonaliteten i enheten. En applikasjon med denne rettigheten kan endre nettverk, slå telefonens radio av eller på og lignende uten noensinne å varsle brukeren."</string>
<string name="permlab_readPhoneState">"lese telefontilstand"</string>
@@ -312,10 +308,8 @@
<string name="permdesc_writeApnSettings">"Lar applikasjonen to endre APN-innstillinger slik som mellomtjener eller port for hvilket som helst aksesspunkt."</string>
<string name="permlab_changeNetworkState">"endre nettverkskonnektivitet"</string>
<string name="permdesc_changeNetworkState">"Lar applikasjonen endre tilstanden til nettverkskonnektivitet."</string>
- <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) -->
- <skip />
- <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) -->
- <skip />
+ <string name="permlab_changeBackgroundDataSetting">"endre innstilling for bakgrunnsdata"</string>
+ <string name="permdesc_changeBackgroundDataSetting">"Lar applikasjonen endre innstillingen for bakgrunnsdata."</string>
<string name="permlab_accessWifiState">"se tilstand for trådløse nettverk"</string>
<string name="permdesc_accessWifiState">"Lar applikasjonen få se informasjon om tilstanden til de trådløse nettene."</string>
<string name="permlab_changeWifiState">"endre tilstand for trådløse nettverk"</string>
@@ -336,14 +330,10 @@
<string name="permdesc_subscribedFeedsRead">"Lar applikasjonen hente detaljer om hvilke nyhetskilder som synkroniseres."</string>
<string name="permlab_subscribedFeedsWrite">"endre abonnement på nyhetskilder"</string>
<string name="permdesc_subscribedFeedsWrite">"Lar applikasjonen redigere hvilke nyhetskilder som synkroniseres. Dette kan gi en ondsinnet applikasjon tilgang til å endre hvilke nyhetskilder som synkroniseres."</string>
- <!-- no translation found for permlab_readDictionary (432535716804748781) -->
- <skip />
- <!-- no translation found for permdesc_readDictionary (1082972603576360690) -->
- <skip />
- <!-- no translation found for permlab_writeDictionary (6703109511836343341) -->
- <skip />
- <!-- no translation found for permdesc_writeDictionary (2241256206524082880) -->
- <skip />
+ <string name="permlab_readDictionary">"lese brukerdefinert ordliste"</string>
+ <string name="permdesc_readDictionary">"Lar applikasjonen lese private ord, navn og uttrykk som brukeren har lagret i den brukerdefinerte ordlisten."</string>
+ <string name="permlab_writeDictionary">"skrive til brukerdefinert ordliste"</string>
+ <string name="permdesc_writeDictionary">"Lar applikasjonen skrive nye ord til den brukerdefinerte ordlisten."</string>
<string-array name="phoneTypes">
<item>"Hjemme"</item>
<item>"Mobil"</item>
@@ -440,12 +430,9 @@
<string name="factorytest_not_system">"The FACTORY_TEST action is only supported for packages installed in /system/app."</string>
<string name="factorytest_no_action">"No package was found that provides the FACTORY_TEST action."</string>
<string name="factorytest_reboot">"Reboot"</string>
- <!-- no translation found for js_dialog_title (8143918455087008109) -->
- <skip />
- <!-- no translation found for js_dialog_title_default (6961903213729667573) -->
- <skip />
- <!-- no translation found for js_dialog_before_unload (1901675448179653089) -->
- <skip />
+ <string name="js_dialog_title">"Siden \\\'<xliff:g id="TITLE">%s</xliff:g>\\\' sier:"</string>
+ <string name="js_dialog_title_default">"JavaScript"</string>
+ <string name="js_dialog_before_unload">"Naviger bort fra denne siden?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Velg OK for å fortsette, eller Avbryt for å forbli på denne siden."</string>
<string name="save_password_label">"Bekreft"</string>
<string name="save_password_message">"Ønsker du at nettleseren skal huske dette passordet?"</string>
<string name="save_password_notnow">"Ikke nå"</string>
@@ -569,17 +556,15 @@
<string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g> <xliff:g id="DATE">%3$s</xliff:g>"</string>
<string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g> <xliff:g id="DATE">%3$s</xliff:g>"</string>
<string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <!-- no translation found for date_time (6104442718633642836) -->
- <skip />
- <!-- no translation found for relative_time (1818557177829411417) -->
- <skip />
+ <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="full_date_month_first">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>'., '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_month_first">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
+ <string name="full_date_month_first">"<xliff:g id="MONTH">MMMM</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="DAY">d</xliff:g>'\\\'\'\\\'\'., \\\'\'\\\'\''<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="full_date_day_first">"<xliff:g id="DAY">d</xliff:g>'\\\'\'\\\'\'. \\\'\'\\\'\''<xliff:g id="MONTH">MMMM</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_month_first">"<xliff:g id="MONTH">MMM</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="DAY">d</xliff:g>'\\\'\'\\\'\', \\\'\'\\\'\''<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>'\\\'\'\\\'\'. \\\'\'\\\'\''<xliff:g id="MONTH">MMM</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>'\\\'\'\\\'\':\\\'\'\\\'\''<xliff:g id="MINUTE">mm</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="AMPM">a</xliff:g>"</string>
+ <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>'\\\'\'\\\'\':\\\'\'\\\'\''<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"middag"</string>
<string name="Noon">"Middag"</string>
<string name="midnight">"midnatt"</string>
@@ -596,18 +581,14 @@
<string name="same_year_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>"</string>
<string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
- <!-- no translation found for same_year_wday1_mdy1_wday2_mdy2 (1345612987720788874) -->
- <skip />
+ <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="YEAR">%9$s</xliff:g>"</string>
<string name="same_year_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <!-- no translation found for same_year_mdy1_time1_mdy2_time2 (2959466512848524124) -->
- <skip />
- <!-- no translation found for same_year_wday1_mdy1_time1_wday2_mdy2_time2 (5129735426508861428) -->
- <skip />
+ <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="numeric_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>.<xliff:g id="MONTH1">%2$s</xliff:g>. – <xliff:g id="DAY2">%8$s</xliff:g>.<xliff:g id="MONTH2">%7$s</xliff:g>."</string>
<string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>.<xliff:g id="MONTH1">%2$s</xliff:g>. – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>.<xliff:g id="MONTH2">%7$s</xliff:g>."</string>
- <!-- no translation found for numeric_mdy1_mdy2 (3933951218078638018) -->
- <skip />
+ <string name="numeric_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>.<xliff:g id="MONTH1">%2$s</xliff:g>.<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>.<xliff:g id="MONTH2">%7$s</xliff:g>.<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
<string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>.<xliff:g id="MONTH1">%2$s</xliff:g>.<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>.<xliff:g id="MONTH2">%7$s</xliff:g>.<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
<string name="numeric_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>.<xliff:g id="MONTH1">%2$s</xliff:g>. <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>.<xliff:g id="MONTH2">%7$s</xliff:g>. <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>.<xliff:g id="MONTH1">%2$s</xliff:g>. <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>.<xliff:g id="MONTH2">%7$s</xliff:g>. <xliff:g id="TIME2">%10$s</xliff:g>"</string>
@@ -711,8 +692,7 @@
<string name="paste">"Lim inn"</string>
<string name="copyUrl">"Kopier URL"</string>
<string name="inputMethod">"Inndatametode"</string>
- <!-- no translation found for addToDictionary (726256909274177272) -->
- <skip />
+ <string name="addToDictionary">"Legg \\\"%s\\\" til ordlisten"</string>
<string name="editTextMenuTitle">"Rediger tekst"</string>
<string name="low_internal_storage_view_title">"Lite plass"</string>
<string name="low_internal_storage_view_text">"Det begynner å bli lite lagringsplass på telefonen."</string>
@@ -720,8 +700,7 @@
<string name="cancel">"Avbryt"</string>
<string name="yes">"OK"</string>
<string name="no">"Avbryt"</string>
- <!-- no translation found for dialog_alert_title (2049658708609043103) -->
- <skip />
+ <string name="dialog_alert_title">"Merk"</string>
<string name="capital_on">"På"</string>
<string name="capital_off">"Av"</string>
<string name="whichApplication">"Complete action using"</string>
@@ -745,8 +724,7 @@
<string name="volume_music">"Medievolum"</string>
<string name="volume_music_hint_playing_through_bluetooth">"Spiller over Bluetooth"</string>
<string name="volume_call">"Samtalevolum"</string>
- <!-- no translation found for volume_bluetooth_call (2002891926351151534) -->
- <skip />
+ <string name="volume_bluetooth_call">"Bluetooth-samtalevolum"</string>
<string name="volume_alarm">"Alarmvolum"</string>
<string name="volume_notification">"Varslingsvolum"</string>
<string name="volume_unknown">"Volum"</string>
@@ -766,7 +744,7 @@
<string name="select_character">"Sett inn tegn"</string>
<string name="sms_control_default_app_name">"Ukjent applikasjon"</string>
<string name="sms_control_title">"Sending SMS messages"</string>
- <string name="sms_control_message">"A large number of SMS messages are being sent. Select \\\"OK\\\" to continue, or \\\"Cancel\\\" to stop sending."</string>
+ <string name="sms_control_message">"A large number of SMS messages are being sent. Select \\\\\\\"OK\\\\\\\" to continue, or \\\\\\\"Cancel\\\\\\\" to stop sending."</string>
<string name="sms_control_yes">"OK"</string>
<string name="sms_control_no">"Avbryt"</string>
<string name="date_time_set">"Lagre"</string>
@@ -776,67 +754,39 @@
<string name="perms_show_all"><b>"Vis alle"</b></string>
<string name="googlewebcontenthelper_loading">"Laster inn…"</string>
<string name="usb_storage_title">"USB koblet til"</string>
- <string name="usb_storage_message">"Du har koblet telefonen til en datamaskin via USB. Velg \\\"Monter\\\" dersom du ønsker å kopiere filer mellom datmaskinen og minnekortet i telefonen."</string>
+ <string name="usb_storage_message">"Du har koblet telefonen til en datamaskin via USB. Velg \\\\\\\"Monter\\\\\\\" dersom du ønsker å kopiere filer mellom datmaskinen og minnekortet i telefonen."</string>
<string name="usb_storage_button_mount">"Monter"</string>
<string name="usb_storage_button_unmount">"Ikke monter"</string>
<string name="usb_storage_error_message">"Det oppsto et problem med å bruke minnekortet ditt for USB-lagring."</string>
<string name="usb_storage_notification_title">"USB tilkoblet"</string>
<string name="usb_storage_notification_message">"Velg om du ønsker å kopiere filer til/fra en datamaskin."</string>
- <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) -->
- <skip />
- <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) -->
- <skip />
- <!-- no translation found for usb_storage_stop_title (6014127947456185321) -->
- <skip />
- <!-- no translation found for usb_storage_stop_message (2390958966725232848) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) -->
- <skip />
- <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) -->
- <skip />
- <!-- no translation found for extmedia_format_title (8663247929551095854) -->
- <skip />
- <!-- no translation found for extmedia_format_message (3621369962433523619) -->
- <skip />
- <!-- no translation found for extmedia_format_button_format (4131064560127478695) -->
- <skip />
+ <string name="usb_storage_stop_notification_title">"Slå av USB-lagring"</string>
+ <string name="usb_storage_stop_notification_message">"Velg for å slå av USB-lagring."</string>
+ <string name="usb_storage_stop_title">"Slå av USB-lagring"</string>
+ <string name="usb_storage_stop_message">"Før du slår av USB-lagring, sjekk at du har avmontert enheten i USB-verten. Velg «slå av» for å slå av USB-lagring."</string>
+ <string name="usb_storage_stop_button_mount">"Slå av"</string>
+ <string name="usb_storage_stop_button_unmount">"Avbryt"</string>
+ <string name="usb_storage_stop_error_message">"Det oppsto et problem under avslutningen av USB-lagring. Sjekk at USB-verten har avmontert og prøv igjen."</string>
+ <string name="extmedia_format_title">"Formatere minnekort"</string>
+ <string name="extmedia_format_message">"Er du sikker på at du ønsker å formatere minnekortet? Alle data på kortet vil gå tapt."</string>
+ <string name="extmedia_format_button_format">"Format"</string>
<string name="select_input_method">"Velg inndatametode"</string>
<string name="fast_scroll_alphabet">"ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
<string name="fast_scroll_numeric_alphabet">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
- <!-- unknown quoting pattern: original -1, translation 1 -->
- <string name="candidates_style">"TAG_FONT"<u>"kandidater"</u>"u&amp;gt;CLOSE_FONT"</string>
- <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) -->
- <skip />
- <!-- no translation found for activity_list_empty (4168820609403385789) -->
- <skip />
- <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) -->
- <skip />
- <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
- <skip />
- <!-- no translation found for tutorial_double_tap_to_zoom_message (9111326385548696308) -->
- <skip />
+ <string name="candidates_style">"TAG_FONT"<u>"kandidater"</u>"CLOSE_FONT"</string>
+ <string name="ext_media_checking_notification_title">"Forbereder minnekort"</string>
+ <string name="ext_media_checking_notification_message">"Sjekker for feil"</string>
+ <string name="ext_media_nofs_notification_title">"Tomt minnekort"</string>
+ <string name="ext_media_nofs_notification_message">"Minnekortet er tomt eller bruker et ustøttet filsystem."</string>
+ <string name="ext_media_unmountable_notification_title">"Skadet minnekort"</string>
+ <string name="ext_media_unmountable_notification_message">"Minnekortet er skadet. Det kan være du må formatere kortet."</string>
+ <string name="ext_media_badremoval_notification_title">"Minnekortet ble tatt ut uventet"</string>
+ <string name="ext_media_badremoval_notification_message">"Avmonter minnekortet før det tas ut, for å unngå datatap."</string>
+ <string name="ext_media_safe_unmount_notification_title">"Trygt å ta ut minnekort"</string>
+ <string name="ext_media_safe_unmount_notification_message">"Minnekortet kan nå trygt tas ut."</string>
+ <string name="ext_media_nomedia_notification_title">"Minnekortet ble tatt ut"</string>
+ <string name="ext_media_nomedia_notification_message">"Minnekortet ble tatt ut. Sett inn et nytt minnekort for å øke lagringsplassen."</string>
+ <string name="activity_list_empty">"Fant ingen tilsvarende aktiviteter"</string>
+ <string name="permlab_pkgUsageStats">"oppdater statistikk over komponentbruk"</string>
+ <string name="permdesc_pkgUsageStats">"Tillater endring av innsamlet data om bruk av komponenter. Ikke ment for vanlige applikasjoner."</string>
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 7ce4c66..a2810a1 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -817,6 +817,5 @@
<skip />
<!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
<skip />
- <!-- no translation found for tutorial_double_tap_to_zoom_message (9111326385548696308) -->
<skip />
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 03c4f8b..12f1616 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -817,6 +817,5 @@
<skip />
<!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
<skip />
- <!-- no translation found for tutorial_double_tap_to_zoom_message (9111326385548696308) -->
<skip />
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index d25ab8d..76a358d 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -817,6 +817,5 @@
<skip />
<!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
<skip />
- <!-- no translation found for tutorial_double_tap_to_zoom_message (9111326385548696308) -->
<skip />
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 447fccd..13d4e9c 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -817,6 +817,5 @@
<skip />
<!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
<skip />
- <!-- no translation found for tutorial_double_tap_to_zoom_message (9111326385548696308) -->
<skip />
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index e97c142..419e8c2 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -817,6 +817,5 @@
<skip />
<!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
<skip />
- <!-- no translation found for tutorial_double_tap_to_zoom_message (9111326385548696308) -->
<skip />
</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 3f21303..593d1ff 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1056,6 +1056,10 @@
enabled for events such as clicking and touching. -->
<attr name="soundEffectsEnabled" format="boolean" />
+ <!-- Boolean that controls whether a view should have haptic feedback
+ enabled for events such as long presses. -->
+ <attr name="hapticFeedbackEnabled" format="boolean" />
+
</declare-styleable>
<!-- Attributes that can be used with a {@link android.view.ViewGroup} or any
@@ -2035,8 +2039,18 @@
<enum name="line" value="2" />
<enum name="ring" value="3" />
</attr>
+ <!-- Inner radius of the ring expressed as a ratio of the ring's width. For instance,
+ if innerRadiusRatio=9, then the inner radius equals the ring's width divided by 9.
+ This value is ignored if innerRadius is defined. Default value is 9. -->
<attr name="innerRadiusRatio" format="float" />
+ <!-- Thickness of the ring expressed as a ratio of the ring's width. For instance,
+ if thicknessRatio=3, then the thickness equals the ring's width divided by 3.
+ This value is ignored if innerRadius is defined. Default value is 3. -->
<attr name="thicknessRatio" format="float" />
+ <!-- Inner radius of the ring. When defined, innerRadiusRatio is ignored. -->
+ <attr name="innerRadius" format="dimension" />
+ <!-- Thickness of the ring. When defined, thicknessRatio is ignored. -->
+ <attr name="thickness" format="dimension" />
<attr name="useLevel" />
</declare-styleable>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 1031585..9175f31 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1001,6 +1001,9 @@
<public type="attr" name="content" id="0x0101025b" />
<public type="attr" name="animateOnClick" id="0x0101025c" />
<public type="attr" name="configure" id="0x0101025d" />
+ <public type="attr" name="hapticFeedbackEnabled" id="0x0101025e" />
+ <public type="attr" name="innerRadius" id="0x0101025f" />
+ <public type="attr" name="thickness" id="0x01010260" />
<!-- The part of the UI shown by an
{@link android.inputmethodservice.InputMethodService} that contains the
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 4700b93..1174996 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2263,8 +2263,7 @@
<string name="permdesc_pkgUsageStats">Allows the modification of collected component usage statistics. Not for use by normal applications.</string>
<!-- Shown in the tutorial for double tap to zoom. -->
- <string name="tutorial_double_tap_to_zoom_message">Congratulations on downloading the Android software update. This update includes a number of great new features for you to enjoy. One major improvement we've made is to how you zoom. Now, when you want to zoom, just double tap on the screen. This will bring up a zoom widget. Drag the widget's handle clockwise to zoom in, and counter-clockwise to zoom out.</string>
-
+ <string name="tutorial_double_tap_to_zoom_message_short">Double tap to zoom</string>
</resources>