Merge "Register EGLExt JNI methods" into jb-mr2-dev
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index ccb9e1f..61fe340 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -31,6 +31,7 @@
import android.content.pm.IPackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
+import android.os.Binder;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -94,6 +95,7 @@
" am set-debug-app [-w] [--persistent] <PACKAGE>\n" +
" am clear-debug-app\n" +
" am monitor [--gdb <port>]\n" +
+ " am hang [--allow-restart]\n" +
" am screen-compat [on|off] <PACKAGE>\n" +
" am to-uri [INTENT]\n" +
" am to-intent-uri [INTENT]\n" +
@@ -169,6 +171,9 @@
"am monitor: start monitoring for crashes or ANRs.\n" +
" --gdb: start gdbserv on the given port at crash/ANR\n" +
"\n" +
+ "am hang: hang the system.\n" +
+ " --allow-restart: allow watchdog to perform normal system restart\n" +
+ "\n" +
"am screen-compat: control screen compatibility mode of <PACKAGE>.\n" +
"\n" +
"am to-uri: print the given Intent specification as a URI.\n" +
@@ -249,6 +254,8 @@
runBugReport();
} else if (op.equals("monitor")) {
runMonitor();
+ } else if (op.equals("hang")) {
+ runHang();
} else if (op.equals("screen-compat")) {
runScreenCompat();
} else if (op.equals("to-uri")) {
@@ -1093,6 +1100,18 @@
}
}
+ @Override
+ public int systemNotResponding(String message)
+ throws RemoteException {
+ synchronized (this) {
+ System.out.println("** ERROR: PROCESS NOT RESPONDING");
+ System.out.println("message: " + message);
+ System.out.println("#");
+ System.out.println("Allowing system to die.");
+ return -1;
+ }
+ }
+
void killGdbLocked() {
mGotGdbPrint = false;
if (mGdbProcess != null) {
@@ -1292,6 +1311,22 @@
controller.run();
}
+ private void runHang() throws Exception {
+ String opt;
+ boolean allowRestart = false;
+ while ((opt=nextOption()) != null) {
+ if (opt.equals("--allow-restart")) {
+ allowRestart = true;
+ } else {
+ System.err.println("Error: Unknown option: " + opt);
+ return;
+ }
+ }
+
+ System.out.println("Hanging the system...");
+ mAm.hang(new Binder(), allowRestart);
+ }
+
private void runScreenCompat() throws Exception {
String mode = nextArgRequired();
boolean enabled;
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 98baa0e..d4478bf 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1870,6 +1870,15 @@
return true;
}
+ case HANG_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IBinder who = data.readStrongBinder();
+ boolean allowRestart = data.readInt() != 0;
+ hang(who, allowRestart);
+ reply.writeNoException();
+ return true;
+ }
+
}
return super.onTransact(code, data, reply, flags);
@@ -4270,5 +4279,17 @@
reply.recycle();
}
+ public void hang(IBinder who, boolean allowRestart) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeStrongBinder(who);
+ data.writeInt(allowRestart ? 1 : 0);
+ mRemote.transact(HANG_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+
private IBinder mRemote;
}
diff --git a/core/java/android/app/IActivityController.aidl b/core/java/android/app/IActivityController.aidl
index aca8305..952c900 100644
--- a/core/java/android/app/IActivityController.aidl
+++ b/core/java/android/app/IActivityController.aidl
@@ -58,4 +58,11 @@
* immediately.
*/
int appNotResponding(String processName, int pid, String processStats);
+
+ /**
+ * The system process watchdog has detected that the system seems to be
+ * hung. Return 1 to continue waiting, or -1 to let it continue with its
+ * normal kill.
+ */
+ int systemNotResponding(String msg);
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 33a2770..a21caee 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -377,6 +377,8 @@
public void killUid(int uid, String reason) throws RemoteException;
+ public void hang(IBinder who, boolean allowRestart) throws RemoteException;
+
/*
* Private non-Binder interfaces
*/
@@ -638,4 +640,5 @@
int GET_LAUNCHED_FROM_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+163;
int KILL_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+164;
int SET_USER_IS_MONKEY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+165;
+ int HANG_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+166;
}
diff --git a/core/java/android/net/nsd/NsdManager.java b/core/java/android/net/nsd/NsdManager.java
index 08ba728..9c3e405 100644
--- a/core/java/android/net/nsd/NsdManager.java
+++ b/core/java/android/net/nsd/NsdManager.java
@@ -306,10 +306,9 @@
switch (message.what) {
case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
- mConnected.countDown();
break;
case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
- // Ignore
+ mConnected.countDown();
break;
case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
Log.e(TAG, "Channel lost");
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index e9e7551..7ffd30b 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -49,6 +49,11 @@
private static final boolean FIND_POTENTIAL_LEAKS = false;
private static final String TAG = "Binder";
+ /**
+ * Control whether dump() calls are allowed.
+ */
+ private static String sDumpDisabled = null;
+
/* mObject is used by native code, do not remove or rename */
private int mObject;
private IInterface mOwner;
@@ -224,7 +229,23 @@
}
return null;
}
-
+
+ /**
+ * Control disabling of dump calls in this process. This is used by the system
+ * process watchdog to disable incoming dump calls while it has detecting the system
+ * is hung and is reporting that back to the activity controller. This is to
+ * prevent the controller from getting hung up on bug reports at this point.
+ * @hide
+ *
+ * @param msg The message to show instead of the dump; if null, dumps are
+ * re-enabled.
+ */
+ public static void setDumpDisabled(String msg) {
+ synchronized (Binder.class) {
+ sDumpDisabled = msg;
+ }
+ }
+
/**
* Default implementation is a stub that returns false. You will want
* to override this to do the appropriate unmarshalling of transactions.
@@ -269,7 +290,15 @@
FileOutputStream fout = new FileOutputStream(fd);
PrintWriter pw = new PrintWriter(fout);
try {
- dump(fd, pw, args);
+ final String disabled;
+ synchronized (Binder.class) {
+ disabled = sDumpDisabled;
+ }
+ if (disabled == null) {
+ dump(fd, pw, args);
+ } else {
+ pw.println(sDumpDisabled);
+ }
} finally {
pw.flush();
}
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 9946c92..986a001 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -468,7 +468,7 @@
<string name="permdesc_recordAudio" msgid="4906839301087980680">"Memungkinkan aplikasi merekam audio dengan mikrofon. Izin ini memungkinkan aplikasi merekam audio kapan saja tanpa konfirmasi Anda."</string>
<string name="permlab_camera" msgid="3616391919559751192">"ambil gambar dan video"</string>
<string name="permdesc_camera" msgid="8497216524735535009">"Memungkinkan aplikasi mengambil gambar dan video dengan kamera. Izin ini memungkinkan aplikasi menggunakan kamera kapan saja tanpa konfirmasi Anda."</string>
- <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"nonaktifkan transmisi LED indikator saat kamera digunakan"</string>
+ <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"nonaktifkan LED indikator transmisi saat kamera digunakan"</string>
<string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"Izinkan aplikasi sistem yang sudah dipasang sebelumnya menonaktifkan LED indikator penggunaan kamera."</string>
<string name="permlab_brick" product="tablet" msgid="2961292205764488304">"noaktifkan tablet secara permanen"</string>
<string name="permlab_brick" product="default" msgid="8337817093326370537">"nonaktifkan ponsel secara permanen"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index e03a6e6..6862ed5 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -156,7 +156,7 @@
<string name="global_action_power_off" msgid="4471879440839879722">"Zima simu"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"Ripoti ya hitilafu"</string>
<string name="bugreport_title" msgid="2667494803742548533">"Chukua ripoti ya hitilafu"</string>
- <string name="bugreport_message" msgid="398447048750350456">"Hii itakusanya maelezo kuhusu hali yako ya sasa ya kifaa, ili kutuma ujumbe wa barua pepe. Itachukua muda mfupi kuanza ripoti ya hitilafu mpaka itakapokuwa tayari kutumwa; tafadhali vumilia."</string>
+ <string name="bugreport_message" msgid="398447048750350456">"Hii itakusanya maelezo kuhusu hali ya kifaa chako kwa sasa, na itume kama barua pepe. Itachukua muda mfupi tangu ripoti ya hitilafu ianze kuzalishwa hadi iwe tayari kutumwa; vumilia."</string>
<string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mtindo wa kimya"</string>
<string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Sauti Imezimwa"</string>
<string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Sauti imewashwa"</string>
@@ -1491,7 +1491,7 @@
<string name="user_switched" msgid="3768006783166984410">"Mtumiaji wa sasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Mmiliki"</string>
<string name="error_message_title" msgid="4510373083082500195">"Hitilafu"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Programu hii haiwezi kutumiwa na akaunti za wasifu zilizodhibitiwa"</string>
+ <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Programu hii haiwezi kutumiwa na akaunti za wasifu zilizowekewa vikwazo"</string>
<string name="app_not_found" msgid="3429141853498927379">"Hakuna programu iliyopatikana ili kushughulikia kitendo hiki"</string>
<string name="revoke" msgid="5404479185228271586">"Batilisha"</string>
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 200a9c2..140dbfb 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -312,7 +312,7 @@
<string name="permlab_stopAppSwitches" msgid="4138608610717425573">"禁止切换应用"</string>
<string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"阻止用户切换到其他应用。"</string>
<string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"获取当前应用的信息"</string>
- <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"允许应用针对目前在屏幕前台运行的应用检索相关隐私信息。"</string>
+ <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"允许应用检索目前在屏幕前台运行的应用专有的信息。"</string>
<string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"监控所有应用的启动"</string>
<string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"允许应用监视和控制系统是如何启动活动的。恶意应用可能会完全破坏系统。此权限只有在进行开发时才需要,正常使用情况下绝不需要。"</string>
<string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"发送包删除的广播"</string>
@@ -625,7 +625,7 @@
<string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"允许应用管理网络政策和定义专门针对应用的规则。"</string>
<string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"修改网络使用情况记录方式"</string>
<string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"允许该应用修改对于各应用的网络使用情况的统计方式。普通应用不应使用此权限。"</string>
- <string name="permlab_accessNotifications" msgid="7673416487873432268">"查看通知"</string>
+ <string name="permlab_accessNotifications" msgid="7673416487873432268">"访问通知"</string>
<string name="permdesc_accessNotifications" msgid="458457742683431387">"允许该应用检索、检查并清除通知,包括其他应用发布的通知。"</string>
<string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"绑定到通知侦听器服务"</string>
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"允许应用绑定到通知侦听器服务的顶级接口(普通应用绝不需要此权限)。"</string>
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 2a3c87e..a537e99 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -3735,7 +3735,16 @@
} else {
// So far so good -- do the signatures match the manifest?
Signature[] sigs = mManifestSignatures.get(info.packageName);
- if (!signaturesMatch(sigs, pkg)) {
+ if (signaturesMatch(sigs, pkg)) {
+ // If this is a system-uid app without a declared backup agent,
+ // don't restore any of the file data.
+ if ((pkg.applicationInfo.uid < Process.FIRST_APPLICATION_UID)
+ && (pkg.applicationInfo.backupAgentName == null)) {
+ Slog.w(TAG, "Installed app " + info.packageName
+ + " has restricted uid and no agent");
+ okay = false;
+ }
+ } else {
Slog.w(TAG, "Installed app " + info.packageName
+ " signatures do not match restore manifest");
okay = false;
diff --git a/services/java/com/android/server/Watchdog.java b/services/java/com/android/server/Watchdog.java
index 167e7af..3aec4ea 100644
--- a/services/java/com/android/server/Watchdog.java
+++ b/services/java/com/android/server/Watchdog.java
@@ -16,6 +16,9 @@
package com.android.server;
+import android.app.IActivityController;
+import android.os.Binder;
+import android.os.RemoteException;
import com.android.server.am.ActivityManagerService;
import com.android.server.power.PowerManagerService;
@@ -91,6 +94,8 @@
Monitor mCurrentMonitor;
int mPhonePid;
+ IActivityController mController;
+ boolean mAllowRestart = true;
final Calendar mCalendar = Calendar.getInstance();
int mMinScreenOff = MEMCHECK_DEFAULT_MIN_SCREEN_OFF;
@@ -223,6 +228,18 @@
}
}
+ public void setActivityController(IActivityController controller) {
+ synchronized (this) {
+ mController = controller;
+ }
+ }
+
+ public void setAllowRestart(boolean allowRestart) {
+ synchronized (this) {
+ mAllowRestart = allowRestart;
+ }
+ }
+
public void addMonitor(Monitor monitor) {
synchronized (this) {
if (isAlive()) {
@@ -391,6 +408,7 @@
final String name;
+ final boolean allowRestart;
synchronized (this) {
long timeout = TIME_TO_WAIT;
@@ -427,6 +445,7 @@
name = (mCurrentMonitor != null) ?
mCurrentMonitor.getClass().getName() : "null";
+ allowRestart = mAllowRestart;
}
// If we got here, that means that the system is most likely hung.
@@ -476,13 +495,34 @@
dropboxThread.join(2000); // wait up to 2 seconds for it to return.
} catch (InterruptedException ignored) {}
+ IActivityController controller;
+ synchronized (this) {
+ controller = mController;
+ }
+ if (controller != null) {
+ Slog.i(TAG, "Reporting stuck state to activity controller");
+ try {
+ Binder.setDumpDisabled("Service dumps disabled due to hung system process.");
+ // 1 = keep waiting, -1 = kill system
+ int res = controller.systemNotResponding(name);
+ if (res >= 0) {
+ Slog.i(TAG, "Activity controller requested to coninue to wait");
+ waitedHalf = false;
+ continue;
+ }
+ } catch (RemoteException e) {
+ }
+ }
+
// Only kill the process if the debugger is not attached.
- if (!Debug.isDebuggerConnected()) {
+ if (Debug.isDebuggerConnected()) {
+ Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the system process");
+ } else if (!allowRestart) {
+ Slog.w(TAG, "Restart not allowed: Watchdog is *not* killing the system process");
+ } else {
Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + name);
Process.killProcess(Process.myPid());
System.exit(10);
- } else {
- Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the system process");
}
waitedHalf = false;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 1d17da9..0081dfc 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -2822,6 +2822,7 @@
resumeOK = mController.activityResuming(next.packageName);
} catch (RemoteException e) {
mController = null;
+ Watchdog.getInstance().setActivityController(null);
}
if (!resumeOK) {
@@ -3334,6 +3335,7 @@
if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
} catch (RemoteException e) {
mController = null;
+ Watchdog.getInstance().setActivityController(null);
}
}
@@ -3437,6 +3439,7 @@
}
} catch (RemoteException e) {
mController = null;
+ Watchdog.getInstance().setActivityController(null);
}
}
@@ -7441,6 +7444,7 @@
"setActivityController()");
synchronized (this) {
mController = controller;
+ Watchdog.getInstance().setActivityController(controller);
}
}
@@ -7809,6 +7813,45 @@
return killed;
}
+ @Override
+ public void hang(final IBinder who, boolean allowRestart) {
+ if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires permission "
+ + android.Manifest.permission.SET_ACTIVITY_WATCHER);
+ }
+
+ final IBinder.DeathRecipient death = new DeathRecipient() {
+ @Override
+ public void binderDied() {
+ synchronized (this) {
+ notifyAll();
+ }
+ }
+ };
+
+ try {
+ who.linkToDeath(death, 0);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "hang: given caller IBinder is already dead.");
+ return;
+ }
+
+ synchronized (this) {
+ Watchdog.getInstance().setAllowRestart(allowRestart);
+ Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
+ synchronized (death) {
+ while (who.isBinderAlive()) {
+ try {
+ death.wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ Watchdog.getInstance().setAllowRestart(true);
+ }
+ }
+
public final void startRunning(String pkg, String cls, String action,
String data) {
synchronized(this) {
@@ -8832,6 +8875,7 @@
}
} catch (RemoteException e) {
mController = null;
+ Watchdog.getInstance().setActivityController(null);
}
}
@@ -12765,6 +12809,7 @@
resumeOK = mController.activityResuming(next.packageName);
} catch (RemoteException e) {
mController = null;
+ Watchdog.getInstance().setActivityController(null);
}
if (!resumeOK) {