diff --git a/res/values/strings.xml b/res/values/strings.xml index ebf1fb451fd..4291581ab0e 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -3540,10 +3540,14 @@ Logger buffer sizes Select Logger sizes per log buffer - - Allow mock locations - - Allow mock locations + + + Select mock location app + + No mock location app set + + Mock location app: %1$s + Enable view attribute inspection diff --git a/res/xml/development_prefs.xml b/res/xml/development_prefs.xml index 39866c9e519..32c96c16b4e 100644 --- a/res/xml/development_prefs.xml +++ b/res/xml/development_prefs.xml @@ -86,10 +86,8 @@ android:title="@string/bugreport_in_power" android:summary="@string/bugreport_in_power_summary"/> - + packageOps = appOpsManager.getPackagesForOps(MOCK_LOCATOIN_APP_OPS); + if (packageOps != null) { + // Should be one but in case we are in a bad state due to use of command line tools. + for (PackageOps packageOp : packageOps) { + if (packageOp.getOps().get(0).getMode() != AppOpsManager.MODE_ERRORED) { + String oldMockLocationApp = packageOp.getPackageName(); + try { + ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo( + oldMockLocationApp, PackageManager.GET_DISABLED_COMPONENTS); + appOpsManager.setMode(AppOpsManager.OP_MOCK_LOCATION, ai.uid, + oldMockLocationApp, AppOpsManager.MODE_ERRORED); + } catch (NameNotFoundException e) { + /* ignore */ + } + } + } + } + + // Enable the app op of the new mock location app if such. + if (!TextUtils.isEmpty(mMockLocationApp)) { + try { + ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo( + mMockLocationApp, PackageManager.GET_DISABLED_COMPONENTS); + appOpsManager.setMode(AppOpsManager.OP_MOCK_LOCATION, ai.uid, + mMockLocationApp, AppOpsManager.MODE_ALLOWED); + } catch (NameNotFoundException e) { + /* ignore */ + } + } + } + private static void resetDebuggerOptions() { try { ActivityManagerNative.getDefault().setDebugApp( @@ -709,6 +757,39 @@ public class DevelopmentSettings extends SettingsPreferenceFragment } } + private void updateMockLocation() { + AppOpsManager appOpsManager = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE); + + List packageOps = appOpsManager.getPackagesForOps(MOCK_LOCATOIN_APP_OPS); + if (packageOps != null) { + for (PackageOps packageOp : packageOps) { + if (packageOp.getOps().get(0).getMode() == AppOpsManager.MODE_ALLOWED) { + mMockLocationApp = packageOps.get(0).getPackageName(); + break; + } + } + } + + if (!TextUtils.isEmpty(mMockLocationApp)) { + String label = mMockLocationApp; + try { + ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo( + mMockLocationApp, PackageManager.GET_DISABLED_COMPONENTS); + CharSequence appLabel = getPackageManager().getApplicationLabel(ai); + if (appLabel != null) { + label = appLabel.toString(); + } + } catch (PackageManager.NameNotFoundException e) { + /* ignore */ + } + + mMockLocationAppPref.setSummary(getString(R.string.mock_location_app_set, label)); + mHaveDebugSettings = true; + } else { + mMockLocationAppPref.setSummary(getString(R.string.mock_location_app_not_set)); + } + } + private void updateVerifyAppsOverUsbOptions() { updateSwitchPreference(mVerifyAppsOverUsb, Settings.Global.getInt(getActivity().getContentResolver(), Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) != 0); @@ -1506,6 +1587,12 @@ public class DevelopmentSettings extends SettingsPreferenceFragment writeDebuggerOptions(); updateDebuggerOptions(); } + } else if (requestCode == RESULT_MOCK_LOCATION_APP) { + if (resultCode == Activity.RESULT_OK) { + mMockLocationApp = data.getAction(); + writeMockLocation(); + updateMockLocation(); + } } else if (requestCode == REQUEST_CODE_ENABLE_OEM_UNLOCK) { if (resultCode == Activity.RESULT_OK) { if (mEnableOemUnlock.isChecked()) { @@ -1574,16 +1661,19 @@ public class DevelopmentSettings extends SettingsPreferenceFragment Utils.setOemUnlockEnabled(getActivity(), false); } } - } else if (preference == mAllowMockLocation) { - Settings.Secure.putInt(getActivity().getContentResolver(), - Settings.Secure.ALLOW_MOCK_LOCATION, - mAllowMockLocation.isChecked() ? 1 : 0); + } else if (preference == mMockLocationAppPref) { + Intent intent = new Intent(getActivity(), AppPicker.class); + intent.putExtra(AppPicker.EXTRA_REQUESTIING_PERMISSION, + Manifest.permission.ACCESS_MOCK_LOCATION); + startActivityForResult(intent, RESULT_MOCK_LOCATION_APP); } else if (preference == mDebugViewAttributes) { Settings.Global.putInt(getActivity().getContentResolver(), Settings.Global.DEBUG_VIEW_ATTRIBUTES, mDebugViewAttributes.isChecked() ? 1 : 0); } else if (preference == mDebugAppPref) { - startActivityForResult(new Intent(getActivity(), AppPicker.class), RESULT_DEBUG_APP); + Intent intent = new Intent(getActivity(), AppPicker.class); + intent.putExtra(AppPicker.EXTRA_DEBUGGABLE, true); + startActivityForResult(intent, RESULT_DEBUG_APP); } else if (preference == mWaitForDebugger) { writeDebuggerOptions(); } else if (preference == mVerifyAppsOverUsb) {