From bd6ad3a2b1c30f7a007c4c2ef7e5c273a2f9df10 Mon Sep 17 00:00:00 2001 From: Svet Ganov Date: Sat, 5 Mar 2016 10:27:49 -0800 Subject: Support app install from a content URI bug:24079113 Change-Id: Ide1aa1667370f6b8d00ff269ef28992589656e9a --- .../packageinstaller/PackageInstallerActivity.java | 270 ++++++++++++++++----- .../permission/model/PermissionApps.java | 2 +- .../permission/model/PermissionGroups.java | 2 +- .../permission/model/PermissionStatusReceiver.java | 2 +- .../permission/ui/ReviewPermissionsActivity.java | 2 +- .../ui/handheld/AllAppPermissionsFragment.java | 2 +- .../ui/handheld/AppPermissionsFragment.java | 3 +- .../ui/handheld/ManagePermissionsFragment.java | 2 +- .../ui/handheld/PermissionAppsFragment.java | 3 +- .../permission/ui/handheld/SettingsWithHeader.java | 1 - .../ui/television/AllAppPermissionsFragment.java | 2 +- .../ui/television/AppPermissionsFragment.java | 3 +- .../ui/television/ManagePermissionsFragment.java | 2 +- .../ui/television/PermissionAppsFragment.java | 3 +- .../ui/television/PermissionsFrameFragment.java | 1 - .../ui/television/SettingsWithHeader.java | 1 - .../ui/wear/AppPermissionsFragmentWear.java | 3 +- .../packageinstaller/permission/utils/Utils.java | 149 ------------ src/com/android/packageinstaller/util/Utils.java | 149 ++++++++++++ 19 files changed, 365 insertions(+), 237 deletions(-) delete mode 100644 src/com/android/packageinstaller/permission/utils/Utils.java create mode 100644 src/com/android/packageinstaller/util/Utils.java (limited to 'src/com/android') diff --git a/src/com/android/packageinstaller/PackageInstallerActivity.java b/src/com/android/packageinstaller/PackageInstallerActivity.java index 79500e6e..cfa3dc24 100644 --- a/src/com/android/packageinstaller/PackageInstallerActivity.java +++ b/src/com/android/packageinstaller/PackageInstallerActivity.java @@ -33,7 +33,9 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageParser; import android.content.pm.PackageUserState; import android.content.pm.VerificationParams; +import android.graphics.drawable.Drawable; import android.net.Uri; +import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.UserManager; @@ -46,10 +48,16 @@ import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.AppSecurityPermissions; import android.widget.Button; +import android.widget.ImageView; import android.widget.TabHost; import android.widget.TextView; +import com.android.packageinstaller.util.Utils; import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; /* * This activity is launched when a new application is installed via side loading @@ -65,12 +73,20 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen private static final String TAG = "PackageInstaller"; private static final int REQUEST_ENABLE_UNKNOWN_SOURCES = 1; + private static final int REQUEST_INSTALL_PACKAGE = 2; + + private static final String SCHEME_FILE = "file"; + private static final String SCHEME_CONTENT = "content"; + private static final String SCHEME_PACKAGE = "package"; private int mSessionId = -1; private Uri mPackageURI; private Uri mOriginatingURI; private Uri mReferrerURI; private int mOriginatingUid = VerificationParams.NO_UID; + private File mContentUriApkStagingFile; + + private AsyncTask mStagingAsynTask; private boolean localLOGV = false; PackageManager mPm; @@ -108,6 +124,7 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen private void startInstallConfirm() { TabHost tabHost = (TabHost)findViewById(android.R.id.tabhost); tabHost.setup(); + tabHost.setVisibility(View.VISIBLE); ViewPager viewPager = (ViewPager)findViewById(R.id.pager); TabsAdapter adapter = new TabsAdapter(this, tabHost, viewPager); // If the app supports runtime permissions the new permissions will @@ -183,10 +200,7 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen ((TextView)findViewById(R.id.install_confirm_question)).setText(msg); } mInstallConfirm.setVisibility(View.VISIBLE); - mOk = (Button)findViewById(R.id.ok_button); - mCancel = (Button)findViewById(R.id.cancel_button); - mOk.setOnClickListener(this); - mCancel.setOnClickListener(this); + mOk.setEnabled(true); if (mScrollView == null) { // There is nothing to scroll view, so the ok button is immediately // set to install. @@ -320,14 +334,14 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { setResult(RESULT_OK); - finish(); + clearCachedApkIfNeededAndFinish(); } }) .setOnCancelListener(this) .create(); } return null; - } + } private void launchSecuritySettings() { Intent launchSettingsIntent = new Intent(Settings.ACTION_SECURITY_SETTINGS); @@ -341,9 +355,8 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen // implement a "allow untrusted source once" feature. if (request == REQUEST_ENABLE_UNKNOWN_SOURCES && result == RESULT_OK) { initiateInstall(); - } else { - finish(); } + clearCachedApkIfNeededAndFinish(); } private boolean isInstallRequestFromUnknownSource(Intent intent) { @@ -430,6 +443,10 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen mUserManager = (UserManager) getSystemService(Context.USER_SERVICE); final Intent intent = getIntent(); + mOriginatingUid = getOriginatingUid(intent); + + final Uri packageUri; + if (PackageInstaller.ACTION_CONFIRM_PERMISSIONS.equals(intent.getAction())) { final int sessionId = intent.getIntExtra(PackageInstaller.EXTRA_SESSION_ID, -1); final PackageInstaller.SessionInfo info = mInstaller.getSessionInfo(sessionId); @@ -440,72 +457,29 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen } mSessionId = sessionId; - mPackageURI = Uri.fromFile(new File(info.resolvedBaseCodePath)); + packageUri = Uri.fromFile(new File(info.resolvedBaseCodePath)); mOriginatingURI = null; mReferrerURI = null; } else { mSessionId = -1; - mPackageURI = intent.getData(); + packageUri = intent.getData(); mOriginatingURI = intent.getParcelableExtra(Intent.EXTRA_ORIGINATING_URI); mReferrerURI = intent.getParcelableExtra(Intent.EXTRA_REFERRER); } - final boolean unknownSourcesAllowedByAdmin = isUnknownSourcesAllowedByAdmin(); - final boolean unknownSourcesAllowedByUser = isUnknownSourcesEnabled(); - if (DeviceUtils.isWear(this)) { showDialogInner(DLG_NOT_SUPPORTED_ON_WEAR); return; } - final String scheme = mPackageURI.getScheme(); - if (scheme != null && !"file".equals(scheme) && !"package".equals(scheme)) { - Log.w(TAG, "Unsupported scheme " + scheme); - setPmResult(PackageManager.INSTALL_FAILED_INVALID_URI); - finish(); - return; - } - - final PackageUtil.AppSnippet as; - if ("package".equals(mPackageURI.getScheme())) { - try { - mPkgInfo = mPm.getPackageInfo(mPackageURI.getSchemeSpecificPart(), - PackageManager.GET_PERMISSIONS | PackageManager.GET_UNINSTALLED_PACKAGES); - } catch (NameNotFoundException e) { - } - if (mPkgInfo == null) { - Log.w(TAG, "Requested package " + mPackageURI.getScheme() - + " not available. Discontinuing installation"); - showDialogInner(DLG_PACKAGE_ERROR); - setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK); - return; - } - as = new PackageUtil.AppSnippet(mPm.getApplicationLabel(mPkgInfo.applicationInfo), - mPm.getApplicationIcon(mPkgInfo.applicationInfo)); - } else { - final File sourceFile = new File(mPackageURI.getPath()); - PackageParser.Package parsed = PackageUtil.getPackageInfo(sourceFile); - - // Check for parse errors - if (parsed == null) { - Log.w(TAG, "Parse error when parsing manifest. Discontinuing installation"); - showDialogInner(DLG_PACKAGE_ERROR); - setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK); - return; - } - mPkgInfo = PackageParser.generatePackageInfo(parsed, null, - PackageManager.GET_PERMISSIONS, 0, 0, null, - new PackageUserState()); - as = PackageUtil.getAppSnippet(this, mPkgInfo.applicationInfo, sourceFile); - } - //set view setContentView(R.layout.install_start); mInstallConfirm = findViewById(R.id.install_confirm_panel); mInstallConfirm.setVisibility(View.INVISIBLE); - PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet); - - mOriginatingUid = getOriginatingUid(intent); + mOk = (Button)findViewById(R.id.ok_button); + mCancel = (Button)findViewById(R.id.cancel_button); + mOk.setOnClickListener(this); + mCancel.setOnClickListener(this); // Block the install attempt on the Unknown Sources setting if necessary. final boolean requestFromUnknownSource = isInstallRequestFromUnknownSource(intent); @@ -517,17 +491,87 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen // If the admin prohibits it, or we're running in a managed profile, just show error // and exit. Otherwise show an option to take the user to Settings to change the setting. final boolean isManagedProfile = mUserManager.isManagedProfile(); - if (!unknownSourcesAllowedByAdmin) { + if (!isUnknownSourcesAllowedByAdmin()) { startActivity(new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS)); - finish(); - } else if (!unknownSourcesAllowedByUser && isManagedProfile) { + clearCachedApkIfNeededAndFinish(); + } else if (!isUnknownSourcesEnabled() && isManagedProfile) { showDialogInner(DLG_ADMIN_RESTRICTS_UNKNOWN_SOURCES); - } else if (!unknownSourcesAllowedByUser) { + } else if (!isUnknownSourcesEnabled()) { // Ask user to enable setting first showDialogInner(DLG_UNKNOWN_SOURCES); - } else { - initiateInstall(); } + + processPackageUri(packageUri); + } + + @Override + protected void onDestroy() { + if (mStagingAsynTask != null) { + mStagingAsynTask.cancel(true); + mStagingAsynTask = null; + } + super.onDestroy(); + } + + private void processPackageUri(final Uri packageUri) { + mPackageURI = packageUri; + + final String scheme = packageUri.getScheme(); + final PackageUtil.AppSnippet as; + + switch (scheme) { + case SCHEME_PACKAGE: { + try { + mPkgInfo = mPm.getPackageInfo(packageUri.getSchemeSpecificPart(), + PackageManager.GET_PERMISSIONS + | PackageManager.GET_UNINSTALLED_PACKAGES); + } catch (NameNotFoundException e) { + } + if (mPkgInfo == null) { + Log.w(TAG, "Requested package " + packageUri.getScheme() + + " not available. Discontinuing installation"); + showDialogInner(DLG_PACKAGE_ERROR); + setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK); + return; + } + as = new PackageUtil.AppSnippet(mPm.getApplicationLabel(mPkgInfo.applicationInfo), + mPm.getApplicationIcon(mPkgInfo.applicationInfo)); + } break; + + case SCHEME_FILE: { + File sourceFile = new File(packageUri.getPath()); + PackageParser.Package parsed = PackageUtil.getPackageInfo(sourceFile); + + // Check for parse errors + if (parsed == null) { + Log.w(TAG, "Parse error when parsing manifest. Discontinuing installation"); + showDialogInner(DLG_PACKAGE_ERROR); + setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK); + return; + } + mPkgInfo = PackageParser.generatePackageInfo(parsed, null, + PackageManager.GET_PERMISSIONS, 0, 0, null, + new PackageUserState()); + as = PackageUtil.getAppSnippet(this, mPkgInfo.applicationInfo, sourceFile); + } break; + + case SCHEME_CONTENT: { + mStagingAsynTask = new StagingAsyncTask(); + mStagingAsynTask.execute(packageUri); + return; + } + + default: { + Log.w(TAG, "Unsupported scheme " + scheme); + setPmResult(PackageManager.INSTALL_FAILED_INVALID_URI); + clearCachedApkIfNeededAndFinish(); + return; + } + } + + PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet); + + initiateInstall(); } /** Get the ApplicationInfo for the calling package, if available */ @@ -612,7 +656,7 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen // Generic handling when pressing back key public void onCancel(DialogInterface dialog) { - finish(); + clearCachedApkIfNeededAndFinish(); } public void onClick(View v) { @@ -620,7 +664,7 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen if (mOkCanInstall || mScrollView == null) { if (mSessionId != -1) { mInstaller.setPermissionsResult(mSessionId, true); - finish(); + clearCachedApkIfNeededAndFinish(); } else { startInstall(); } @@ -633,7 +677,7 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen if (mSessionId != -1) { mInstaller.setPermissionsResult(mSessionId, false); } - finish(); + clearCachedApkIfNeededAndFinish(); } } @@ -664,7 +708,99 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); } if(localLOGV) Log.i(TAG, "downloaded app uri="+mPackageURI); - startActivity(newIntent); + startActivityForResult(newIntent, REQUEST_INSTALL_PACKAGE); + } + + private void clearCachedApkIfNeededAndFinish() { + if (mContentUriApkStagingFile != null) { + mContentUriApkStagingFile.delete(); + mContentUriApkStagingFile = null; + } finish(); } + + private final class StagingAsyncTask extends AsyncTask { + private static final long SHOW_EMPTY_STATE_DELAY_MILLIS = 300; + + private final Runnable mEmptyStateRunnable = new Runnable() { + @Override + public void run() { + ((TextView) findViewById(R.id.app_name)).setText(R.string.app_name_unknown); + ((TextView) findViewById(R.id.install_confirm_question)) + .setText(R.string.message_staging); + mInstallConfirm.setVisibility(View.VISIBLE); + findViewById(android.R.id.tabhost).setVisibility(View.INVISIBLE); + findViewById(R.id.ok_button).setEnabled(false); + Drawable icon = getDrawable(R.drawable.ic_file_download); + Utils.applyTint(PackageInstallerActivity.this, + icon, android.R.attr.colorControlNormal); + ((ImageView) findViewById(R.id.app_icon)).setImageDrawable(icon); + } + }; + + @Override + protected void onPreExecute() { + getWindow().getDecorView().postDelayed(mEmptyStateRunnable, + SHOW_EMPTY_STATE_DELAY_MILLIS); + } + + @Override + protected File doInBackground(Uri... params) { + if (params == null || params.length <= 0) { + return null; + } + Uri packageUri = params[0]; + File sourceFile = null; + try { + sourceFile = File.createTempFile("package", ".apk", getCacheDir()); + try ( + InputStream in = getContentResolver().openInputStream(packageUri); + OutputStream out = (in != null) ? new FileOutputStream( + sourceFile) : null; + ) { + // Despite the comments in ContentResolver#openInputStream + // the returned stream can be null. + if (in == null) { + return null; + } + byte[] buffer = new byte[4096]; + int bytesRead; + while ((bytesRead = in.read(buffer)) >= 0) { + // Be nice and respond to a cancellation + if (isCancelled()) { + return null; + } + out.write(buffer, 0, bytesRead); + } + } + } catch (IOException ioe) { + Log.w(TAG, "Error staging apk from content URI", ioe); + if (sourceFile != null) { + sourceFile.delete(); + } + } + return sourceFile; + } + + @Override + protected void onPostExecute(File file) { + getWindow().getDecorView().removeCallbacks(mEmptyStateRunnable); + if (isFinishing() || isDestroyed()) { + return; + } + if (file == null) { + showDialogInner(DLG_PACKAGE_ERROR); + setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK); + return; + } + mContentUriApkStagingFile = file; + Uri fileUri = Uri.fromFile(file); + processPackageUri(fileUri); + } + + @Override + protected void onCancelled(File file) { + getWindow().getDecorView().removeCallbacks(mEmptyStateRunnable); + } + }; } diff --git a/src/com/android/packageinstaller/permission/model/PermissionApps.java b/src/com/android/packageinstaller/permission/model/PermissionApps.java index 9ff5025c..2c0508a5 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionApps.java +++ b/src/com/android/packageinstaller/permission/model/PermissionApps.java @@ -32,7 +32,7 @@ import android.util.Log; import android.util.SparseArray; import com.android.packageinstaller.R; -import com.android.packageinstaller.permission.utils.Utils; +import com.android.packageinstaller.util.Utils; import java.util.ArrayList; import java.util.Collections; diff --git a/src/com/android/packageinstaller/permission/model/PermissionGroups.java b/src/com/android/packageinstaller/permission/model/PermissionGroups.java index 8ca69f24..04dd07ff 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionGroups.java +++ b/src/com/android/packageinstaller/permission/model/PermissionGroups.java @@ -31,7 +31,7 @@ import android.os.Bundle; import android.util.ArraySet; import com.android.packageinstaller.R; -import com.android.packageinstaller.permission.utils.Utils; +import com.android.packageinstaller.util.Utils; import java.util.ArrayList; import java.util.Collections; diff --git a/src/com/android/packageinstaller/permission/model/PermissionStatusReceiver.java b/src/com/android/packageinstaller/permission/model/PermissionStatusReceiver.java index 810ae8ec..d7e4547a 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionStatusReceiver.java +++ b/src/com/android/packageinstaller/permission/model/PermissionStatusReceiver.java @@ -26,7 +26,7 @@ import android.util.ArrayMap; import android.util.ArraySet; import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; -import com.android.packageinstaller.permission.utils.Utils; +import com.android.packageinstaller.util.Utils; import java.text.Collator; import java.util.ArrayList; diff --git a/src/com/android/packageinstaller/permission/ui/ReviewPermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/ReviewPermissionsActivity.java index b872983d..38080e6b 100644 --- a/src/com/android/packageinstaller/permission/ui/ReviewPermissionsActivity.java +++ b/src/com/android/packageinstaller/permission/ui/ReviewPermissionsActivity.java @@ -46,7 +46,7 @@ import android.widget.TextView; import com.android.packageinstaller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; -import com.android.packageinstaller.permission.utils.Utils; +import com.android.packageinstaller.util.Utils; import com.android.packageinstaller.permission.ui.ConfirmActionDialogFragment.OnActionConfirmedListener; import java.util.List; diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java index 0c249e55..540d8765 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java @@ -37,7 +37,7 @@ import android.provider.Settings; import android.util.Log; import android.view.MenuItem; import com.android.packageinstaller.R; -import com.android.packageinstaller.permission.utils.Utils; +import com.android.packageinstaller.util.Utils; import java.util.ArrayList; import java.util.Collections; diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java index d5e649ee..674b562e 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java @@ -49,10 +49,9 @@ import android.widget.Toast; import com.android.packageinstaller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; -import com.android.packageinstaller.permission.ui.OverlayTouchActivity; import com.android.packageinstaller.permission.utils.LocationUtils; import com.android.packageinstaller.permission.utils.SafetyNetLogger; -import com.android.packageinstaller.permission.utils.Utils; +import com.android.packageinstaller.util.Utils; import com.android.settingslib.RestrictedLockUtils; import java.util.ArrayList; diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java index c53da879..f5d7020e 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java @@ -37,7 +37,7 @@ import com.android.packageinstaller.permission.model.PermissionApps; import com.android.packageinstaller.permission.model.PermissionApps.PmCache; import com.android.packageinstaller.permission.model.PermissionGroup; import com.android.packageinstaller.permission.model.PermissionGroups; -import com.android.packageinstaller.permission.utils.Utils; +import com.android.packageinstaller.util.Utils; import java.util.List; diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index ccf864fb..5e5c42d1 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -43,10 +43,9 @@ import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.PermissionApps; import com.android.packageinstaller.permission.model.PermissionApps.Callback; import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; -import com.android.packageinstaller.permission.ui.OverlayTouchActivity; import com.android.packageinstaller.permission.utils.LocationUtils; import com.android.packageinstaller.permission.utils.SafetyNetLogger; -import com.android.packageinstaller.permission.utils.Utils; +import com.android.packageinstaller.util.Utils; import com.android.settingslib.RestrictedLockUtils; import java.util.ArrayList; diff --git a/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithHeader.java b/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithHeader.java index c15a4287..d5775796 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithHeader.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithHeader.java @@ -28,7 +28,6 @@ import android.widget.TextView; import com.android.packageinstaller.DeviceUtils; import com.android.packageinstaller.R; -import com.android.packageinstaller.permission.utils.Utils; public abstract class SettingsWithHeader extends PermissionsFrameFragment implements OnClickListener { diff --git a/src/com/android/packageinstaller/permission/ui/television/AllAppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/television/AllAppPermissionsFragment.java index 7ea9a258..db99538c 100644 --- a/src/com/android/packageinstaller/permission/ui/television/AllAppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/television/AllAppPermissionsFragment.java @@ -45,7 +45,7 @@ import android.view.MenuItem; import com.android.packageinstaller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; -import com.android.packageinstaller.permission.utils.Utils; +import com.android.packageinstaller.util.Utils; import java.util.ArrayList; import java.util.Collections; diff --git a/src/com/android/packageinstaller/permission/ui/television/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/television/AppPermissionsFragment.java index 5bb0d01c..4a38af96 100644 --- a/src/com/android/packageinstaller/permission/ui/television/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/television/AppPermissionsFragment.java @@ -50,11 +50,10 @@ import android.widget.Toast; import com.android.packageinstaller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; -import com.android.packageinstaller.permission.ui.OverlayTouchActivity; import com.android.packageinstaller.permission.ui.ReviewPermissionsActivity; import com.android.packageinstaller.permission.utils.LocationUtils; import com.android.packageinstaller.permission.utils.SafetyNetLogger; -import com.android.packageinstaller.permission.utils.Utils; +import com.android.packageinstaller.util.Utils; import java.util.ArrayList; import java.util.List; diff --git a/src/com/android/packageinstaller/permission/ui/television/ManagePermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/television/ManagePermissionsFragment.java index 47301f48..81550337 100644 --- a/src/com/android/packageinstaller/permission/ui/television/ManagePermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/television/ManagePermissionsFragment.java @@ -38,7 +38,7 @@ import com.android.packageinstaller.permission.model.PermissionApps; import com.android.packageinstaller.permission.model.PermissionApps.PmCache; import com.android.packageinstaller.permission.model.PermissionGroup; import com.android.packageinstaller.permission.model.PermissionGroups; -import com.android.packageinstaller.permission.utils.Utils; +import com.android.packageinstaller.util.Utils; import java.util.List; diff --git a/src/com/android/packageinstaller/permission/ui/television/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/television/PermissionAppsFragment.java index 1f4228bb..a5ef5411 100644 --- a/src/com/android/packageinstaller/permission/ui/television/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/television/PermissionAppsFragment.java @@ -45,11 +45,10 @@ import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.PermissionApps; import com.android.packageinstaller.permission.model.PermissionApps.Callback; import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; -import com.android.packageinstaller.permission.ui.OverlayTouchActivity; import com.android.packageinstaller.permission.ui.ReviewPermissionsActivity; import com.android.packageinstaller.permission.utils.LocationUtils; import com.android.packageinstaller.permission.utils.SafetyNetLogger; -import com.android.packageinstaller.permission.utils.Utils; +import com.android.packageinstaller.util.Utils; import java.util.ArrayList; import java.util.List; diff --git a/src/com/android/packageinstaller/permission/ui/television/PermissionsFrameFragment.java b/src/com/android/packageinstaller/permission/ui/television/PermissionsFrameFragment.java index e81aee86..2c7b91e9 100644 --- a/src/com/android/packageinstaller/permission/ui/television/PermissionsFrameFragment.java +++ b/src/com/android/packageinstaller/permission/ui/television/PermissionsFrameFragment.java @@ -33,7 +33,6 @@ import android.widget.TextView; import com.android.packageinstaller.DeviceUtils; import com.android.packageinstaller.R; -import com.android.packageinstaller.permission.utils.Utils; public abstract class PermissionsFrameFragment extends PreferenceFragment { diff --git a/src/com/android/packageinstaller/permission/ui/television/SettingsWithHeader.java b/src/com/android/packageinstaller/permission/ui/television/SettingsWithHeader.java index 4dae629c..a401426d 100644 --- a/src/com/android/packageinstaller/permission/ui/television/SettingsWithHeader.java +++ b/src/com/android/packageinstaller/permission/ui/television/SettingsWithHeader.java @@ -28,7 +28,6 @@ import android.widget.TextView; import com.android.packageinstaller.DeviceUtils; import com.android.packageinstaller.R; -import com.android.packageinstaller.permission.utils.Utils; public abstract class SettingsWithHeader extends PermissionsFrameFragment implements OnClickListener { diff --git a/src/com/android/packageinstaller/permission/ui/wear/AppPermissionsFragmentWear.java b/src/com/android/packageinstaller/permission/ui/wear/AppPermissionsFragmentWear.java index 6ea34628..13a16d6e 100644 --- a/src/com/android/packageinstaller/permission/ui/wear/AppPermissionsFragmentWear.java +++ b/src/com/android/packageinstaller/permission/ui/wear/AppPermissionsFragmentWear.java @@ -35,12 +35,11 @@ import android.widget.Toast; import com.android.packageinstaller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; -import com.android.packageinstaller.permission.ui.OverlayTouchActivity; import com.android.packageinstaller.permission.ui.wear.settings.PermissionsSettingsAdapter; import com.android.packageinstaller.permission.ui.wear.settings.SettingsAdapter; import com.android.packageinstaller.permission.utils.LocationUtils; import com.android.packageinstaller.permission.utils.SafetyNetLogger; -import com.android.packageinstaller.permission.utils.Utils; +import com.android.packageinstaller.util.Utils; import java.util.ArrayList; import java.util.List; diff --git a/src/com/android/packageinstaller/permission/utils/Utils.java b/src/com/android/packageinstaller/permission/utils/Utils.java deleted file mode 100644 index 21830378..00000000 --- a/src/com/android/packageinstaller/permission/utils/Utils.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.packageinstaller.permission.utils; - -import android.Manifest; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.content.res.Resources.Theme; -import android.graphics.drawable.Drawable; -import android.util.ArraySet; -import android.util.Log; -import android.util.TypedValue; - -import com.android.packageinstaller.permission.model.AppPermissionGroup; -import com.android.packageinstaller.permission.model.AppPermissions; -import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; - -import java.util.List; - -public class Utils { - - private static final String LOG_TAG = "Utils"; - - public static final String OS_PKG = "android"; - - public static final String[] MODERN_PERMISSION_GROUPS = { - Manifest.permission_group.CALENDAR, - Manifest.permission_group.CAMERA, - Manifest.permission_group.CONTACTS, - Manifest.permission_group.LOCATION, - Manifest.permission_group.SENSORS, - Manifest.permission_group.SMS, - Manifest.permission_group.PHONE, - Manifest.permission_group.MICROPHONE, - Manifest.permission_group.STORAGE - }; - - private static final Intent LAUNCHER_INTENT = new Intent(Intent.ACTION_MAIN, null) - .addCategory(Intent.CATEGORY_LAUNCHER); - - private Utils() { - /* do nothing - hide constructor */ - } - - public static Drawable loadDrawable(PackageManager pm, String pkg, int resId) { - try { - return pm.getResourcesForApplication(pkg).getDrawable(resId, null); - } catch (Resources.NotFoundException | PackageManager.NameNotFoundException e) { - Log.d(LOG_TAG, "Couldn't get resource", e); - return null; - } - } - - public static boolean isModernPermissionGroup(String name) { - for (String modernGroup : MODERN_PERMISSION_GROUPS) { - if (modernGroup.equals(name)) { - return true; - } - } - return false; - } - - public static boolean shouldShowPermission(AppPermissionGroup group, String packageName) { - // We currently will not show permissions fixed by the system. - // which is what the system does for system components. - if (group.isSystemFixed() && !LocationUtils.isLocationGroupAndProvider( - group.getName(), packageName)) { - return false; - } - - final boolean isPlatformPermission = group.getDeclaringPackage().equals(OS_PKG); - // Show legacy permissions only if the user chose that. - if (isPlatformPermission - && !Utils.isModernPermissionGroup(group.getName())) { - return false; - } - return true; - } - - public static boolean shouldShowPermission(PermissionApp app) { - // We currently will not show permissions fixed by the system - // which is what the system does for system components. - if (app.isSystemFixed() && !LocationUtils.isLocationGroupAndProvider( - app.getPermissionGroup().getName(), app.getPackageName())) { - return false; - } - - return true; - } - - public static Drawable applyTint(Context context, Drawable icon, int attr) { - Theme theme = context.getTheme(); - TypedValue typedValue = new TypedValue(); - theme.resolveAttribute(attr, typedValue, true); - icon = icon.mutate(); - icon.setTint(context.getColor(typedValue.resourceId)); - return icon; - } - - public static Drawable applyTint(Context context, int iconResId, int attr) { - return applyTint(context, context.getDrawable(iconResId), attr); - } - - public static ArraySet getLauncherPackages(Context context) { - ArraySet launcherPkgs = new ArraySet<>(); - for (ResolveInfo info : - context.getPackageManager().queryIntentActivities(LAUNCHER_INTENT, 0)) { - launcherPkgs.add(info.activityInfo.packageName); - } - - return launcherPkgs; - } - - public static List getAllInstalledApplications(Context context) { - return context.getPackageManager().getInstalledApplications(0); - } - - public static boolean isSystem(PermissionApp app, ArraySet launcherPkgs) { - return isSystem(app.getAppInfo(), launcherPkgs); - } - - public static boolean isSystem(AppPermissions app, ArraySet launcherPkgs) { - return isSystem(app.getPackageInfo().applicationInfo, launcherPkgs); - } - - public static boolean isSystem(ApplicationInfo info, ArraySet launcherPkgs) { - return info.isSystemApp() && (info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 0 - && !launcherPkgs.contains(info.packageName); - } -} diff --git a/src/com/android/packageinstaller/util/Utils.java b/src/com/android/packageinstaller/util/Utils.java new file mode 100644 index 00000000..f0d88d32 --- /dev/null +++ b/src/com/android/packageinstaller/util/Utils.java @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.util; + +import android.Manifest; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.res.Resources; +import android.content.res.Resources.Theme; +import android.graphics.drawable.Drawable; +import android.util.ArraySet; +import android.util.Log; +import android.util.TypedValue; + +import com.android.packageinstaller.permission.model.AppPermissionGroup; +import com.android.packageinstaller.permission.model.AppPermissions; +import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; +import com.android.packageinstaller.permission.utils.LocationUtils; + +import java.util.List; + +public class Utils { + + private static final String LOG_TAG = "Utils"; + + public static final String OS_PKG = "android"; + + public static final String[] MODERN_PERMISSION_GROUPS = { + Manifest.permission_group.CALENDAR, + Manifest.permission_group.CAMERA, + Manifest.permission_group.CONTACTS, + Manifest.permission_group.LOCATION, + Manifest.permission_group.SENSORS, + Manifest.permission_group.SMS, + Manifest.permission_group.PHONE, + Manifest.permission_group.MICROPHONE, + Manifest.permission_group.STORAGE + }; + + private static final Intent LAUNCHER_INTENT = new Intent(Intent.ACTION_MAIN, null) + .addCategory(Intent.CATEGORY_LAUNCHER); + + private Utils() { + /* do nothing - hide constructor */ + } + + public static Drawable loadDrawable(PackageManager pm, String pkg, int resId) { + try { + return pm.getResourcesForApplication(pkg).getDrawable(resId, null); + } catch (Resources.NotFoundException | PackageManager.NameNotFoundException e) { + Log.d(LOG_TAG, "Couldn't get resource", e); + return null; + } + } + + public static boolean isModernPermissionGroup(String name) { + for (String modernGroup : MODERN_PERMISSION_GROUPS) { + if (modernGroup.equals(name)) { + return true; + } + } + return false; + } + + public static boolean shouldShowPermission(AppPermissionGroup group, String packageName) { + // We currently will not show permissions fixed by the system. + // which is what the system does for system components. + if (group.isSystemFixed() && !LocationUtils.isLocationGroupAndProvider( + group.getName(), packageName)) { + return false; + } + + final boolean isPlatformPermission = group.getDeclaringPackage().equals(OS_PKG); + // Show legacy permissions only if the user chose that. + if (isPlatformPermission + && !Utils.isModernPermissionGroup(group.getName())) { + return false; + } + return true; + } + + public static boolean shouldShowPermission(PermissionApp app) { + // We currently will not show permissions fixed by the system + // which is what the system does for system components. + if (app.isSystemFixed() && !LocationUtils.isLocationGroupAndProvider( + app.getPermissionGroup().getName(), app.getPackageName())) { + return false; + } + + return true; + } + + public static Drawable applyTint(Context context, Drawable icon, int attr) { + Theme theme = context.getTheme(); + TypedValue typedValue = new TypedValue(); + theme.resolveAttribute(attr, typedValue, true); + icon = icon.mutate(); + icon.setTint(context.getColor(typedValue.resourceId)); + return icon; + } + + public static Drawable applyTint(Context context, int iconResId, int attr) { + return applyTint(context, context.getDrawable(iconResId), attr); + } + + public static ArraySet getLauncherPackages(Context context) { + ArraySet launcherPkgs = new ArraySet<>(); + for (ResolveInfo info : + context.getPackageManager().queryIntentActivities(LAUNCHER_INTENT, 0)) { + launcherPkgs.add(info.activityInfo.packageName); + } + + return launcherPkgs; + } + + public static List getAllInstalledApplications(Context context) { + return context.getPackageManager().getInstalledApplications(0); + } + + public static boolean isSystem(PermissionApp app, ArraySet launcherPkgs) { + return isSystem(app.getAppInfo(), launcherPkgs); + } + + public static boolean isSystem(AppPermissions app, ArraySet launcherPkgs) { + return isSystem(app.getPackageInfo().applicationInfo, launcherPkgs); + } + + public static boolean isSystem(ApplicationInfo info, ArraySet launcherPkgs) { + return info.isSystemApp() && (info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 0 + && !launcherPkgs.contains(info.packageName); + } +} -- cgit v1.2.3