OSDN Git Service

Backport ChooserTarget package source check from N
[android-x86/frameworks-base.git] / core / java / com / android / internal / app / ChooserActivity.java
index 6bbebb7..e137f94 100644 (file)
@@ -373,6 +373,11 @@ public class ChooserActivity extends ResolverActivity {
         int targetsToQuery = 0;
         for (int i = 0, N = adapter.getDisplayResolveInfoCount(); i < N; i++) {
             final DisplayResolveInfo dri = adapter.getDisplayResolveInfo(i);
+            if (adapter.getScore(dri) == 0) {
+                // A score of 0 means the app hasn't been used in some time;
+                // don't query it as it's not likely to be relevant.
+                continue;
+            }
             final ActivityInfo ai = dri.getResolveInfo().activityInfo;
             final Bundle md = ai.metaData;
             final String serviceName = md != null ? convertServiceName(ai.packageName,
@@ -651,7 +656,19 @@ public class ChooserActivity extends ResolverActivity {
             }
             intent.setComponent(mChooserTarget.getComponentName());
             intent.putExtras(mChooserTarget.getIntentExtras());
-            activity.startActivityAsCaller(intent, options, true, userId);
+
+            // Important: we will ignore the target security checks in ActivityManager
+            // if and only if the ChooserTarget's target package is the same package
+            // where we got the ChooserTargetService that provided it. This lets a
+            // ChooserTargetService provide a non-exported or permission-guarded target
+            // to the chooser for the user to pick.
+            //
+            // If mSourceInfo is null, we got this ChooserTarget from the caller or elsewhere
+            // so we'll obey the caller's normal security checks.
+            final boolean ignoreTargetSecurity = mSourceInfo != null
+                    && mSourceInfo.getResolvedComponentName().getPackageName()
+                    .equals(mChooserTarget.getComponentName().getPackageName());
+            activity.startActivityAsCaller(intent, options, ignoreTargetSecurity, userId);
             return true;
         }
 
@@ -920,7 +937,7 @@ public class ChooserActivity extends ResolverActivity {
         @Override
         public int compare(ChooserTarget lhs, ChooserTarget rhs) {
             // Descending order
-            return (int) Math.signum(lhs.getScore() - rhs.getScore());
+            return (int) Math.signum(rhs.getScore() - lhs.getScore());
         }
     }
 
@@ -1017,7 +1034,15 @@ public class ChooserActivity extends ResolverActivity {
                             final RowScale rs = new RowScale(ChooserRowAdapter.this, 0.f, 1.f)
                                     .setInterpolator(mInterpolator);
                             mServiceTargetScale[i] = rs;
-                            rs.startAnimation();
+                        }
+
+                        // Start the animations in a separate loop.
+                        // The process of starting animations will result in
+                        // binding views to set up initial values, and we must
+                        // have ALL of the new RowScale objects created above before
+                        // we get started.
+                        for (int i = oldRCount; i < rcount; i++) {
+                            mServiceTargetScale[i].startAnimation();
                         }
                     }
 
@@ -1097,17 +1122,19 @@ public class ChooserActivity extends ResolverActivity {
 
             for (int i = 0; i < mColumnCount; i++) {
                 final View v = mChooserListAdapter.createView(row);
+                final int column = i;
                 v.setOnClickListener(new OnClickListener() {
                     @Override
                     public void onClick(View v) {
-                        startSelected(holder.itemIndex, false, true);
+                        startSelected(holder.itemIndices[column], false, true);
                     }
                 });
                 v.setOnLongClickListener(new OnLongClickListener() {
                     @Override
                     public boolean onLongClick(View v) {
                         showAppDetails(
-                                mChooserListAdapter.resolveInfoForPosition(holder.itemIndex, true));
+                                mChooserListAdapter.resolveInfoForPosition(
+                                        holder.itemIndices[column], true));
                         return true;
                     }
                 });
@@ -1165,8 +1192,8 @@ public class ChooserActivity extends ResolverActivity {
                 final View v = holder.cells[i];
                 if (start + i <= end) {
                     v.setVisibility(View.VISIBLE);
-                    holder.itemIndex = start + i;
-                    mChooserListAdapter.bindView(holder.itemIndex, v);
+                    holder.itemIndices[i] = start + i;
+                    mChooserListAdapter.bindView(holder.itemIndices[i], v);
                 } else {
                     v.setVisibility(View.GONE);
                 }
@@ -1197,11 +1224,12 @@ public class ChooserActivity extends ResolverActivity {
         final View[] cells;
         final ViewGroup row;
         int measuredRowHeight;
-        int itemIndex;
+        int[] itemIndices;
 
         public RowViewHolder(ViewGroup row, int cellCount) {
             this.row = row;
             this.cells = new View[cellCount];
+            this.itemIndices = new int[cellCount];
         }
 
         public void measure() {
@@ -1389,7 +1417,7 @@ public class ChooserActivity extends ResolverActivity {
                 final View v = mChooserRowAdapter.getView(pos, mCachedView, mListView);
                 int height = ((RowViewHolder) (v.getTag())).measuredRowHeight;
 
-                offset += (int) (height * mChooserRowAdapter.getRowScale(pos) * chooserTargetRows);
+                offset += (int) (height * mChooserRowAdapter.getRowScale(pos));
 
                 if (vt >= 0) {
                     mCachedViewType = vt;